freeCodeCamp 旅途4 - 響應式設計和布局

彈性盒子

網頁的用戶界面(User Interface 縮寫 UI)包括兩個部分:

  • 第一部分是視覺要素,如色彩、字體和圖片等。
  • 第二部分是這些元素的排列和定位。
    CSS3 引入了 Flexible Box,簡稱 flexbox(彈性盒子),它特別適合用來創建彈性的頁面布局。彈性布局以一種可預見的方式排列元素,使其適用于不同尺寸的設備。雖然這是個新東西,但所有現代瀏覽器都已經支持 flexbox。

使用 display: flex 定位兩個盒子

只要在一個元素的 CSS 中添加display: flex;,就可以使用其他 flex 屬性來構建響應式頁面了。

#box-container {    height: 500px;    display: flex;  }
#box-1 {    background-color: dodgerblue;    width: 50%;    height: 50%;      }
#box-2 {    background-color: orangered;    width: 50%;    height: 50%;      }

使用 flex-direction 屬性

添加了display: flex的元素會成為 flex 容器。只要把flex-direction屬性添加到父元素,并設置其為 rowcolumn 即可輕易橫或豎排列它的子元素。設為 row 可以讓子元素水平排列,column 可以讓子元素垂直排列。默認值為 row。
flex-direction: row-reverse; // 一行逆序排列

使用 flex-direction 創建多行,使用flex-direction屬性可以把子元素排列成一行。這個屬性告訴 CSS 需要將這個元素的子元素水平排列。

使用 flex-direction 屬性創建一列,#box-container { display: flex; height: 500px; flex-direction: column; }

使用 flex-direction 創建多列, header .profile-name { display: flex; flex-direction: column; margin-left: 10px; }

使用 justify-content 屬性對齊元素

flex 容器里的 flex 子元素有時不能充滿整個容器,所以我們需要告訴 CSS 如何以特定方案排列和調整 flex 子元素。justify-content屬性就是處理這個問題。

元素橫著排列

把 flex 容器設為一個行,它的子元素會從左到右逐個排列,把 flex 容器設為一個列,它的子元素會從上到下逐個排列。子元素排列的方向被稱為 main axis(主軸)。對于行,主軸水平貫穿每一個項目;對于列,主軸垂直貫穿每一個項目。

關于 flex 子元素在主軸排列方式,可以選擇以下值:其中一個很常用的是justify-content: center;,可以讓 flex 子元素排列在 flex 容器中間。其他可選值還有:

  • flex-start:從 flex 容器的前端開始排列項目。對行來說是把項目都靠左放,對于列是把項目都靠頂部放。
  • flex-end:從 flex 容器的后端開始排列項目。對行來說是把項目都靠右放,對于列是把項目都靠底部放。
  • space-between:項目間保留一定間距地在主軸排列。第一個和最后一個項目會被擠到容器邊沿。例如,在行中第一個項目會緊貼著容器左側,最后一個項目會緊貼著容器右側,然后其他項目均勻排布。
  • space-around:與space-between相似,但頭尾兩個項目不會緊貼容器邊緣,空間會均勻分布在所有項目兩邊

使用 align-items 屬性對齊元素

align-items屬性與justify-content類似。justify-content屬性使 flex 子元素沿主軸排列。行的主軸是水平線,列的主軸是垂直線。

Flex 容器中,與主軸垂直的叫做 cross axis(交叉軸)。行的交叉軸是垂直的,列的交叉軸是水平的。CSS 提供了align-items屬性,可以用于在交叉軸調整 flex 子元素。對于行,它規定了項目在容器中應該靠上還是靠下,而對于列,就是靠左或靠右。
align-items的可選值包括:

  • flex-start:從 flex 容器的前端開始排列項目。對行來說是把項目都靠頂部放,對于列是把項目都靠左放。
  • flex-end:從 flex 容器的后端開始排列項目。對行來說是把項目都靠底部放,對于列是把項目都靠右放。
  • center:把項目的位置調整到中間。對于行,垂直居中(項目上下方空間相等)。對于列,水平居中(項目左右方空間相等)。
  • stretch:拉伸項目,填滿 flex 容器。例如,排成行的項目從容器頂部拉伸到底部。
  • baseline:基線對齊地排列。基線是字體相關的概念,可以認為字體坐落在基線上。

