CSS樣式布局筆記

層疊樣式表(英文全稱:Cascading Style Sheets)是一種用來(lái)表現(xiàn)HTML或XML等文件樣式的計(jì)算機(jī)語(yǔ)言

1. 正常文檔流(Normal Flow)

沒有用任何CSS來(lái)改變頁(yè)面布局的網(wǎng)頁(yè)怒见,那么網(wǎng)頁(yè)元素就會(huì)排列在一個(gè)正常流(normal flow)之中死遭。在正常流中象浑,元素盒子(boxes)會(huì)基于文檔的寫作模式(writing mode)一個(gè)接一個(gè)地排列招狸。意味著胯究,如果你的寫作模式是水平方向的(句子是從左到右或從右到左書寫)系忙,正常流會(huì)垂直地一個(gè)接一個(gè)排列頁(yè)面的塊級(jí)元素

<div class="container">
  <div>1</div>
  <p>CSS 能夠?qū)W(wǎng)頁(yè)中元素位置的排版進(jìn)行像素級(jí)精確控制又碌,支持幾乎所有的字體字號(hào)樣式畅卓,擁有對(duì)網(wǎng)頁(yè)對(duì)象和模型樣式編輯的能力</p>
  <br/>
  <p>從HTML被發(fā)明開始埃难,樣式就以各種形式存在</p>
</div>

正常流是一種最基礎(chǔ)的布局:當(dāng)你為文檔應(yīng)用了CSS莹弊、創(chuàng)建了某些CSS布局,你其實(shí)是讓這些塊做了一個(gè)正常文檔流之外的“事”

1.1. 通過(guò)頁(yè)面結(jié)構(gòu)來(lái)發(fā)揮正常文檔流的優(yōu)勢(shì)

通過(guò)確保你書寫的頁(yè)面具有良好的頁(yè)面結(jié)構(gòu)(well-structured manner)涡尘,你可以最大程度利用正常流所帶來(lái)的優(yōu)勢(shì)忍弛。試想一下,如果瀏覽器中沒有正常流考抄,那么你創(chuàng)建的元素都會(huì)堆積在瀏覽器的右上角细疚。這就意味著你必須指定所有的元素的布局方式。
有了正常流川梅,即使CSS加載失敗了疯兼,用戶仍然能閱讀你的頁(yè)面內(nèi)容;同時(shí)贫途,一些不使用CSS的工具(例如一些閱讀器)會(huì)按照元素在文檔中的位置來(lái)讀取頁(yè)面內(nèi)容吧彪。如果你的內(nèi)容順序和用戶預(yù)期的閱讀順序一致,你就不需要為了將元素調(diào)整到正確的位置而進(jìn)行大量的布局調(diào)整

1.2. 脫離正常文檔流

一旦你有了一個(gè)結(jié)構(gòu)良好的頁(yè)面丢早,你就需要去決定如何利用它并將它變?yōu)槲覀冃枰牟季纸Y(jié)構(gòu)姨裸。這會(huì)涉及到 脫離正常文檔流(moving away from normal flow),后續(xù)的部分內(nèi)容有許多布局可以學(xué)習(xí)使用怨酝。

2. 浮動(dòng)(Float)

float屬性定義元素在哪個(gè)方向浮動(dòng)傀缩。以往這個(gè)屬性總應(yīng)用于圖像,使文本圍繞在圖像周圍农猬,不過(guò)在 CSS 中赡艰,任何元素都可以浮動(dòng)。浮動(dòng)元素會(huì)生成一個(gè)塊級(jí)框斤葱,而不論它本身是何種元素瞄摊。如果浮動(dòng)非替換元素,則要指定一個(gè)明確的寬度苦掘;否則换帜,它們會(huì)盡可能地窄。
浮動(dòng)被用來(lái)將盒子(box)置于左側(cè)或右側(cè)鹤啡,同時(shí)讓內(nèi)容環(huán)繞其展示惯驼。要讓一個(gè)元素進(jìn)行浮動(dòng),需要為該元素設(shè)置一個(gè)值為leftright的float屬性。默認(rèn)值為none祟牲。

當(dāng)你使某個(gè)元素浮動(dòng)并讓文字環(huán)繞它時(shí)隙畜,內(nèi)容的line box被截?cái)嗔恕H绻阕屢粋€(gè)元素浮動(dòng)说贝,同時(shí)為緊跟著的包含文本的元素設(shè)置一個(gè)背景色议惰,你會(huì)發(fā)現(xiàn)背景色會(huì)出現(xiàn)在浮動(dòng)元素下方

  .item{
    float: left;
    width: 100px;
    height: 100px;
    background-color: pink;
  }

如果你想要在浮動(dòng)元素和環(huán)繞的文本之間創(chuàng)建邊距,你需要給浮動(dòng)元素設(shè)置外邊距乡恕。在文本元素上設(shè)置外邊距只會(huì)讓其相對(duì)于容器縮進(jìn)言询。例如在下面這個(gè)例子中,你就需要為左側(cè)浮動(dòng)的圖片設(shè)置右邊距和下邊距

 .item{
    margin: 0 30px 30px 0;
}
2.1. 清除浮動(dòng)

