SS Grid 是一種為 Web 開(kāi)發(fā)創(chuàng)建網(wǎng)站布局的方式。它已經(jīng)存在了很多年,隨著更多瀏覽器的支持,它終于變得越來(lái)越流行。
接下來(lái)我們將了解下 CSS Grid 及其工作原理。了解下它如何使用。
隨著布局系統(tǒng)的不斷發(fā)展,CSS 也取得了長(zhǎng)足的進(jìn)步。隨著 CSS Grid 的發(fā)布,我們終于有了一個(gè)強(qiáng)大的工具來(lái)創(chuàng)建二維布局。如今,設(shè)計(jì)師和開(kāi)發(fā)人員正在使用各種布局系統(tǒng),如 Flexbox 甚至純 CSS 來(lái)創(chuàng)建令人驚嘆的響應(yīng)式網(wǎng)站。但是當(dāng)涉及到某些任務(wù)時(shí),這些方法中的每一種都有其自身的局限性。在這種情況下,CSS Grid 可以派上用場(chǎng)!
有兩種使用 CSS 網(wǎng)格布局的方法:隱式和顯式。使用隱式網(wǎng)格,您只需定義所需的列數(shù),瀏覽器將自動(dòng)創(chuàng)建網(wǎng)格。使用顯式網(wǎng)格,您可以定義列數(shù)和行數(shù)。這使您可以更好地控制布局,但設(shè)置起來(lái)可能更復(fù)雜。
它是一個(gè)二維布局系統(tǒng)。這意味著它可以處理列和行。然而,與主要是一維的傳統(tǒng) CSS 布局不同,CSS Grid 旨在同時(shí)處理兩個(gè)維度。
它是一個(gè)基于容器的布局系統(tǒng)。這意味著它適用于作為容器元素的子元素的元素。容器元素定義網(wǎng)格,子元素放置在網(wǎng)格單元格中。
它是一個(gè)響應(yīng)式布局系統(tǒng)。這意味著它可以適應(yīng)不同的屏幕尺寸和分辨率。CSS Grid 也很靈活,這意味著它可以用于從簡(jiǎn)單到復(fù)雜的各種布局。
它是在現(xiàn)有的 CSS 盒子模型之上構(gòu)建的。這意味著它可以與任何現(xiàn)有的 CSS 代碼庫(kù)一起使用。但是,它還具有一些使其獨(dú)一無(wú)二的新功能。
所有這些功能在正確使用時(shí)都可以創(chuàng)建在任何屏幕尺寸上都能很好顯示的響應(yīng)式布局。
在構(gòu)建網(wǎng)頁(yè)時(shí)使用 CSS Grid 有很多好處。主要好處之一是它可以更輕松地創(chuàng)建復(fù)雜的布局。使用 CSS Grid,您可以創(chuàng)建具有多列和多行的布局,并且可以輕松控制頁(yè)面上每個(gè)元素的大小和位置。
CSS Grid 的另一個(gè)好處是它有助于保持代碼整潔有序。使用傳統(tǒng)的 CSS,您的代碼很容易變得混亂且難以閱讀。但是,使用 CSS Grid,您的所有樣式都應(yīng)用于網(wǎng)格,這使您的代碼更易于閱讀和理解。
您需要首先定義一個(gè)容器元素并為其分配一個(gè)類(lèi)名。此元素將包含您的所有內(nèi)容。在容器內(nèi)部,您將定義一系列子元素,每個(gè)子元素將占據(jù)網(wǎng)格的特定區(qū)域。您可以使用各種屬性來(lái)控制這些元素的大小和位置。之后,將以下 CSS 代碼添加到您的樣式表中:
.container {
display: grid;
}
這將創(chuàng)建一個(gè)網(wǎng)格布局,其中一列包含所有子元素。
網(wǎng)格父元素是應(yīng)用了 display: grid 屬性的元素。它可以是任何類(lèi)型的元素。
網(wǎng)格父元素的屬性:
CSS Grid 中的子屬性用于定義網(wǎng)格項(xiàng)的大小、位置和其他方面。這些是可以應(yīng)用于網(wǎng)格元素的一些主要子屬性:
網(wǎng)格允許您指定布局中的列數(shù)和行數(shù),然后將元素放置在這些列和行中。
grid-template-columns 您可以使用和 grid-template-rows 屬性控制列和行的寬度。例如,您可以使用以下代碼創(chuàng)建三列布局:
.container {
display: grid;
grid-template-columns: 100px 200px 300px;
}
您還可以使用百分比或分?jǐn)?shù)來(lái)控制列寬。例如,以下代碼將創(chuàng)建三列,第一列的寬度是第二列的兩倍,第三列的寬度是第三列的三倍:
.container {
display: grid;
grid-template-columns: 50% 33.33% 25%;
}
在布局中指定列數(shù)和行數(shù)后,您可以使用 grid-column 和 grid-row 屬性將元素放置在這些列和行中。例如,如果您有一個(gè)三列布局,您可以使用以下代碼在第一列中放置一個(gè)元素:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 columns, each 1/3 width of the container */
grid-column: 1;
}
如果你沒(méi)有使用過(guò) grid 布局,或者使用過(guò),但是用的不多的話,那么我建議您可以多嘗試下,因?yàn)楫?dāng)你用的多的時(shí)候,你就會(huì)發(fā)現(xiàn),它是真的好用。
原創(chuàng),翻譯自An Interactive Guide to CSS Grid
建議結(jié)合閱讀原文,原文示例可交互
CSS Grid 是 CSS 語(yǔ)言里最令人贊嘆的部分之一,它為我們提供了許多新型工具,可以用這些工具來(lái)創(chuàng)建精致且流暢的布局。
它還出人意料地復(fù)雜。我花了相當(dāng)長(zhǎng)的時(shí)間才真正適應(yīng) CSS 網(wǎng)格!
本教程中,我將分享我在學(xué)習(xí) CSS 網(wǎng)格布局時(shí)獲得的最大 啟發(fā)時(shí)刻。你將學(xué)習(xí)這種布局模式的基礎(chǔ)知識(shí),并了解如何用它做一些很酷的事情。?
瀏覽器支持?
CSS Grid 是構(gòu)建 CSS 布局最現(xiàn)代的工具,但它并不是 “前沿” 技術(shù);它自 2017 年以來(lái)就受到所有主流瀏覽器的支持!
根據(jù) caniuse 的數(shù)據(jù),CSS Grid 擁有 97.8% 的用戶(hù)支持率。支持程度非常高;Flexbox 的支持率也僅高出 0.5% 左右!
CSS 由多種不同的布局算法組成,每種算法都針對(duì)不同類(lèi)型的用戶(hù)界面而設(shè)計(jì)。默認(rèn)布局算法流式布局(Flow layout)適用于數(shù)字文檔。表格布局(Table layout)適用于表格數(shù)據(jù)。彈性盒布(Flexbox)局用于沿單個(gè)軸分布項(xiàng)目。
CSS 網(wǎng)格(Grid)是最新且最佳的布局算法。它非常強(qiáng)大:我們可以用它基于一些條件構(gòu)建靈活調(diào)整的復(fù)雜布局。
在我看來(lái),CSS Grid 最不尋常的部分是它僅使用 CSS 定義了網(wǎng)格結(jié)構(gòu)(即行和列):
使用用 CSS Grid,可以將一個(gè) DOM 節(jié)點(diǎn)細(xì)分為行與列。在本教程中,我們使用虛線高亮顯示行/列,但實(shí)際上它們都是不可見(jiàn)的。
這真是太奇怪了!在其他所有布局模式中,創(chuàng)建這樣的分隔區(qū)域唯一的方法就是增加更多的 DOM 節(jié)點(diǎn)。例如,在表格布局中,每一行都是用一個(gè) <tr> 來(lái)創(chuàng)建的,而該行內(nèi)的每個(gè)單元格則使用 <td> 或 <th> 來(lái)實(shí)現(xiàn):
<table>
<tbody>
<!-- First row -->
<tr>
<!-- Cells in the first row -->
<td></td>
<td></td>
<td></td>
</tr>
<!-- Second row -->
<tr>
<!-- Cells in the second row -->
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
不同于表格布局,CSS 網(wǎng)格允許我們完全在 CSS 內(nèi)部管理布局。我們可以按照自己的意愿切割容器,創(chuàng)建出網(wǎng)格子元素可以作為錨點(diǎn)使用的分隔區(qū)域。
我們通過(guò) display 屬性選擇進(jìn)入網(wǎng)格布局模式:
.wrapper {
display: grid;
}
默認(rèn)情況下,CSS 網(wǎng)格使用單列,并將根據(jù)子項(xiàng)的數(shù)量根據(jù)需要?jiǎng)?chuàng)建行。這被稱(chēng)為隱式網(wǎng)格,因?yàn)槲覀儧](méi)有明確定義任何結(jié)構(gòu)。
工作原理如下:
隱式表格是動(dòng)態(tài)的,會(huì)根據(jù)子元素的數(shù)量添加或移除行。每個(gè)子元素都有它自己的行。
默認(rèn)情況下,網(wǎng)格容器的高度由其子元素決定。它會(huì)動(dòng)態(tài)地增長(zhǎng)和縮小。有趣的是,這甚至不是“CSS 網(wǎng)格”的特性;網(wǎng)格容器仍然使用流式布局,而流式布局中的塊級(jí)元素會(huì)垂直增長(zhǎng)以包含它們的內(nèi)容。只有子元素是使用網(wǎng)格布局來(lái)排列的。
但如果我們給網(wǎng)格設(shè)定一個(gè)固定的高度呢?在那種情況下,總面積會(huì)被劃分成等大小的行:
默認(rèn)情況下,CSS 網(wǎng)格會(huì)創(chuàng)建一個(gè)單列布局。我們可以使用 grid-template-columns 屬性來(lái)指定列:
向 grid-template-columns 傳入兩個(gè)值 — 25% 和 75% — 我告訴 CSS 網(wǎng)格算法將元素切分成兩列。
列可以用任何合法的 CSS 值來(lái)定義,包括像素、rem、視口單位等等。此外,我們還可以使用一個(gè)新的單位,也就是fr單位:
“fr”表示“fraction”。在這個(gè)示例中,我們說(shuō)第一列應(yīng)占據(jù) 1 個(gè)單位的空間,而第二列占據(jù) 3 個(gè)單位的空間。這意味著共有 4 個(gè)單位的空間,這將成為分母。第一列消耗了可用空間的 ?,而第二列消耗了 ?。
fr 單位為 CSS 網(wǎng)格帶來(lái)了 Flexbox 風(fēng)格的靈活性。百分比和 <length> 值創(chuàng)建固定約束,而 fr 列可以根據(jù)需要自由增長(zhǎng)和縮小,以包含它們的內(nèi)容。
請(qǐng)嘗試增減該容器,以查看差別:
在這種場(chǎng)景下,我們的第一列有一個(gè)毛茸茸的小幽靈,顯示的寬度明確為 55 像素。但如果列太小無(wú)法包含它該怎么辦?
更確切地說(shuō),fr 分配的是多余空間。首先,列寬將根據(jù)其內(nèi)容進(jìn)行計(jì)算。如果有任何剩余空間,它將根據(jù) fr 值進(jìn)行分配。這與 flex-grow 非常相似,如我在 Flexbox 交互式指南 中所述。
總體而言,這種靈活性是一件好事。百分比太死板了。
我們可以通過(guò) gap 看到這個(gè)原理的一個(gè)非常好的例子。gap 是一個(gè)神奇的 CSS 屬性,它可以在網(wǎng)格中的所有列和行之間添加固定數(shù)量的間距。
看看當(dāng)我們?cè)诎俜直群托?shù)間切換時(shí)會(huì)發(fā)生什么:
當(dāng)使用百分比時(shí),注意內(nèi)容是如何溢出網(wǎng)格父元素的嗎?這是因?yàn)榘俜直仁鞘褂镁W(wǎng)格的總面積計(jì)算的。兩個(gè)列占用了父元素內(nèi)容區(qū)域的 100%,并且不允許它們縮小。當(dāng)我們添加 16px 的間距時(shí),這些列別無(wú)選擇,只能溢出容器。
相反,fr 單位是根據(jù)額外的空間來(lái)計(jì)算的。在這種情況下,額外的空間因 gap 而減少了 16 像素。CSS 網(wǎng)格算法會(huì)在兩個(gè)網(wǎng)格列之間分配剩余的空間。
如果我們向一個(gè)兩列的網(wǎng)格中添加超過(guò)兩個(gè)子元素會(huì)發(fā)生什么?
好吧,我們來(lái)嘗試一下:
有趣!我們的網(wǎng)格產(chǎn)生了新的行。grid算法想要確保每個(gè)子項(xiàng)都有它自己的網(wǎng)格單元格。它會(huì)根據(jù)需要生成新行,以實(shí)現(xiàn)這一目標(biāo)。在項(xiàng)目數(shù)量變化的情況下(例如照片網(wǎng)格),且希望網(wǎng)格自動(dòng)擴(kuò)展時(shí),這非常方便。
在其他情況下,我們想要顯式的定義行,創(chuàng)建特定的布局。我們可以使用 grid-template-rows 屬性來(lái)完成此操作:
通過(guò)定義 grid-template-rows 和 grid-template-columns,我們創(chuàng)建了一個(gè)明確的網(wǎng)格。這是構(gòu)建頁(yè)面布局的完美選擇,例如本教程頂部的“圣杯”布局。
想象一下我們要?jiǎng)?chuàng)建一個(gè)日歷:
CSS 網(wǎng)格是用于這種類(lèi)型事情的非常棒的工具。我們可以將其構(gòu)建為 7 列網(wǎng)格,每列占用 1 個(gè)單位的空間:
這種方法可行,但不得不數(shù)每個(gè) 1fr 項(xiàng)有點(diǎn)煩人。想象一下,如果我們有 50 列!
幸運(yùn)的是,有一個(gè)更優(yōu)雅的解決方案:
.calendar {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
repeat 函數(shù)將為我們完成復(fù)制/粘貼。我們說(shuō)我們需要 7 列,每一列的寬度都是 1fr。
默認(rèn)情況下,CSS 網(wǎng)格算法會(huì)將每個(gè)子元素分配到第一個(gè)未占用的網(wǎng)格單元格,很像一個(gè)熟練工人在地板上鋪瓷磚一樣。
不過(guò)最棒的是:我們可以把項(xiàng)目分配到我們想要的任何單元格里!孩子們甚至可以在多行/多列中展開(kāi)。
這是一個(gè)展示此工作原理的交互式演示。點(diǎn)擊/按住并拖動(dòng)以將孩子放在網(wǎng)格中:
.parent {
display: grid;
grid-template-columns:
repeat(4, 1fr);
grid-template-rows:
repeat(4, 1fr);
}
.child {
grid-row: 2;
grid-column: 2;
}
grid-row 和 grid-column 屬性允許我們指定網(wǎng)格子元素應(yīng)占據(jù)哪個(gè)軌道。
如果我們希望孩子占用單獨(dú)一行或列,我們可以通過(guò)其編號(hào)來(lái)指定它。grid-column: 3 會(huì)將孩子設(shè)置在第三列中。
網(wǎng)格子組件也可以跨多行/列拉伸。其語(yǔ)法是使用斜杠來(lái)定義開(kāi)始和結(jié)束:
.child {
grid-column: 1 / 4;
}
乍一看,這看起來(lái)像一個(gè)分?jǐn)?shù) ?。然而,在 CSS 中,斜杠字符不用于除法,它用于分隔值組。在這種情況下,它允許我們?cè)谝粋€(gè)聲明中設(shè)置開(kāi)始和結(jié)束列。
這是一種簡(jiǎn)寫(xiě),它相當(dāng)于:
.child {
grid-column-start: 1;
grid-column-end: 4;
}
這里有一個(gè)狡猾的陷阱:我們提供的值是基于列的“線”而不是列的“索引”。
從一張圖中,最容易理解這個(gè)陷阱:
.child {
grid-row: 2 / 4;
grid-column: 1 / 4;
}
雖然令人費(fèi)解,但一個(gè) 4 列的網(wǎng)格實(shí)際上有 5 條列線。當(dāng)我們將一個(gè)子元素分配到網(wǎng)格時(shí),我們使用這些線來(lái)錨定它們。如果我們想要子元素跨越前 3 列,它需要從第 1 條線開(kāi)始,并在第 4 條線上結(jié)束。
好的,現(xiàn)在要談?wù)?CSS Grid 最酷的部分之一。
假設(shè)我們要建立此布局:
根據(jù)我們目前已經(jīng)學(xué)到的東西,我們可以構(gòu)建如下這種結(jié)構(gòu):
.grid {
display: grid;
grid-template-columns: 2fr 5fr;
grid-template-rows: 50px 1fr;
}
.sidebar {
grid-column: 1;
grid-row: 1 / 3;
}
header {
grid-column: 2;
grid-row: 1;
}
main {
grid-column: 2;
grid-row: 2;
}
這種方法可行,但有一種更符合人體工學(xué)的方法可以用:網(wǎng)格區(qū)域。
看看它長(zhǎng)什么樣:
.parent {
display: grid;
grid-template-columns: 2fr 5fr;
grid-template-rows: 50px 1fr;
grid-template-areas:
'sidebar header'
'sidebar main';
}
.child {
grid-area: sidebar;
}
一如既往,我們使用 grid-template-columns 和 grid-template-rows 定義網(wǎng)格結(jié)構(gòu)。然后,我們有了這個(gè)奇怪的聲明:
.parent {
grid-template-areas:
'sidebar header'
'sidebar main';
}
這原理如下:我們正在畫(huà)我們想要?jiǎng)?chuàng)建的表格,有點(diǎn)像我們制作 ASCII 藝術(shù)一樣。每一行表示一行,每個(gè)單詞都是我們給表格特定部分起的名字。明白它為何從視覺(jué)上看起來(lái)像表格了嗎?
于是,我們不再為子元素分配 grid-column 和 grid-row,而是為其分配 grid-area!
當(dāng)我們希望某個(gè)區(qū)域跨越多行或多列時(shí),可以在模板中重復(fù)此區(qū)域的名稱(chēng)。在此示例中,“sidebar”區(qū)域跨越兩行,因此我們?yōu)榈谝涣兄械膬蓚€(gè)單元格都編寫(xiě)了“sidebar”。
應(yīng)該使用區(qū)塊還是行/列呢?在構(gòu)建像這樣明確的布局時(shí),我非常喜歡使用區(qū)塊。這可以讓我為我的網(wǎng)格分配賦予語(yǔ)義含義,而不是使用難以理解的行/列編號(hào)。話雖如此,只有當(dāng)網(wǎng)格有固定數(shù)量的行和列時(shí),區(qū)塊才能發(fā)揮最佳作用。grid-column 和 grid-row 可以用于隱式網(wǎng)格。
網(wǎng)格分配存在一個(gè)很大的問(wèn)題:標(biāo)簽順序仍將基于 DOM 位置,而非網(wǎng)格位置。
我們用一個(gè)例子來(lái)說(shuō)明一下,在這個(gè) playground 中,我準(zhǔn)備了一組按鈕,并用 CSS Grid 進(jìn)行布局。
<div class="wrapper">
<button class="btn one">
One
</button>
<button class="btn four">
Four
</button>
<button class="btn six">
Six
</button>
<button class="btn two">
Two
</button>
<button class="btn five">
Five
</button>
<button class="btn three">
Three
</button>
</div>
按鈕似乎有順序。從左向右、從上到下閱讀,我們從一到六。
如果你有帶鍵盤(pán)的設(shè)備,請(qǐng)嘗試通過(guò)這些按鈕來(lái)切換。 您可以先點(diǎn)擊左上角的第一個(gè)按鈕(“一”),然后連續(xù)按 Tab 鍵,逐個(gè)切換按鈕。
您應(yīng)該看到類(lèi)似這樣的內(nèi)容:
用戶(hù)看來(lái),焦點(diǎn)輪廓沒(méi)有任何道理地跳躍到頁(yè)面的各個(gè)部分。發(fā)生這種情況是因?yàn)榘粹o的焦點(diǎn)基于它們?cè)?DOM 中的順序。
為了修復(fù)這個(gè)問(wèn)題,我們應(yīng)該在 DOM 中重新排列網(wǎng)格的子元素,以便它們與可視順序匹配,這樣我就可以從左到右,從上至下進(jìn)行制表鍵切換。
在迄今為止的所有示例中,我們的列和行都延伸來(lái)填充整個(gè)網(wǎng)格容器。但這種情況并非一定要發(fā)生!
例如,我們定義了兩個(gè) 90px 寬的列。只要網(wǎng)格父級(jí)大于 180px,那么就會(huì)在末端產(chǎn)生一些空白:
通過(guò) justify-content 屬性,我們可以控制列分布:
如果您熟悉 Flexbox 布局算法,那么這聽(tīng)起來(lái)可能很熟悉。CSS Grid 基于 Flexbox 首次引入的對(duì)齊屬性,并將這些屬性發(fā)揮到了極致。
最大的區(qū)別是,我們要調(diào)整的是 列,而不是元素本身。實(shí)質(zhì)上,justify-content 讓我們可以整理網(wǎng)格的隔間,以我們希望的方式在網(wǎng)格中分布。
如果我們想在列內(nèi)對(duì)齊項(xiàng)目本身,我們可以使用 justify-items 屬性:
當(dāng)我們將一個(gè) DOM 節(jié)點(diǎn)放入網(wǎng)格父元素中時(shí),默認(rèn)行為是使其跨越該列的整個(gè)寬度,就像流布局中的 <div> 會(huì)水平拉伸以填充其容器一樣。但是使用 justify-items 可以調(diào)整這種行為。
這很有用,因?yàn)樗试S我們擺脫列的剛性對(duì)稱(chēng)。當(dāng)我們把 justify-items 設(shè)置為 stretch 以外的其他值時(shí),子項(xiàng)將縮小至由其內(nèi)容確定的默認(rèn)寬度。結(jié)果,同一列中的項(xiàng)目可以具有不同的寬度。
我們可以使用 justify-self 屬性來(lái)控制一個(gè)特定的網(wǎng)格子項(xiàng)的對(duì)齊方式:
與用于設(shè)置網(wǎng)格父級(jí)并控制所有網(wǎng)格子元素對(duì)齊方式的 justify-items 不同,justify-self 是在子元素上設(shè)置的。我們可以將 justify-items 看作在所有網(wǎng)格子元素上設(shè)置 justify-self 的默認(rèn)值的方式。
迄今為止,我們一直在談?wù)撊绾卧谒椒较蛏蠈?duì)齊內(nèi)容。CSS 網(wǎng)格布局提供了一組額外的屬性,用以在垂直方向上對(duì)齊內(nèi)容:
align-content與justify-content類(lèi)似,但它影響的是行而不是列。類(lèi)似地,align-items與justify-items類(lèi)似,但它處理的是網(wǎng)格區(qū)域內(nèi)項(xiàng)目_垂直_對(duì)齊方式,而不是水平對(duì)齊方式。
更進(jìn)一步分解為:
最后,除了justify-self,我們還有align-self。該屬性控制單元格內(nèi)單個(gè)網(wǎng)格項(xiàng)的垂直位置。
還有一件事我必須給你演示一下。這是我喜歡的小技巧之一,用 CSS Grid 實(shí)現(xiàn)的。
使用僅有的兩個(gè) CSS 屬性,我們可以讓子元素在容器中居中,無(wú)論水平還是垂直方向:
.parent {
display: grid;
place-content: center;
}
place-content 是一個(gè)簡(jiǎn)寫(xiě)形式屬性。它等同于以下代碼:
.parent {
justify-content: center;
align-content: center;
}
正如我們已經(jīng)了解的,justify-content 控制了列的位置。align-content 控制了行的位置。在這種情況下,我們有一個(gè)具有一個(gè)子項(xiàng)的隱式網(wǎng)格,因此我們最終得到一個(gè) 1×1 網(wǎng)格。place-content: center 將行和列都推到中心位置。
在現(xiàn)代 CSS 中有多種方法可以使 div 居中,但是這是我知道的唯一一種只需要兩個(gè) CSS 聲明的方法!
本教程涵蓋了 CSS 網(wǎng)格布局算法的一些基本內(nèi)容,但老實(shí)說(shuō),我們還沒(méi)有談?wù)撨^(guò) 很多東西!
如果你覺(jué)得這篇博文有幫助,你可能會(huì)對(duì)這個(gè)我精心制作的學(xué)習(xí)資源感興趣,它非常深入。它叫《 CSS for JavaScript Developers.》。
本課程使用了與我的博客相同的技術(shù),因此其充滿(mǎn)了交互式說(shuō)明。但也包含一些小視頻、練習(xí)題、靈感源自現(xiàn)實(shí)世界的項(xiàng)目,甚至還有一些小游戲。
如果您覺(jué)得此博客文章有幫助,您會(huì)喜歡這門(mén)課程。它遵循類(lèi)似的方法,但適用于整個(gè) CSS 語(yǔ)言,并通過(guò)動(dòng)手練習(xí)來(lái)確保您確實(shí)在發(fā)展新的技能。
專(zhuān)為使用 React/Angular/Vue 等 JS 框架的人打造。80% 的課程將教授 CSS 基礎(chǔ),我們還會(huì)學(xué)習(xí)如何將這些基礎(chǔ)知識(shí)集成到現(xiàn)代 JS 應(yīng)用程序中,如何構(gòu)建 CSS 等。
如果你在學(xué)習(xí) CSS 的時(shí)候遇到困難,我希望你能試試它。尤其在你已經(jīng)熟悉 HTML 和 JS 的情況下,掌握 CSS 是能夠徹底改變游戲規(guī)則的。當(dāng)你掌握了三者之后,你便可以更容易地進(jìn)入狀態(tài),真正地享受 Web 應(yīng)用程序的開(kāi)發(fā)。
希望這個(gè)指南對(duì)您有用。??
2023年11月22日
. 流式定位
這是網(wǎng)頁(yè)元素默認(rèn)的定位方式,網(wǎng)頁(yè)元素按照其HTML標(biāo)簽的先后順序,在網(wǎng)頁(yè)內(nèi)依次顯示,就像液體一樣“流動(dòng)”,所以稱(chēng)為“流式定位”,這種方式將所有網(wǎng)頁(yè)元素的默認(rèn)顯示方式分為以下幾種類(lèi)型:
塊級(jí)元素(display: block): 可以設(shè)置寬度,默認(rèn)寬度為100%,但不管多寬都會(huì)獨(dú)占一行,多個(gè)塊級(jí)元素按從上到下的順序縱向顯示,默認(rèn)顯示為塊級(jí)元素的包括:段落(p)、層(div)、表單(form)等。
內(nèi)聯(lián)元素(display: inline): 不會(huì)獨(dú)占一行,可以多個(gè)元素共享一行,按從左至右的順序橫向顯示,默認(rèn)顯示為內(nèi)聯(lián)元素的包括:文本標(biāo)簽(label)、鏈接(a)等。
行內(nèi)塊元素(display: inline-block): 這種定位方式兼具塊級(jí)元素和內(nèi)聯(lián)元素的優(yōu)勢(shì),既可以像塊級(jí)元素一樣設(shè)置寬度和高度,又可以一行放置多個(gè),默認(rèn)顯示為內(nèi)聯(lián)元素的包括:圖片(img)、輸入項(xiàng)(input)、多行文本(textarea)等。
可以通過(guò)設(shè)置HTML元素的CSS樣式的display屬性來(lái)改變?cè)啬J(rèn)的流式定位方式,例如將層(div)元素設(shè)置為行內(nèi)塊元素后,就可以跟文本標(biāo)簽(label)、圖片(img)等元素放在同一行顯示,不再獨(dú)占一行。
流式定位存在一些問(wèn)題,主要包括:
l 塊級(jí)元素很難被有效利用起來(lái),因?yàn)槠洫?dú)占一行的特性,不能一行顯示多個(gè)。
l 內(nèi)聯(lián)元素?zé)o法設(shè)置寬度、高度和垂直方向邊距,不好精確控制元素大小和顯示位置。
l 內(nèi)聯(lián)元素之間水平方向會(huì)因?yàn)榇a中的空格、換行等產(chǎn)生間隙,垂直方向存在默認(rèn)的底部間隙,這給水平布局帶來(lái)額外的麻煩。
2. 浮動(dòng)定位
浮動(dòng)定位會(huì)讓元素脫離原來(lái)的標(biāo)準(zhǔn)文檔流浮動(dòng)起來(lái),直至它的外邊緣遇到父元素的內(nèi)邊緣或者另一個(gè)兄弟浮動(dòng)元素的外邊緣。
任何HTML元素都可以設(shè)置為浮動(dòng),可以通過(guò)設(shè)置HTML元素的CSS樣式的float屬性來(lái)設(shè)置具體的浮動(dòng)方式,可以選擇向左浮動(dòng)(float: left)或向右浮動(dòng)(float: right)。
相對(duì)于網(wǎng)頁(yè)默認(rèn)的流式定位,浮動(dòng)定位有以下優(yōu)勢(shì):
l 多個(gè)塊級(jí)元素可以共享一行。
l 內(nèi)聯(lián)元素可以設(shè)置寬度和高度。
l 元素之間的空格、換行不影響元素的顯示位置。
浮動(dòng)定位最初被設(shè)計(jì)出來(lái)是為了實(shí)現(xiàn)文字環(huán)繞圖片顯示的效果,但由于其上述優(yōu)勢(shì),后來(lái)大家也用浮動(dòng)定位來(lái)設(shè)置更多網(wǎng)頁(yè)元素的位置,代替默認(rèn)的流式定位,也是TaskBuilder默認(rèn)的組件定位方式。
不過(guò),浮動(dòng)定位也有一些問(wèn)題,不是所有的場(chǎng)合都適合,大家根據(jù)需要選擇,這些問(wèn)題包括:
l 居中對(duì)齊問(wèn)題:浮動(dòng)定位不太好實(shí)現(xiàn)垂直和水平居中對(duì)齊。
l 父元素的高度塌陷問(wèn)題:如果元素不浮動(dòng),會(huì)自動(dòng)撐開(kāi)父元素的高度,浮動(dòng)后,由于浮動(dòng)元素已經(jīng)脫離原來(lái)的標(biāo)準(zhǔn)流,如果父元素沒(méi)有設(shè)置高度,且父元素中沒(méi)有其他非浮動(dòng)元素時(shí),會(huì)造成父元素的高度塌陷(高度變成了0)。
3. 坐標(biāo)定位
坐標(biāo)定位是指為HTML元素設(shè)置上下左右的偏移量來(lái)確定其具體的顯示位置或大小,通過(guò)設(shè)置元素CSS的position屬性,可以選擇坐標(biāo)定位的具體方式,包括:
相對(duì)定位(position: relative):即相對(duì)于元素在流式定位時(shí)的正常位置進(jìn)行定位,您可以通過(guò) top、right、bottom、left 這 4 個(gè)CSS屬性來(lái)設(shè)置元素相對(duì)于正常位置的偏移量,在此過(guò)程中不會(huì)對(duì)其它元素造成影響。
相對(duì)定位示意圖
絕對(duì)定位(position: absolute):即相對(duì)于第一個(gè)非靜態(tài)定位的父級(jí)元素進(jìn)行定位,可以通過(guò) top、right、bottom、left 這 4 個(gè)屬性來(lái)設(shè)置元素相對(duì)于父級(jí)元素位置的偏移量。如果沒(méi)有滿(mǎn)足條件的父級(jí)元素,則會(huì)相對(duì)于瀏覽器窗口來(lái)進(jìn)行定位。元素使用絕對(duì)定位后,其他標(biāo)準(zhǔn)流元素會(huì)填補(bǔ)它的位置。絕對(duì)定位可以通過(guò)設(shè)置元素CSS樣式的left和top屬性來(lái)精確控制元素的顯示位置,再設(shè)置right或bottom這兩個(gè)CSS樣式,實(shí)現(xiàn)元素的寬度或高度根據(jù)父元素的寬度和高度動(dòng)態(tài)設(shè)置和變化。
絕對(duì)定位示意圖
固定定位(position: fixed):即相對(duì)于瀏覽器的窗口進(jìn)行定位,可以使用 top、right、bottom、left 這 4 個(gè)CSS屬性來(lái)定義元素相對(duì)于瀏覽器窗口的位置。使用固定定位的元素?zé)o論如何滾動(dòng)瀏覽器窗口,元素的位置都是固定不變的。
粘性定位(position: sticky):它是相對(duì)定位和固定定位的結(jié)合體,能夠?qū)崿F(xiàn)類(lèi)似吸附的效果,當(dāng)滾動(dòng)頁(yè)面時(shí)它的效果與相對(duì)定位相同,當(dāng)元素要滾動(dòng)到屏幕之外時(shí)則會(huì)自動(dòng)變成固定定位的效果。用粘性定位很容易實(shí)現(xiàn)元素置頂顯示的效果。
4. 表格定位
顧名思義,表格定位就是用表格來(lái)實(shí)現(xiàn)網(wǎng)頁(yè)內(nèi)容的定位,先繪制一個(gè)多行多列的表格,并設(shè)定表格各列的寬度和各行的高度,然后在表格的單元格里插入相關(guān)網(wǎng)頁(yè)元素,最終實(shí)現(xiàn)這些元素的位置定位。
這種定位方式比較適合可以將頁(yè)面內(nèi)容清晰明確地劃分為多行多列的場(chǎng)景,例如各種業(yè)務(wù)單據(jù)和數(shù)據(jù)報(bào)表等。
有兩種方式可以實(shí)現(xiàn)表格布局: HTML Table(<table>標(biāo)簽)和CSS Table(display:table 等相關(guān)屬性)。HTML Table是早期網(wǎng)頁(yè)設(shè)計(jì)采用的表格定位方式,由于其渲染性能較低,且有些界面效果較難實(shí)現(xiàn),用的人已經(jīng)比較少了,現(xiàn)在推薦使用CSS Table,能實(shí)現(xiàn)一些HTML Table做不到的效果。
目前,TaskBuilder只是在報(bào)表設(shè)計(jì)器里集成了一個(gè)第三方的表格插件,在前端tfp頁(yè)面設(shè)計(jì)器里,還沒(méi)有提供表格定位相應(yīng)的容器組件,未來(lái)會(huì)提供。(現(xiàn)有的可編輯表格和數(shù)據(jù)表格不是用來(lái)為其他組件提供定位的,所以不能算作是表格定位的容器組件)
5. 彈性定位
彈性定位又叫彈性布局,這種定位方式最大的特點(diǎn)就是可以讓子元素的大小可以根據(jù)父元素的大小自動(dòng)擴(kuò)張或收縮,從而可以做到自動(dòng)適應(yīng)不同終端的屏幕尺寸,或者在用戶(hù)改變?yōu)g覽器窗口大小時(shí)自動(dòng)伸縮。
這種定位方式需要先將一個(gè)父元素的CSS屬性display設(shè)置為flex,然后該元素里的子元素即可實(shí)現(xiàn)彈性定位。
采用彈性定位的容器元素可以設(shè)置以下CSS樣式:
元素排列方向(flex-direction):用來(lái)設(shè)置子元素的排列方向,有四種方式可以選擇:從左到右顯示(row)、從右到左顯示(row-reverse)、從上到下顯示(column)、從下到上顯示(column-reverse)。
元素水平對(duì)齊方式(justify-content):用來(lái)設(shè)置子元素在水平方向的對(duì)齊方式,可以選左對(duì)齊(flex-start)、右對(duì)齊(flex-end)、居中對(duì)齊(center)、兩端對(duì)齊(space-between)和等距對(duì)齊(space-around)。
元素垂直對(duì)齊方式(align-items):用來(lái)設(shè)置子元素在垂直方向的對(duì)齊方式,可以選頂部對(duì)齊(flex-start)、底部對(duì)齊(flex-end)、居中對(duì)齊(center)、基線對(duì)齊(baseline)、自動(dòng)伸展(stretch)。
內(nèi)容整體對(duì)齊方式(align-content):當(dāng)有多行子元素時(shí),可以用該屬性設(shè)置全部子元素整體的垂直對(duì)齊方式,包括自動(dòng)拉伸(stretch)、在容器的頂部排列(flex-start)、在容器的底部排列(flex-end)、在容器內(nèi)居中排列(center)、均勻分布,上下靠邊(space-between)、均勻分布,每行等距(space-around)。
元素是否自動(dòng)換行(flex-wrap):用來(lái)設(shè)置子元素是否自動(dòng)換行。
彈性定位容器內(nèi)的子元素可以設(shè)置以下CSS樣式:
擴(kuò)展量(flex-grow):必須參數(shù),用來(lái)設(shè)置當(dāng)前元素相對(duì)于其他元素的增長(zhǎng)量,默認(rèn)值為 0,即如果存在剩余空間,也不自動(dòng)放大。
如果所有元素的擴(kuò)展量都設(shè)置為1,將等分剩余空間。如果一個(gè)元素的擴(kuò)展量設(shè)置為2,其他元素都為1,則前者占據(jù)的剩余空間將是其他項(xiàng)的2倍,如下圖所示:
收縮量(flex-shrink):必須參數(shù),用來(lái)設(shè)置當(dāng)彈性容器空間不足時(shí),該元素相對(duì)于其他元素的收縮量,默認(rèn)值為 1。如果所有元素的flex-shrink屬性都為1,當(dāng)空間不足時(shí),都將等比例縮小。如果一個(gè)元素的flex-shrink屬性為0,其他元素都為1,則空間不足時(shí),前者不縮小。
基準(zhǔn)長(zhǎng)度(flex-basis):必須參數(shù),元素的基準(zhǔn)長(zhǎng)度定義了父容器在分配多余空間之前,當(dāng)前元素占據(jù)的主軸空間(main size,如果是橫向排列,則指父容器在水平方向的空間,如果是縱向排列,則指父容器在垂直方向的空間)。瀏覽器根據(jù)這個(gè)屬性,計(jì)算主軸是否有多余空間。合法值為 auto(默認(rèn)值,表示根據(jù)其他情況自動(dòng)伸縮),或者以具體的值加 "%"、"px"等單位的形式,表示該元素將占據(jù)固定空間。
顯示順序(order):屬性用來(lái)設(shè)置元素在容器中出現(xiàn)的順序,您可以通過(guò)具體的數(shù)值來(lái)定義元素在容器中的位置,默認(rèn)值為 0。下圖所示的四個(gè)普通的面板組件,在彈性面板里從左至右的正常插入順序是panel1、panel2、panel3、panel4,但通過(guò)設(shè)置這四個(gè)面板的顯示順序,將panel1和panel4的顯示位置進(jìn)行了調(diào)換。
對(duì)齊方式(align-self):該屬性允許您為某個(gè)特定的元素設(shè)置不同于其它元素的對(duì)齊方式,該屬性可以覆蓋父容器組件(彈性面板)里的垂直對(duì)齊屬性的值。該屬性的可選頂部對(duì)齊(flex-start)、底部對(duì)齊(flex-end)、居中對(duì)齊(center)、基線對(duì)齊(baseline)、自動(dòng)伸展(stretch)。
由于彈性定位的自動(dòng)伸縮特性,且易于實(shí)現(xiàn)子元素的水平和垂直對(duì)齊,目前很多主流的前端UI框架都大量地采用了該定位方式。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。