使用 flex-wrap 屬性包裹一行或一列

CSS flexbox 有一個把 flex 子元素拆分為多行(或多列)的特性。默認情況下,flex 容器會調整項目大小,把它們都塞到一起。如果是行的話,所有項目都會在一條直線上。
使用flex-wrap屬性可以使項目換行。這意味著多出來的項目會被移到新的行或列。換行發生的斷點由項目和容器的大小決定。
換行方向的可選值有這些:

  • nowrap:默認值,不換行。
  • wrap:行從上到下排,列從左到又排。
  • wrap-reverse:行從下到上排,列從右到左排。

使用 flex-shrink 屬性收縮項目

flex-shrink屬性使用之后,如果 flex 容器太小,該項目會自動縮小。當容器的寬度小于里面所有項目的寬度,項目就會自動壓縮。
flex-shrink屬性接受 number 類型的值。數值越大,與其他項目相比會被壓縮得更厲害。例如,如果一個項目的flex-shrink為 1 ,另一個項目flex-shrink為 3,那么 3 的那個與另一個相比會受到 3 倍壓縮。

使用 flex-grow 屬性擴展項目

flex-shrink相對的是flex-growflex-shrink會在容器太小時對元素作出調整。相應地,flex-grow會在容器太大時對元素作出調整。
如果一個項目flex-grow屬性的值為 1,另一個flex-grow為 3,那么 3 的會比 1 的擴大三倍。

使用 flex-basic 屬性設置項目的初始大小

flex-basis屬性指定了項目在 CSS 進行flex-shrinkflex-grow調整前的初始大小。
flex-basis屬性的單位與其他 size 屬性一致(pxem%等)。如果值為auto,項目的大小依賴于自身內容。

使用 flex 短方法屬性

flex 屬性有一個簡寫方式。flex-growflex-shrinkflex-basis屬性可以在flex中一同設置。
例如,flex: 1 0 10px;會把項目屬性設為flex-grow: 1;flex-shrink: 0;以及flex-basis: 10px;。屬性的默認設置是flex: 0 1 auto;

  #box-1 {    background-color: dodgerblue;     height: 200px;    
    flex: 2 2 150px;    
  }
  #box-2 {    background-color: orangered;    height: 200px;
    flex: 1 1 150px;
  }
/* 在容器大于 300px 時,會讓#box-1填充倍率為#box-2的兩倍;
在容器小于 300px 時,縮小倍率為#box-2的兩倍。
300px 是兩個盒子的flex-basis的值之和。 */

使用 order 屬性重新排列項目

order屬性告訴 CSS flex 容器里項目的順序。默認情況下,項目排列順序與源 HTML 文件中順序相同。這個屬性接受數字作為參數,可以使用負數。

使用 align-self 屬性

flex 子元素的最后一個屬性是align-self。這個屬性允許你調整每個項目自己的對齊方式,而不是一次性設置全部項目。因為floatclearvertical-align等調整使用的屬性都不能應用在 flex 子元素,所以這個屬性顯得十分有用。
align-self的允許值與align-items一樣,并且它會覆蓋align-items的值。

CSS 網格

CSS Grid 幫助你輕松實現復雜的 Web 設計。它通過把 HTML 元素轉換為具有行和列的網格容器,以便將子元素放置在所需要的位置。

創建

通過將屬性display的值設為grid,使 HTML 元素變為網格容器。通過前面的操作,你可以對該容器使用與 CSS 網格(CSS Grid)相關的屬性。display:grid;

在 CSS 網格中,父元素稱為容器(container),它的子元素稱為項(items)。