一旦你對(duì)一個(gè)元素應(yīng)用了浮動(dòng)傲宜,所有接下來(lái)的元素都會(huì)環(huán)繞它直到內(nèi)容處于它下方且開始應(yīng)用正常文檔流运杭。如果你想要避免這種情況,可以手動(dòng)去清除浮動(dòng)函卒。

當(dāng)你不想要某個(gè)元素受到其之前的浮動(dòng)元素影響時(shí)辆憔,為其添加clear: both屬性即可。使用left值可以清除左浮動(dòng)效果报嵌,right值為右浮動(dòng)虱咧,both則會(huì)清除左右浮動(dòng)。


但是锚国,當(dāng)你發(fā)現(xiàn)在容器內(nèi)有了一個(gè)浮動(dòng)元素彤钟,同時(shí)容器文本內(nèi)容過(guò)短時(shí)就會(huì)出現(xiàn)問(wèn)題。文本盒子會(huì)被繪制在浮動(dòng)元素下跷叉,然后接下來(lái)的部分會(huì)以正常流繪制在其后逸雹。

為了避免這種情況,我們需要為容器中某個(gè)元素應(yīng)用clear屬性云挟。我們可以在容器最后添加一個(gè)空元素并設(shè)置clear屬性梆砸。但是在某些情況下可能無(wú)法使用這種方式。因此园欣,比較常見的清除浮動(dòng)的方案是:在容器內(nèi)添加一個(gè)CSS偽元素帖世,并將其clear屬性設(shè)置為both。

  .container p::after{
    content: "";
    display: block;
    clear: both;
  }
2.2. 塊級(jí)格式化上下文(Block Formatting Context)

清除浮動(dòng)的另一個(gè)方法是在容器內(nèi)創(chuàng)建BFC沸枯。一個(gè)BFC元素完全包裹住了它內(nèi)部的所有元素日矫,包括內(nèi)部的浮動(dòng)元素,保證浮動(dòng)元素不會(huì)超出其底部绑榴。創(chuàng)建BFC的方式有很多種哪轿,其中最常用的一種清除浮動(dòng)的方式是為元素設(shè)置除visible(默認(rèn))之外的overflow: auto屬性值

像上面這樣使用overflow一般情況下是有效的。然而翔怎,在某些情況下窃诉,這可能會(huì)帶來(lái)一些陰影的截?cái)嗷蚴欠穷A(yù)期的滾動(dòng)條杨耙。同時(shí)它也使你的CSS變得不那么直觀:為了使清除浮動(dòng)的意圖更加直觀,并且避免BFC的負(fù)面影響飘痛,你可以使用flow-root作為display屬性的值珊膜。display: flow-root做的唯一的一件事就是去創(chuàng)建一個(gè)BFC,因此可以避免其他創(chuàng)建BFC方法帶來(lái)的問(wèn)題宣脉。

2.3. 浮動(dòng)的一些遺留用法

在新的布局方式出現(xiàn)以前车柠,float經(jīng)常會(huì)被用來(lái)創(chuàng)建多欄布局。我們會(huì)給一系列元素設(shè)置寬度并且將它們一個(gè)接一個(gè)進(jìn)行浮動(dòng)塑猖。通過(guò)為浮動(dòng)元素設(shè)置一些精細(xì)的百分比大小可以創(chuàng)建類似網(wǎng)格的效果竹祷。

我不建議在當(dāng)下仍然過(guò)度地使用這種方法。但是萌庆,在現(xiàn)有的網(wǎng)站中,這種方式仍然會(huì)存在許多年币旧。因此践险,當(dāng)你碰到一個(gè)頁(yè)面里面到處是float的應(yīng)用,可以確定它就是用的這種技術(shù)吹菱。

3. 定位(Positioning)

想要把一個(gè)元素從正常流中移除巍虫,或者改變其在正常文檔流中的位置,可以使用CSS中的position屬性鳍刷。當(dāng)處于正常文檔流時(shí)规揪,元素的position屬性為static诗鸭。在塊級(jí)維度上元素會(huì)一個(gè)接一個(gè)排列下去,當(dāng)你滾動(dòng)頁(yè)面時(shí)元素也會(huì)隨著滾動(dòng)。

當(dāng)你改變?cè)氐膒osition屬性時(shí)欠雌,通常情況下你也會(huì)設(shè)置一些偏移量來(lái)使元素相對(duì)于參照點(diǎn)進(jìn)行一定的移動(dòng)。不同的position值會(huì)產(chǎn)生不同的參照點(diǎn)业筏。

3.1. 相對(duì)定位(relative postioning)

如果一個(gè)元素具有屬性position: relative姨俩,那么它偏移的參照位是其原先在正常文檔流中的位置。你可以使用top北戏、left负芋、bottom和right屬性來(lái)相對(duì)其正常流位置進(jìn)行移動(dòng)。

注意嗜愈,頁(yè)面上的其他元素并不會(huì)因該元素的位置變化而受到影響旧蛾。該元素在正常流中的位置會(huì)被保留,因此你需要自己去處理一些元素內(nèi)容覆蓋的情況蠕嫁。

<div class="container">
  <p>P1</p>
  <div class="item">1</div>
  <p>P2</p>
</div>

