面我學習了Flex布局之后感覺是真的爽啊,比之前用浮動,定位方便太多了,之前幾十行代碼才能寫完的布局,用了Flex10行左右就搞定了,今天學了Grid發現比Flex更爽,代碼寫的還要少,真是太厲害了,現在我把學習的相關知識梳理了一下,給大家分享一下,同時也可以作為我日后復習的筆記。
1.Grid容器屬性:
屬性說明:
grid-template-columns 軌道列寬
grid-template-rows 軌道行高
gap 軌道間距
grid-auto-columns 隱式軌道的列寬
grid-auto-rows 隱式軌道的行高
grid-auto-flow 隱式軌道排列方式,默認行優先
首先我們寫出一個html結構,聲明它的樣式為網格布局:display:grid;
<div class="container">
<span class="item">item1</span>
<span class="item">item2</span>
<span class="item">item3</span>
<span class="item">item4</span>
<span class="item">item5</span>
<span class="item">item6</span>
</div>
由此可見,之前的span元素為行內元素,在聲明了網格布局之后,全部變為了塊元素。
與之前的flex布局不一樣,flex布局是行內元素。
以下是創建了一個2行3列的布局:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>網格容器/網格項目/網格軌道/軌道間距</title>
<style>
.container {
border: 1px solid #000;
padding: 0.5em;
grid-template-columns: auto;
grid-template-columns: 10em 10em auto;
grid-template-rows: 5em 5em;
gap: 0.5em;
}
.container > .item {
background-color: lightcyan;
border: 1px solid #000;
padding: 0.5em;
}
</style>
</head>
<body>
<div class="container">
<span class="item">item1</span>
<span class="item">item2</span>
<span class="item">item3</span>
<span class="item">item4</span>
<span class="item">item5</span>
<span class="item">item6</span>
</div>
</body>
</html>
通過上述案例我可以學習到網格布局的相關屬性用法:
2.自定義項目屬性:
grid-area語法:grid-row-start / grid-column-start / grid-row-end / grid-column-end;
編號從左上角開始(1,1)并且是遞增的。
相關屬性說明:
首先,還是先創建一個網格布局的html結構:
<div class="container">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
<div class="item">item4</div>
<div class="item">item5</div>
<div class="item">item6</div>
<div class="item">item7</div>
<div class="item">item8</div>
<div class="item">item9</div>
</div>
給出以下樣式:
<style>
.container {
border: 1px solid #000;
padding: 0.5em;
display: grid;
/* 軌道列寬 */
grid-template-columns: repeat(3, 1fr);
/* 軌道行高 */
grid-template-rows: 5em 5em;
/* 行優先時要設置隱式軌道的行高 */
grid-auto-rows: 5em;
/* 軌道間距 */
gap: 0.5em 1em;
}
.container > .item {
background-color: lightcyan;
border: 1px solid #000;
padding: 0.5em;
}
</style>
現在我們以第5個項目來舉例,將它移動到第一個網格單元中:
<style>
.container .item:nth-of-type(5) {
background-color: lightyellow;
/* item5的默認位置 */
grid-area: 2 / 2 / 3 / 3;
/* 將它放入到第一個網格單元中 */
grid-area: 1 / 1 / 2 / 2;
}
</style>
由于默認項目是跨越一行一列的,所以可以簡寫成下面的格式:
grid-area: 1 / 2;
但是,如果是跨越1行1列以上的,就不能省略了。例如要跨越2行3列,就必須寫成下面的格式:
grid-area: 1 / 1 / 3 / 4;
通常的情況是我們只關心跨越幾行幾列,并不關心它的結束行號,所以還可以這樣寫:
grid-area: 1 / 1 / span 2 / span 3;
所以,上述兩種寫法的效果是一樣的。
再以第1個項目為例,有如下樣式:
<style>
/* 添加一個淺綠色背景便于區分 */
background-color: lightgreen;
/* 默認位置 */
grid-area: 1 / 1 / 2 / 2;
</style>
如果現在要跨1行3列,可以寫成如下格式:
grid-area: 1 / 1 / span 1 / span 3;
因為item1默認的位置是1 / 1,所以上述樣式可以簡寫成:
grid-area: span 1 / span 3;
之前說過,項目默認的是跨1行1列,所以,可以簡寫成如下格式:
grid-area: auto / span 3;
由以上案例可以得出結論:
grid-area:參數數量不同,意義不同
3.網格單元尺寸的新單位:fr
設置軌道寬度時可以用一個新單位:fr(fraction),類似于flex中的伸縮因子。
現有如下網格布局:
<div class="container">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
<div class="item">item4</div>
<div class="item">item5</div>
<div class="item">item6</div>
</div>
給出如下樣式:
<style>
.container {
border: 1px solid #000;
padding: 0.5em;
display: grid;
/* 軌道列寬 */
grid-template-columns: 10em 10em 10em;
/* 軌道行高 */
grid-template-rows: 5em 5em;
/* 軌道間距 */
gap: 0.5em;
}
</style>
此時我們可以在設置軌道寬度的時候使用一個新單位:fr(fraction),類似于flex的伸縮因子
grid-template-columns: auto auto auto;
以上屬性設置了一個自適應的3列等寬的布局,如果現在出現一個新的需求,中間一列的寬度是兩邊的二倍,那么auto就無法滿足了,但是fr可以完美解決這個問題:
grid-template-columns: 1fr 2fr 1fr;
4.網格單元尺寸的常用函數:repeat(),minmax()
還是跟上面案例一樣的初始樣式,現在如果我要設置一個3列10em寬度的布局,可以利用repeat()函數這樣寫:
grid-template-columns: repeat(3, 10em);
等價于下面的寫法:
grid-template-columns: 10em 10em 10em;
repeat()的第二個參數可以是多個值
grid-template-columns: repeat(3, 10em 2em);
等價于下面的寫法:
grid-template-columns: 10em 2em 10em 2em 10em 2em;
repeat()函數還可以與fr混合使用:
grid-template-columns: repeat(2, 1fr) 2fr;
等價于下面的寫法:
grid-template-columns: 1fr 1fr 2fr;
中間列,最小寬度是20em,最大寬度是左右的2倍
grid-template-columns: 1fr minmax(20em, 2fr) 1fr;
grid-template-columns: 20em minmax(20em, 1fr);
當使用1fr時,auto效果也一樣,即使寫成5fr也是可以的。
grid-template-columns: 20em minmax(20em, 1fr);
grid-template-columns: 20em minmax(20em, 5fr);
grid-template-columns: 20em minmax(20em, auto);
以上三種寫法效果完全一樣。
5.網格單元的排列方式與隱式軌道
現有如下的html結構和樣式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>網格單元的排列方式與隱式軌道</title>
<style>
/* 網格容器 */
.container {
border: 1px solid #000;
padding: 0.5em;
display: grid;
/* 軌道列寬 */
grid-template-columns: repeat(3, 1fr);
/* 軌道行高 */
grid-template-rows: 5em 5em;
/* 軌道間距 */
gap: 0.5em 1em;
}
.container > .item {
background-color: lightcyan;
border: 1px solid #000;
padding: 0.5em;
}
</style>
</head>
<body>
<div class="container">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
<div class="item">item4</div>
<div class="item">item5</div>
<div class="item">item6</div>
<div class="item">item7</div>
<div class="item">item8</div>
<div class="item">item9</div>
</div>
</body>
</html>
此時聲明的網格單元數量已經不夠存放網格項目了,多出的三個項目會自動放入到自動生成的網格空間中了,這時,原來聲明的網格單元叫做:顯示軌道,新項目顯示的軌道稱為:隱式軌道。
此時,默認項目在容器中按照先行后列的順序排列,即:“行優先”。
grid-auto-flow: row;
自動生成的隱式軌道的高度是自動的,因此,行優先時要設置隱式軌道的行高。
grid-auto-rows: 5em;
列優先時,需要設置隱式軌道的列寬:
grid-auto-flow: column;
grid-auto-columns: 1fr;
以上就是Grid布局的基本知識,個人感覺難度不是很大,就是屬性有點多,需要花時間去牢記,多寫一些布局,模仿一些網站這樣對于掌握這些知識會有很大的幫助,這兩天準備學習完Flex和Grid布局之后仿一個京東手機端的頁面練練手。
如果有跟我一樣才學習這些基礎知識的朋友大家可以相互交流一下。
件來源:阿里云開發者社區(點擊下面“了解更多”查看原文)
CSS Grid 可以將元素放入有行和列的網格中,從而讓創建二維布局成為可能。有了它,你可以自定義網格的任何形態,例如網格寬高、網格范圍、或者網格之間的間隙。但是,CSS Grid 可能會有訪問性不佳的問題,尤其是對于那些使用屏幕閱讀器和僅使用鍵盤的用戶。本篇教程將會幫助你避免此類問題。
“源順序獨立性”是 CSS Grid 強大優勢之一。這意味著你不需要像使用 float 或者表格布局那樣,在 HTML 中定義布局結構。你可以使用 CSS Grid 的排序和網格位置屬性改變 HTML 呈現的視覺效果。
W3C 的 CSS Grid 文檔中的重排序和可訪問性章節,將源順序獨立性定義為:
“通過將網格布局與媒體查詢相結合,開發者可以使用相同的語義標記,但是元素布局的重新排列是脫離源代碼順序而獨立存在的,這樣就可以同時在源代碼順序和渲染出的視覺效果兩個方面實現需要的布局。”
使用 CSS Grid,你可以將邏輯順序和視覺順序解耦。源順序獨立性在很多時候都非常有用,但是它也有可能會破壞代碼的可訪問性。使用屏幕閱讀器和鍵盤的用戶都只能看到你 HTML 文件的代碼邏輯順序,但是無法看到通過 CSS Grid 創建出來的視覺順序。
如果你的文檔很簡單,這通常不是什么大問題,因為這時候源代碼邏輯順序和視覺順序基本是一致的。但是,比較復雜、不對稱、零散,或者使用了其他創意布局的文件通常就會對使用屏幕閱讀器或者鍵盤的用戶造成困惑。
能改變視覺順序的屬性
CSS Grid 有很多可以改變文檔視覺順序的屬性:
order —— 在 flexbox 和 CSS Grid 規則中都有 order 屬性。它可以改變 flex 或者 grid 容器中項目的默認排序。
網格位置屬性 —— grid-row-start,grid-row-end,grid-column-start,grid-column-end。
上述網格位置屬性的簡寫 —— grid-row,grid-column,和 grid-area(它是 grid-row 和 grid-column 的簡寫)。
grid-template-areas —— 指定已命名的網格區的位置。
如果你想知道更多關于網格位置屬性的使用方法,可以看看我們之前關于網格區域的文章。現在,讓我們看看視覺重排序是如何造成代碼可訪問性的問題的。
這是一個簡單的網格布局,只有幾個簡單的鏈接,所以你可以使用鍵盤測試代碼:
<div class="container"> <div class="item-1"><a href="#">Link 1</a></div> <div class="item-2"><a href="#">Link 2</a></div> <div class="item-3"><a href="#">Link 3</a></div> <div class="item-4"><a href="#">Link 4</a></div> <div class="item-5"><a href="#">Link 5</a></div> <div class="item-6"><a href="#">Link 6</a></div> </div>
現在我們再加入一些樣式。下面的 CSS 代碼將網格元素放入了三個寬度相同的列中。使用 grid-row 屬性,第一個元素被移動到了第二行的開始。
.container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 0.625rem; } .item-1 { grid-row: 2; }
在下面這個圖中,你可以看到最終的視覺效果,其中 Link 1 被加上了一些特殊樣式以便突出說明。普通的用戶將會首先看到 Link 2,但是使用屏幕閱讀器的用戶將會從 Link 1 開始,因為他們遵從的是 HTML 代碼中定義的邏輯順序。
對于純鍵盤使用者,使用 tab 鍵瀏覽頁面也同樣困難,因為這樣依舊會從 Link 1 開始,也就是頁面的左下角(你可以自己嘗試一下)。
解決方案
解決方案非常簡單優雅。不要改變視覺順序,你只需要將 Link 1 移動到 HTML 文件的下面。這樣,源代碼順序和視覺順序就一致了。
<div class="container"> <div class="item-2"><a href="#">Link 2</a></div> <div class="item-3"><a href="#">Link 3</a></div> <div class="item-4"><a href="#">Link 4</a></div> <div class="item-1"><a href="#">Link 1</a></div> <div class="item-5"><a href="#">Link 5</a></div> <div class="item-6"><a href="#">Link 6</a></div> </div>
你不需要在 CSS 中為 .item-1 添加任何關于 Grid 的屬性。因為你也不用改變默認的源代碼順序了,那么你只需要為網格容器定義屬性即可。
.container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 0.625rem; }
看,盡管這個例子最終結果和以前一樣,現在它的可訪問性更高了。使用 tab 或者屏幕閱讀器都會從 Link 2 開始,邏輯上也遵循源代碼順序。
這里有幾個通用的布局模版,你可以讓使用 CSS Grid 重排序屬性的代碼可訪問性更高。例如,“圣杯布局”就是這樣一種模式。它包括一個頭部,一個主要內容區域,一個頁腳,還有兩個固定寬度的側邊欄,它們倆一個在左一個在右。
左邊欄布局可能會為使用屏幕閱讀器的用戶造成困惑。因為左邊欄在源代碼順序要要比主要內容區域靠前,而它則是使用屏幕閱讀器的用戶最先看到的內容。但是,通常情況下,使用屏幕閱讀器的用戶開始閱讀的位置最好是主要內容。特別是當左邊欄主要包括的其實是廣告,博客目錄,標簽云,或者其他一些不相關的內容。
CSS Grid 允許你改變 HTML 文件的源代碼順序,并將主要內容放在兩個側邊欄前面:
<div class="container"> <header>Header</header> <main>Main content</main> <aside class="left-sidebar">Left sidebar</aside> <aside class="right-sidebar">Right sidebar</aside> <footer>Footer</footer> </div>
還有一些其他可用的解決方案,來使用 CSS Grid 定義視覺順序的改變。大部分教程都會使用命名的網格區域,并使用 grid-template-areas 屬性對它們進行重排列。
下面的代碼是最簡單的解決方案,因為它只是為視覺順序和源代碼順序不同的元素添加了幾個額外的規則。CSS Grid 有優秀的自動排列功能,能夠把余下的網格元素搞定。
.container { display: grid; grid-template-columns: 9.375rem 1fr 9.375rem; grid-gap: 0.625rem; } header, footer { grid-column: 1 / span 3; } .left-sidebar { grid-area: 2 / 1; }
這樣,grid-column 讓 <header> 和 <footer> 區域橫跨整個屏幕(三列),然后 grid-area(grid-row 和 grid-column 的簡寫)固定了左邊欄的位置。如下就是使用這些樣式后的樣子:
盡管圣杯布局是一個相對簡單的布局,你還可以使用相同的邏輯來完成一些更復雜的布局。要始終牢記頁面的哪個部分是最重要的,哪部分是使用屏幕閱讀器的用戶在看到其他內容之前可能最想看的。
某些情況下,CSS Grid 也會對語義造成破壞;這也是影響可訪問性的一個方面。由于 display: grid; 布局僅被元素的直接子元素繼承,網格元素的子元素其實就不是網格布局的一部分了。為了節省工作量,開發者也許認為將布局扁平化是一個不錯的解決方案,所以他們就將所有希望包括在網格布局內的元素都作為網格容器的直接子元素。但是,如果一個布局被認為的扁平化了,文件的語義通常也就丟失了。
加入你想要創建一個元素展覽墻(比如圖片墻),在這里,元素按照網格排列并被一個頭部和一個頁腳包圍。如下是帶語義的標簽寫法:
<section class="container"> <header>Header</header> <ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> <li>Item 5</li> <li>Item 6</li> </ul> <footer>Footer</footer> </section>
但是如果你想要使用 CSS Grid,<section> 應該作為網格容器,<h1>、<h2> 和 <ul> 是網格元素。但是,列表內的元素不被包括在網格內,因為他們是網格容器子元素的子元素。
所以,如果你想要快速的完成工作,將布局結構扁平化也許是一個不錯的主意,也就是讓所有的元素都作為網格容器的子元素:
<section class="container"> <header>Header</header> <div class="item">Item 1</div> <div class="item">Item 2</div> <div class="item">Item 3</div> <div class="item">Item 4</div> <div class="item">Item 5</div> <div class="item">Item 6</div> <footer>Footer</footer> </section>
現在,你就可以很輕松地使用 CSS Grid 創建出想要的布局:
.container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 0.625rem; } header, footer { grid-column: 1 / span 3; }
一切看上去都非常好,但是文檔已經丟失了它最初的語義,所以:
使用屏幕閱讀器的用戶無法知道元素之間的關系,也無法知道它們其實是列表的一部分(大部分的屏幕閱讀器都會通知用戶列表元素的數量);
被破壞的語義也會讓搜索引擎很難明白你的內容;
如果用戶在禁用 CSS 的時候訪問你的內容(例如,網速不佳的時候),在瀏覽頁面時可能會很困惑,因為他們只看到一系列不相關的 div。
最重要的規則是,你絕對不能為了看上去好看而放棄語義。
解決方案
目前的解決方案通過為未排序的列表添加了 CSS 規則,創建出了嵌套的網格。
.container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 0.625rem; } .container > * { grid-column: 1 / span 3; } ul { display: inherit; grid-template-columns: inherit; grid-gap: inherit; }
在如下例子中,你可以看到嵌套的網格和父級網格是如何關聯的。元素按照期望的樣子排列出來了,但是此時,文檔始終保留著它的語義。
簡單的 CSS Grid 布局可能不會導致可訪問性的問題。但是當你想要改變視覺順序或者創建多層網格的時候,問題就可能暴露出來。解決這些問題通常不會很麻煩,所以這樣做來修復那些可訪問性問題是很值得的,因為這樣你能夠讓那些使用輔助工具的用戶更易讀懂你的內容。
稿件來源:阿里云開發者社區(點擊下面“了解更多”查看原文)
何把網頁上的內容用javascript來實現截圖?今天分享的html2canvas就可以。
在微信項目中經常會遇到動態生成海報的需求,Web前端合成圖片往往會使用canvas。canvas雖然強大,但用來合成海報非常繁瑣,一不小心就幾百行代碼了。而html2canvas.js是一款輕松地將HTML+CSS寫成的布局直接轉換成canvas,生成可保存分享的圖片。
html2canvas.js官網截圖
這是一個把HTML的DOM結構根據所支持的CSS樣式生成canvas的js開源庫,CSS的寫法千變萬化,不同的布局有很多不同的寫法,因此html2canvas是不能100%還原網頁的樣式,因此不用用于像電腦屏幕截圖這樣的需求中。
官網關于支持css的說明
使用的時候要注意查看所支持的CSS屬性,盡量使用這些屬性來寫布局,不支持的效果可以嘗試用圖片來實現。只要產品經理腦子在線,目測幾乎沒有什么海報需求是實現不了的。
官網是英文的,寫得很專業,谷歌翻譯閱讀無壓力。
html2canvas 由開發者 Niklas von Hertzen 創建,基于MIT許可開源,可以免費使用在任何項目。
關注我,持續分享高質量的免費開源、免費商用的資源。
↓↓點【了解更多】查看本次分享的相關網址。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。