使用 grid-template-columns 添加多列, grid-template-rows 添加多行

在一個網格容器中使用grid-template-columns屬性可以添加一些列,示例如下:
.container { display: grid; grid-template-columns: 50px 50px; }可以在網格容器中添加兩列,寬度均為 50px。

grid-template-columns屬性值的個數表示網格的列數,而每個值表示對應列的寬度。

使用 grid-template-rows 添加多行,用法和 grid-template-columns一樣,grid-template-columns

使用 CSS 網格單位來更改列和行的大小

在 CSS 網格中,可以使用絕對定位和相對定位單位如pxem來確定行或列的大小。下面的單位也可以使用:

  • fr:設置列或行占剩余空間的一個比例
  • auto:設置列寬或行高自動等于它的內容的寬度或高度
  • %:將列或行調整為它的容器寬度或高度的百分比,

生成三列的網格,每列寬度分別為:1fr,100px,和 2fr。grid-template-columns: 1fr 100px 2fr;

使用 grid-column-gap 創建多列之間的間距

如果需要在列與列之間添加一些間隙,我們可以使用grid-column-gapgrid-column-gap: 10px;

使用 grid-row-gap 創建多行之間的間距,grid-row-gap: 5px;

使用 grid-gap 更快地添加間距

grid-gapgrid-row-gapgrid-column-gap的簡寫,它更方便使用。如果grid-gap有一個值,行與行之間和列與列之間將添加等于該值的間隙。但是,如果有兩個值,第一個值將作為行間隙的高度值,第二個值是列間隙的寬度值。
grid-gap: 10px 20px;在行之間添加10px的間隙,在列之間添加20px的間隙。

使用 grid-column 來控制剩余部分

網格的假想水平線和垂直線被稱為線(lines)。這些線在網格的左上角從 1 開始編號,垂直線向右、水平線向下累加計數。


3x3 網格的線條

你可以用grid-column屬性定義網格項開始和結束的位置,進而控制每個網格項占用的列數。
grid-column: 1 / 3;網格項從左側第一條線開始到第三條線結束,占用兩列。
grid-column: 2 / 4 ;網格項占用網格的第 2 列和第 3 列。

使用 grid-row 來控制剩余部分,來確定行開始和結束的水平線。
grid-row: 2 / 4;網格項占用網格的第 2 行和第 3 行。

使用 justify-self 水平對齊項目

在 CSS 網格中,每個網格項的內容分別位于被稱為單元格(cell)的框內。你可以使用網格項的justify-self屬性,設置其內容的位置在單元格內沿行軸對齊的方式。默認情況下,這個屬性的值是stretch,這將使內容占滿整個單元格的寬度。該 CSS 網格屬性也可以使用其他的值:

  • start:使內容在單元格左側對齊,
  • center:使內容在單元格居中對齊,
  • end:使內容在單元格右側對齊,

使用 align-self 垂直對齊項目
對網格項使用align-self屬性,設置網格項沿列軸對齊方式。對于該屬性,能使用可用于justify-self屬性的任一個值。

使用 justify-items 水平對齊所有項目

對于這個屬性你能使用justify-selfalign-self中的所有值,與之不同的是,它將使網格中所有的網格項按所設置的方式對齊。

使用 align-items 垂直對齊所有項目
對網格容器使用align-items屬性可以給網格中所有的網格項設置沿列軸對齊的方式。

將網格劃分為區域模板

你可以將網格中的一些網格單元格組合成一個區域(area),并為該區域指定一個自定義名稱。你可以通過給容器加上grid-template-areas來實現:

grid-template-areas: "header header header" "advert content content" "footer footer footer";
將頂部三個單元格合并成一個名為header的區域,將底部三個單元格合并為一個名為footer的區域,并在中間行生成兩個區域————advertcontent
注意:在代碼中,每個單詞代表一個網格單元格,每對引號代表一行。除了自定義標簽,你還能使用句點(.)來表示一個空單元格。

使用 grid-area 屬性將項目放置在網格區域中