<style>
  .item{
    width: 50px;
    height: 50px;
    background-color: pink;
    position: relative;
    bottom: 20px;
  }
</style>
3.2. 絕對(duì)定位(absolute postioning)

給一個(gè)元素設(shè)置position: absolute屬性可以將其完全從正常流中移除锨天。其原本占據(jù)的空間也會(huì)被移除。該元素會(huì)定位會(huì)相對(duì)于視口容器剃毒,除非其某個(gè)祖先元素也是定位元素(position值不為static)绍绘。

因此,當(dāng)你為某個(gè)元素設(shè)置position: absolute時(shí),首先發(fā)生的變化是該元素會(huì)定位在視口的左上角陪拘。你可以通過(guò)設(shè)置top厂镇、left、bottom和right偏移量屬性來(lái)將元素移動(dòng)到你想要的位置

通常情況下你并不希望元素相對(duì)于視口進(jìn)行定位左刽,而是相對(duì)于容器元素捺信。在這種情況下,你需要為容器元素設(shè)置一個(gè)除了默認(rèn)static之外的值欠痴。

由于給一個(gè)元素設(shè)置position: relative并不會(huì)將其從正常流中移除迄靠,所以通常這是一個(gè)不錯(cuò)的選擇。給你想要相對(duì)的容器元素設(shè)置position : relative喇辽,就可以讓絕對(duì)定位的元素相對(duì)其進(jìn)行偏移掌挚。

  .item{
    width: 50px;
    height: 50px;
    background-color: pink;
    position: absolute;
    top: 20px;
    left: 50px;
  }
3.3. 固定定位(fixed positioning)

大多數(shù)情況下,position: fixed的元素會(huì)相對(duì)于視口定位菩咨,并且會(huì)從正常文檔流中被移除吠式,不會(huì)保留它所占據(jù)的空間。當(dāng)頁(yè)面滾動(dòng)時(shí)抽米,固定的元素會(huì)留在相對(duì)于視口的位置特占,而其他正常流中的內(nèi)容則和通常一樣滾動(dòng)。

當(dāng)你想要一個(gè)固定導(dǎo)航欄一直停留在屏幕上時(shí)這會(huì)非常有效云茸。和其他的position值一樣是目,這也可能會(huì)造成一些元素被遮擋,需要小心保證頁(yè)面內(nèi)容的可讀而不會(huì)被固定元素遮擋标捺。

為了使一個(gè)固定定位的元素不相對(duì)于視口進(jìn)行定位懊纳,你需要為容器元素設(shè)置transform、perspective亡容、filter三個(gè)屬性之一(不為默認(rèn)值none)长踊。這樣固定的元素就會(huì)相對(duì)于該塊級(jí)元素偏移,而非視口萍倡。

  .item{
    width: 50px;
    height: 50px;
    background-color: pink;
    position: fixed;
    top: 20px;
    left: 30px;
  }
3.4. STICKY 定位

設(shè)置position: sticky會(huì)讓元素在頁(yè)面滾動(dòng)時(shí)如同在正常流中身弊,但當(dāng)其滾動(dòng)到相對(duì)于視口的某個(gè)特定位置時(shí)就會(huì)固定在屏幕上,如同fixed一般列敲。這個(gè)屬性值是一個(gè)較新的CSS屬性阱佛,在瀏覽器兼容性上會(huì)差一些,但在不兼容的瀏覽器中會(huì)被忽略并會(huì)退到正常的滾動(dòng)情況戴而。

下面的代碼展示了如何創(chuàng)建一個(gè)非常流行導(dǎo)航欄效果:導(dǎo)航欄會(huì)隨著頁(yè)面滾動(dòng)凑术,而當(dāng)導(dǎo)航欄滾動(dòng)到頁(yè)面頂部時(shí)則會(huì)固定在頂部位置。

  .item{
    width: 50px;
    height: 50px;
    background-color: pink;
    position: sticky;
    top: 0;
    width: 100%;
  }

4. 彈性布局(Flex Layout)

彈性盒子(Flexbox)布局是一種為一維布局而設(shè)計(jì)的布局方法所意。一維的意思是你希望內(nèi)容是按行或者列來(lái)布局淮逊。你可以使用display: flex來(lái)將元素變?yōu)閺椥圆季执呤住T撊萜鞯闹苯幼釉貢?huì)變?yōu)閺椥皂?xiàng)(flex item),并按行排列泄鹏。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

<style>
  .container {
    border: 5px solid burlywood;
    border-radius: .5em;
    background-color: lightgrey;
    padding: 10px;
    display: flex;
  }
  .item {
    width: 50px;
    height: 50px;
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }
</style>

4.1. 彈性盒子的軸(axes)

在上面的例子中郎任,我們會(huì)稱彈性項(xiàng)在行內(nèi)是從起始位置開始排列,而不是說(shuō)它們是左對(duì)齊备籽。這些元素會(huì)按行排列是因?yàn)槟J(rèn)的flex-direction值為row舶治,row代表了文本的行文方向。由于我們工作的環(huán)境是英文(中文也是如此)车猬,一種自左向右的語(yǔ)言霉猛,行的開始位置就是在左邊,因此我們的彈性項(xiàng)也是從左邊開始的珠闰。因此flex-direction的值被定義為彈性盒子的主軸(main axis)惜浅。

交叉軸(cross axis)則是和主軸垂直的一條軸。如果你的flex-direction是row并且彈性項(xiàng)是按照行內(nèi)方向排列的伏嗜,那么交叉軸就是塊級(jí)元素的排列方向坛悉。如果flex-direction是column那么彈性項(xiàng)就會(huì)以塊級(jí)元素排列的方向排布,然后交叉軸就會(huì)變?yōu)閞ow阅仔。設(shè)置flex-direction: column效果如下:

4.2. 方向和次序

彈性盒子模型讓我們可以通過(guò)為flex-direction屬性設(shè)置row-reverse或column-reverse值來(lái)改變主軸上彈性項(xiàng)的方向吹散。當(dāng)然弧械,你也可以通過(guò)order屬性來(lái)改變某一個(gè)彈性項(xiàng)的順序八酒。但是要特別注意,這可能會(huì)給那些通過(guò)鍵盤(而非鼠標(biāo)或觸屏)訪問(wèn)你的網(wǎng)站的用戶帶來(lái)一些麻煩刃唐,因?yàn)閠ab的順序是頁(yè)面內(nèi)元素在源碼中的順序而非顯示順序羞迷。設(shè)置flex-direction: row-reverse效果如下:

4.3. 一些Flex的屬性

這些flex的屬性是用來(lái)控制彈性項(xiàng)在主軸上空間大小的。這三個(gè)屬性是:

flex-grow / flex-shrink / flex-basis

通郴ⅲ可以使用它們的簡(jiǎn)寫形式:flex: 1 1 200px衔瓮;第一個(gè)值代表flex-grow,第二個(gè)是flex-shrink抖甘,而第三個(gè)則是flex-basis热鞍。

flex-basis會(huì)為彈性項(xiàng)設(shè)置未拉伸和壓縮時(shí)的初始大小。在上面的例子中衔彻,大小是200px薇宠,因此我們會(huì)給每個(gè)項(xiàng)200px的空間大小。但是大多數(shù)情況下容器元素大小不會(huì)正好被分為許多200px大小的項(xiàng)艰额,而是可能有一些不足或剩余空間澄港。flex-grow和flow-shrink屬性允許我們在容器大小不足或有空余時(shí)控制各個(gè)彈性項(xiàng)的大小。

如果flex-grow的值是任意的正數(shù)柄沮,那么彈性項(xiàng)會(huì)被允許拉伸來(lái)占據(jù)更多的空間回梧。因此废岂,在上面的例子中,當(dāng)各項(xiàng)被設(shè)為200px后狱意,所有多余的空間會(huì)被每個(gè)彈性項(xiàng)平分并填滿湖苞。

如果flex-shrink的值為任意的正數(shù),那么當(dāng)彈性項(xiàng)被設(shè)置了flex-basis后髓涯,元素溢出容器時(shí)會(huì)進(jìn)行收縮袒啼。在上面這個(gè)CSS的例子中,如果容器空間不足纬纪,每個(gè)彈性項(xiàng)會(huì)等比例縮放以適應(yīng)容器的大小蚓再。

flex-grow和flex-shrink的值可以是任意的正數(shù)。一個(gè)具有較大flex-grow值的彈性項(xiàng)會(huì)在容器有剩余空間時(shí)拉伸更大的比例包各;而一個(gè)具有更大flex-shrink值的項(xiàng)則會(huì)在容器空間不足時(shí)被壓縮的更多摘仅。

  .item {
    flex: 1 1 200px;
    width: 200px;
    height: 50px;
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }

  .container :nth-child(1) {
    flex: 10 1 200px;
  }

5. 網(wǎng)格布局(grid layout)

CSS網(wǎng)格布局(grid layout)是一種用來(lái)進(jìn)行二維布局的技術(shù)。二維(two-dimesional)意味著你希望按照行和列來(lái)排布你的內(nèi)容问畅。和彈性盒子類似娃属,網(wǎng)格布局也需要設(shè)置一個(gè)display值。你可以為容器元素設(shè)置display: grid护姆,并且使用grid-template-columnsgrid-template-rows屬性來(lái)控制網(wǎng)格中的行與列矾端。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>

<style>
  .container {
    width: 780px;
    border: 5px solid burlywood;
    border-radius: .5em;
    background-color: lightgrey;
    padding: 10px;
    display: grid;
    grid-template-columns: 200px auto auto;
    grid-template-rows: 80px 80px;
  }
  .item {
    width: 200px;
    height: 50px;
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }
</style>

這段CSS會(huì)創(chuàng)建一個(gè)行列元素大小固定的網(wǎng)格。不過(guò)這也許并不是你希望的卵皂。默認(rèn)值為auto秩铆,你可以認(rèn)為這代表了“讓格子盡可能的大”。如果你每沒有指定行(row track)的大小灯变,所有添加進(jìn)來(lái)的行內(nèi)容大小都會(huì)被置為auto殴玛。一種常用的模式是為網(wǎng)格制定列寬度,但是允許網(wǎng)格按需添加行添祸。