在為網格容添加區域模板后,你可以通過添加你定義的名稱將網格項放入自定義區域。為此,你需要對網格項使用grid-area

.item1 { grid-area: header; }
類名為item1的網格項就被放到了header區域里。這種情況下,網格項將使用整個頂行,因為這一行被名為 header 區域。

使用 grid-area 創建區域模板

如果網格中沒有定義區域模板,你也可以像這樣為它添加一個模板:
item1 { grid-area: 1/1/2/4; }網格項將占用第 1 條和第 2 條水平線之間的行及第 1 條和第 4 條垂直線之間的列。

grid-area: 起始水平線 / 起始垂直線 / 末尾水平線 / 終止垂直線 ;網格項將占用第 1 條和第 2 條水平線之間的行及第 1 條和第 4 條垂直線之間的列。

使用 repeat 函數減少重復

當使用grid-template-columnsgrid-template-rows定義網格結構時,你需要為添加的每一行和每一列都輸入一個值。

使用repeat方法指定行或列的重復次數,后面加上逗號以及需要重復的值。添加 100 行網格的例子,使每行高度均為 50px:grid-template-rows: repeat(100, 50px);

你還可以用 repeat 方法重復多個值,并在定義網格結構時與其他值一起使用。
grid-template-columns: repeat(2, 1fr 50px) 20px;
相當于:grid-template-columns: 1fr 50px 1fr 50px 20px;

使用 minmax 函數限制項目大小

內置函數minmax也可以可用于設置grid-template-columnsgrid-template-rows的值。它的作用是在網格容器改變大小時限制網格項的大小。為此,你需要指定網格項允許的尺寸范圍。

grid-template-columns: 100px minmax(50px, 200px);添加兩列,第一列 100px 寬,第二列寬度最小值是 50px,最大值是 200px。

使用 auto-fill 創建彈性布局

重復方法帶有一個名為自動填充(auto-fill)的功能。它的功能是根據容器的大小,盡可能多地放入指定大小的行或列。你可以通過結合auto-fill和minmax來更靈活地布局。

repeat(auto-fill, minmax(60px, 1fr));列的寬度會隨容器大小改變,在可以插入一個 60px 寬的列之前,當前行的所有列會一直拉伸。
注意:如果容器無法使所有網格項放在同一行,余下的網格項將移至新的一行。

使用 auto-fit 創建彈性布局

auto-fit效果幾乎和auto-fill一樣。不同點僅在于,當容器的大小大于各網格項之和時,auto-fill將會持續地在一端放入空行或空列,這樣就會使所有網格項擠到另一邊;而auto-fit則不會在一端放入空行或空列,而是會將所有網格項拉伸至合適的大小。
注意:如果容器無法使所有網格項放在同一行,余下的網格項將移至新的一行。

使用媒體查詢創建響應式布局

通過使用媒體查詢重新排列網格區域,更改網格尺寸以及重新排列網格項位置,CSS 網格能輕松地使網站更具響應性。

@media (min-width: 400px){
    .container{
      grid-template-columns: 50% 50%;    //  分成兩列,每列占50%
      grid-template-rows: auto auto auto;  // 分成三行,每行占 33.33%
      grid-template-areas:
        "header header"
        "advert content"
        "footer footer";
    }

在網格中創建網格

將元素轉換為網格只會影響其子代元素。因此,在把某個子代元素設置為網格后,就會得到一個嵌套的網格。

例如,設置類為item3的元素的displaygrid-template-columns屬性,就會得到一個嵌套的網格。.item3 { display: grid; grid-template-columns: auto 1fr; }

項目實戰

Build a Tribute Page

a Tribute Page

Tim.jpg

Build a Survey Form

a Survey Form

Build a Product Landing Page

a Product Landing Page

just-we

Build a Technical Documentation Page

a Technical Documentation Page

Build a Personal Portfolio Webpage

a Personal Portfolio Webpage

acivii.png
form.png
js.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內容