你可以使用任意的長(zhǎng)度單位或時(shí)百分比來(lái)設(shè)置行與列滚粟,同時(shí)你可以使用為網(wǎng)格系統(tǒng)所創(chuàng)造的新的單位——fr。fr是一種彈性單位刃泌,它可以指定網(wǎng)格容器內(nèi)的空間被如何劃分凡壤。

網(wǎng)格會(huì)替你計(jì)算與分配空間,你不需要去計(jì)算元素的百分比去適應(yīng)容器大小耙替。在下面這個(gè)例子中亚侠,我們使用fr來(lái)創(chuàng)建網(wǎng)格的列,這使得網(wǎng)格的列可以自適應(yīng)林艘。同時(shí)我們還使用了grid-gap來(lái)保證元素間的間距(關(guān)于網(wǎng)格內(nèi)元素與的間距會(huì)在“對(duì)齊”這一部分詳細(xì)介紹)盖奈。

  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
5.1. 關(guān)于網(wǎng)格的一些術(shù)語(yǔ)

網(wǎng)格系統(tǒng)總是有兩個(gè)軸:inline axis表示頁(yè)面中文字的文字排列的方向,block axis表示頁(yè)面中塊級(jí)元素的排列方向狐援。

一個(gè)被設(shè)置為display: grid的元素就是所謂的網(wǎng)格容器钢坦。在網(wǎng)格容器中會(huì)有網(wǎng)格線(grid line)究孕,網(wǎng)格線就是你在指定grid-template-columnsgrid-template-rows時(shí)網(wǎng)格中行列所生成的。網(wǎng)格中的最小單位(也就是被四條網(wǎng)格線截取生成的區(qū)域)被成為網(wǎng)格單元格(grid cell)爹凹,進(jìn)一步的厨诸,由若干個(gè)單元格組成的矩形區(qū)域被成為網(wǎng)格區(qū)域(grid area)。

5.2. 網(wǎng)格的自動(dòng)排列規(guī)則

一旦你創(chuàng)建了網(wǎng)格禾酱,那么網(wǎng)格容器的直接子元素就會(huì)開始將它們自己一個(gè)一個(gè)地放置在網(wǎng)格的單元格中微酬。子元素的放置是依據(jù)網(wǎng)格的自動(dòng)排列規(guī)則(auto-placement rule)。這些規(guī)則確保了網(wǎng)格內(nèi)元素是被安排在各個(gè)空的單元格中颤陶,而不會(huì)彼此遮蓋颗管。

網(wǎng)格中任何沒有被進(jìn)行定位的直接子元素都會(huì)根據(jù)自動(dòng)排列規(guī)則進(jìn)行放置。在下面這個(gè)列子中滓走,我讓每三個(gè)元素中的第一個(gè)占據(jù)兩行垦江,但仍然從起始行開始去自動(dòng)排列(自動(dòng)伸縮需元素需去除width&height屬性)。

  .container :nth-child(1){
    grid-row-end: span 2;
  }

5.3. 基于行/列的基本定位方法

定位網(wǎng)格元素最簡(jiǎn)單的方式是使用基于行/列(line)的定位方法搅方,只需告訴瀏覽器從哪一排到哪一排來(lái)進(jìn)行合并比吭。例如,如果你需要一個(gè)2*2的網(wǎng)格區(qū)域姨涡,你可以將指定元素從第一行開始到第三行衩藤、從第一列開始到第三列,這樣就可以覆蓋到四個(gè)單元格涛漂。

.item {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
}
可簡(jiǎn)寫為:
.item {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
}

你也可以讓網(wǎng)格項(xiàng)(grid item)占據(jù)同一個(gè)單元格赏表。支持一些內(nèi)容間會(huì)覆蓋的設(shè)計(jì)。網(wǎng)格項(xiàng)會(huì)像通常網(wǎng)頁(yè)中的元素那樣疊起來(lái)怖喻,在html源碼中下面的網(wǎng)格項(xiàng)會(huì)疊在其他元素上面底哗。你仍然可以用z-index來(lái)控制它的堆疊順序

  .container :nth-child(1){
    grid-column: 1 / 3;
    grid-row: 2;
    z-index: 100;
  }
  .container :nth-child(4){
    grid-row: 1/3;
    grid-column: 2;
    background-color: rgba(11,41,97,.3);
  }
5.4. 通過(guò)命名區(qū)域來(lái)定位元素

你可以通過(guò)命名區(qū)域(named areas)來(lái)定位網(wǎng)格中的元素岁诉。要是用這種方式锚沸,你需要給每個(gè)元素一個(gè)名字,然后通過(guò)grid-template-areas屬性的值來(lái)描述布局方式涕癣。

使用這種方式有幾個(gè)需要注意的點(diǎn)哗蜈。如果你想要合并一些單元格作為你的網(wǎng)格項(xiàng),你需要重復(fù)元素的名字坠韩。網(wǎng)格區(qū)域需要能形成一個(gè)完整的矩形 —— 每個(gè)單元格都需要被填入一個(gè)值距潘。如果你想要空出某些單元格,那就需要使用.這個(gè)值只搁。例如在下面的CSS里我將最右下角的單元格留空音比。

    grid-template-areas:
        "a a b"
        "a c c";
6. 顯示順序和文檔順序(visual and document order)

在文章的最開始,我建議你以從上到下的閱讀順序來(lái)組織你的文檔順序氢惋,這樣會(huì)有助于可讀性和CSS的布局方式洞翩。從我們關(guān)于彈性盒子和CSS網(wǎng)格的簡(jiǎn)短介紹來(lái)看稽犁,你可以發(fā)現(xiàn)用這些布局方法可能會(huì)極大地改變頁(yè)面展示的元素在文檔中的順序。這可能會(huì)導(dǎo)致一個(gè)隱含的問(wèn)題骚亿。

在一些非可視化的應(yīng)用場(chǎng)景中已亥,瀏覽器會(huì)遵循文檔源碼來(lái)進(jìn)行使用。因此来屠,屏幕閱讀器會(huì)讀取文檔的順序虑椎,此外使用鍵盤tab鍵來(lái)瀏覽的用戶訪問(wèn)文檔的順序是基于源碼的順序,而不是元素展示的順序俱笛。許多屏幕閱讀器的用戶并非完全失明捆姜,他們可能在使用屏幕閱讀器的同時(shí)也能夠看到這些元素在文檔的哪個(gè)部分。在這些情況下迎膜,當(dāng)與源碼進(jìn)行對(duì)比時(shí)娇未,這種混亂的頁(yè)面展現(xiàn)可能會(huì)令人充滿迷惑。

當(dāng)你改變了元素在文檔中原來(lái)的順序時(shí)星虹,一定確保知道自己在做什么零抬。如果你發(fā)現(xiàn)你自己正在CSS中重新排序你的元素,你應(yīng)該去回頭看看是否要重新組織你的頁(yè)面元素宽涌。你可以通過(guò)使用tab訪問(wèn)來(lái)測(cè)試一下你的頁(yè)面平夜。

7. 盒模型的生成(box generation)

你寫在網(wǎng)頁(yè)里的任何東西都會(huì)生成一個(gè)盒子(box),這篇文章討論的所有東西其實(shí)都是如何能夠使用CSS來(lái)按照你的設(shè)計(jì)布局這些盒子卸亮。然而忽妒,在某些情況下,你可能根本不想創(chuàng)建一個(gè)盒子兼贸。有兩個(gè)display的屬性值會(huì)幫你處理這種情況段直。

7.1. 不生成盒子或內(nèi)容(display: none)

如果你希望元素以及它所有的內(nèi)容(包括所有子元素)都不會(huì)生成,你可以使用display: none溶诞。這樣元素就不會(huì)被展示鸯檬,并且不會(huì)保留其本該占有的空間

7.2 不生成該元素螺垢,但是生成其所有子元素(display: contents)

display: content是display的一個(gè)新的屬性值喧务。為一個(gè)元素應(yīng)用display: content屬性會(huì)導(dǎo)致其自身的盒子不生成但所有的子元素都會(huì)照常生成。這有什么用呢枉圃?試想一下功茴,如果你希望一個(gè)彈性布局或網(wǎng)格布局中的非直接子元素能應(yīng)用這些布局,這就會(huì)非常有用孽亲。

在下面這個(gè)例子里坎穿,第一個(gè)彈性項(xiàng)包含了兩個(gè)子元素,由于它被設(shè)為display: contents,它的盒子不會(huì)生成并且它的兩個(gè)子元素會(huì)成為彈性項(xiàng)玲昧,并被當(dāng)作彈性盒子容器的直接子元素來(lái)布局犯祠。

<div class="container">
  <div class="item">
    <div class="subitem">A</div>
    <div class="subitem">B</div>
  </div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

<style>
  .container {
    border: 5px solid burlywood;
    border-radius: .5em;
    background-color: lightgrey;
    padding: 10px;
    display: flex;
  }

  .item {
    width: 200px;
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }
</style>

增加以下樣式后:

  .subitem {
    width: 200px;
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }

  .container .item:first-child{
    display: contents;
  }

8. 對(duì)齊

在以前,要實(shí)現(xiàn)對(duì)齊往往會(huì)用到一些很"tricky"的方式酌呆,并且能夠使用的方法也非常有限衡载。隨著CSS盒模型對(duì)齊(box alignment module)的出現(xiàn),這一切都發(fā)生了變化隙袁。你將會(huì)使用它來(lái)控制網(wǎng)格容器與彈性盒子容器中的對(duì)齊痰娱。未來(lái)其他的各種布局方法都會(huì)應(yīng)用這些對(duì)齊屬性。盒模型對(duì)齊(box alignment specification)規(guī)范中的一系列詳細(xì)屬性如下:

  • justify-content
  • align-content
  • place-content
  • justify-items
  • align-items
  • place-items
  • justify-self
  • align-self
  • place-self
  • row-gap
  • column-gap
  • gap

由于不同的布局模型有不同的特性菩收,因此用于不同布局模型的對(duì)齊屬性會(huì)有一些表現(xiàn)上的差異梨睁。讓我們來(lái)看看在一些簡(jiǎn)單的網(wǎng)格與彈性布局中對(duì)齊是如何工作的。

align-itemsjustify-items屬性相對(duì)是align-selfjustify-self屬性的一種批量形式娜饵。這些屬性會(huì)控制與元素在其網(wǎng)格區(qū)域(grid area)中的對(duì)齊情況坡贺。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
</div>

<style>
  .container {
    border: 5px solid burlywood;
    border-radius: .5em;
    background-color: lightgrey;
    padding: 10px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-auto-rows: minmax(100px, auto);
    grid-gap: 20px;
    align-items: center;
    justify-items: start;
  }

  .item {
    width: 200px;
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }

  .container :nth-child(5){
    align-self: end;
    justify-self: end;
  }
</style>

align-contentjustify-content屬性則會(huì)對(duì)網(wǎng)格中的行/列(tracks)進(jìn)行對(duì)齊控制(網(wǎng)格容器中需要在排列完行/列元素后有多余的空間)。

    align-content: space-between;
    justify-content: end;

在彈性盒子中箱舞,align-itemsalign-self用來(lái)解決交叉軸上的對(duì)齊問(wèn)題遍坟,而justify-content則用于解決主軸上空間的分配。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

<style>
  .container {
    border: 5px solid burlywood;
    border-radius: .5em;
    background-color: lightgrey;
    padding: 10px;
    display: flex;
    height: 200px;
    justify-content: space-between;
    align-items: flex-end;
  }
  .item {
    width: 200px;
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }
  .container :nth-child(3){
    align-self: stretch;
  }
</style>

在交叉軸上晴股,把彈性行(flex line)和額外空間包裹在彈性容器中之后愿伴,你就可以使用align-content了。

8.1. 行/列的間隔

一個(gè)多欄布局具有column-gap屬性电湘,到目前位置隔节,網(wǎng)格布局具有grid-column-gapgrid-row-gapgrid-gap寂呛。這些現(xiàn)在都被從grid標(biāo)準(zhǔn)中刪除而被添加進(jìn)盒模型對(duì)齊中了怎诫。與此同時(shí),grid-的前綴屬性被重命名為column-gap贷痪、row-gapgap幻妓。瀏覽器會(huì)將帶有前綴的屬性換為新的重命名屬性,所以如果你在目前的代碼中使用兼容性更好的老名字也不用擔(dān)心呢诬。

重命名意味著這些屬性也能被應(yīng)用于其他布局方法涌哲,一個(gè)明顯的備選就是彈性盒子胖缤。雖然目前沒有瀏覽器支持盒子模型中的gap屬性尚镰,但是在未來(lái)我們應(yīng)該可以使用column-gaprow-gap來(lái)創(chuàng)建彈性項(xiàng)目元素間的間距。

9. 多欄布局(多列布局)

多欄布局(multi-column layout)是一種支持創(chuàng)建多欄的布局類型哪廓,如同報(bào)紙上那樣狗唉。每一塊都被分割成欄(column),你會(huì)按照塊方向在欄中往下讀然后會(huì)在回到下一欄的頂部涡真。然而用這種方式閱讀在網(wǎng)頁(yè)內(nèi)容中并不總是有效分俯,因?yàn)槿藗儾⒉幌肴プ対L動(dòng)條滾動(dòng)來(lái)肾筐、滾動(dòng)去地去閱讀。當(dāng)需要展示少部分內(nèi)容缸剪、折疊一組復(fù)選框或者其他一些小的UI組件時(shí)會(huì)非常有用吗铐。

當(dāng)展示一組高度不同的卡片或產(chǎn)品時(shí)多欄布局也非常有用。

9.1. 設(shè)置欄的寬度

要設(shè)置一個(gè)最有的欄寬杏节,并通知瀏覽器依此寬度展示盡可能多的欄可以使用下面的CSS:

.container {
    column-width: 300px;
}

這會(huì)創(chuàng)建盡可能多的300px的欄唬渗,所有剩下的空間會(huì)被所有欄共享。因此奋渔,除非空間被劃分為300px時(shí)沒有剩余镊逝,否則你的欄會(huì)比300px稍多一些。

9.2. 設(shè)置欄的數(shù)目

除了設(shè)置寬度嫉鲸,你可以使用column-count來(lái)設(shè)置欄的數(shù)目撑蒜。在這種情況下,瀏覽器會(huì)將空間均分給你需要的數(shù)目的欄玄渗。

.container {
    column-count: 3;
}

如果你同時(shí)添加了column-widthcolumn-count座菠,那么column-count屬性會(huì)作為一個(gè)最大值限制。在下面的代碼里藤树,欄會(huì)被添加直到達(dá)到三個(gè)辈灼,此時(shí)任何額外的空間都會(huì)被分給三欄,即使空間足夠成為一個(gè)額外的新欄也榄。

.container {
    column-width: 300px;
    column-count: 3;
}
9.3. 間距和欄規(guī)則

你無(wú)法為單個(gè)欄盒子添加外邊距和內(nèi)邊距巡莹,需要用column-gap屬性來(lái)設(shè)置間距。如果你不具體指定column-gap的值甜紫,它會(huì)默認(rèn)為1em來(lái)防止欄間碰撞降宅。這和其他布局方法中column-gap的行為不一樣,其他布局中默認(rèn)為0囚霸。你可以在間距上使用任意的長(zhǎng)度單元腰根,包括0(如果你不希望有欄間距)。

column-rule屬性讓你有能力向兩欄間*添加規(guī)則拓型。它是column-rule-width额嘿、column-rule-colorcolumn-rule-style的簡(jiǎn)寫形式,可border行為類似劣挫。注意册养,一個(gè)規(guī)則自身不會(huì)占用任何空間。它會(huì)占據(jù)在間距的頂部压固,從而增加或減少那些你設(shè)置column-gap的規(guī)則與內(nèi)容間的空間球拦。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3<br/>33</div>
</div>

<style>
  .container {
    border: 5px solid burlywood;
    border-radius: .5em;
    background-color: lightgrey;
    padding: 10px;
    column-width: 240px;
    column-gap: 20px;
    column-rule: 4px dotted #000;
  }
  .item {
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }
</style>
9.4. 允許元素橫跨多欄

你可以使用column-span屬性讓多欄容器內(nèi)的元素橫跨多欄,類似通欄。
當(dāng)column-span出現(xiàn)時(shí)坎炼,多欄容器分欄會(huì)在這個(gè)元素上放停下愧膀,因此,容器里的內(nèi)容會(huì)在元素上方形成多欄樣式谣光,然后在橫跨元素(spanning element)的下方形成一組新的欄盒子(column box)檩淋。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3<br/>33</div>
  <div class="special">header</div>
  <div class="item">2</div>
  <div class="item">3<br/>33</div>
</div>

<style>
  .container {
    border: 5px solid burlywood;
    border-radius: .5em;
    background-color: lightgrey;
    padding: 10px;
    column-width: 240px;
    column-gap: 20px;
    column-rule: 4px dotted #000;
  }
  .item {
    padding: 10px;
    background-color: rgba(111,41,97,.3);
    border: 2px solid rgba(111,41,97,.5);
  }
  .special{
    column-span: all;
    background-color: rgba(193,225,237,.6);
    border:2px solid rgba(193,225,237,.6);
    margin: 1em 0;
    padding: .5em;
  }
</style>

你只可以使用column-span: allcolumn-span: none,并不能讓元素橫跨某幾個(gè)欄(非通欄)萄金。在文章寫作時(shí)狼钮,F(xiàn)irefox還不支持column-span屬性。

10. 碎片化(Fragmentation)

多欄布局是碎片化(fragmentation)的一個(gè)例子捡絮,頁(yè)面內(nèi)容會(huì)被拆分成欄熬芜。這和打印時(shí)內(nèi)容被分到不同頁(yè)非常類似。這個(gè)過(guò)程是碎片化規(guī)范(Fragmentation specification)處理的福稳。這個(gè)規(guī)范包括了一些幫助控制內(nèi)容切分的屬性涎拉。

11. 布局類型選擇

大多數(shù)的網(wǎng)頁(yè)會(huì)混合使用多種布局類型。各布局規(guī)范都準(zhǔn)確定義了它們之間是如何相互作用的的圆。例如鼓拧,你可能會(huì)在網(wǎng)格布局的網(wǎng)格項(xiàng)中使用彈性布局。一些彈性容器可能具有定位屬性或浮動(dòng)越妈。這些規(guī)范根據(jù)最優(yōu)的布局方式已經(jīng)包含了布局模型的混合使用季俩。在這篇指南中,我嘗試概述了這種布局類型的基本使用方式梅掠,來(lái)幫助你了解實(shí)現(xiàn)一個(gè)效果可能的最好方法酌住。

然而,別害怕去運(yùn)用多種方式來(lái)實(shí)現(xiàn)布局設(shè)計(jì)阎抒。擔(dān)心你的選擇會(huì)不會(huì)造成實(shí)際問(wèn)題的情況比你想象中要少很多酪我。所以請(qǐng)?jiān)陂_始就組織好你的文檔結(jié)構(gòu),并且注意你文檔內(nèi)容的可視展示順序且叁。剩下的大部分工作就是在瀏覽器中試試你的布局方式是否符合預(yù)期。

原文鏈接:https://juejin.cn/post/6844903634849759239

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子毡代,更是在濱河造成了極大的恐慌,老刑警劉巖酪耕,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異盟步,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)黄橘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門子巾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)线梗,“玉大人廉羔,你說(shuō)我怎么就攤上這事≈竦玻” “怎么了梯码?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我许溅,道長(zhǎng),這世上最難降的妖魔是什么并蝗? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任筛峭,我火速辦了婚禮镰吵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勺馆。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布嘿般。 她就那樣靜靜地躺著功偿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吨瞎。 梳的紋絲不亂的頭發(fā)上对湃,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嘿架,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播戈擒,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼眶明,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了筐高?” 一聲冷哼從身側(cè)響起蜀肘,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后罢艾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體楣颠,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年咐蚯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了童漩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡春锋,死狀恐怖矫膨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情看疙,我是刑警寧澤豆拨,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站能庆,受9級(jí)特大地震影響施禾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜搁胆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一弥搞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渠旁,春花似錦攀例、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至杂靶,卻和暖如春梆惯,著一層夾襖步出監(jiān)牢的瞬間酱鸭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工垛吗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凹髓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓怯屉,卻偏偏與公主長(zhǎng)得像蔚舀,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锨络,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容