css揭祕筆記——結構與佈局

自適應內部元素

咱們但願 width 能夠像 height 同樣, 能夠自動適應內容的寬度。假若有以下結構:css

<p>Lorem ipsum dolor ...</p>
<figure>
    <img src="./image/flower.jpg">
    <figcaption>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</figcaption>
</figure>
<p>Lorem ipsum dolor sit...</p>

咱們但願 figure 元素跟它所包含的圖片同樣寬(圖片尺寸不固定),並且水平居中。而咱們能想到的解決方案,如讓 figure 元素浮動,或者使 figure 的父元素 text-aligin:center、再對全部子元素都設置 text-align:left。這些方法都不是特別理想。css3

css3中爲 width 和 height 又增長了一些新的關鍵字,如min-content,它能使容器的寬度爲內部最大的不可斷行元素的寬度。app

figure{
    max-width: 300px; /*回退方案*/
    max-width: min-content; 
    margin: auto;
}
figure>img{
    max-width: inherit;
}

圖片描述

根據兄弟元素的數量來設置樣式

知識點:僞類選擇器函數

只有一個列表項::only-child 等效於 :first-child:last-child
一個正好有四個列表項的列表中的第一個列表項: :first-child:nth-last-child(4)佈局

ul>li{
    display: inline-block;
    padding: .5em 1em;
    border-radius: .5em;
    background: pink;
    color: white;
}
li:first-child:nth-last-child(4){
    background: deeppink;
}

圖片描述

它以後的全部兄弟元素: :first-child:nth-last-child(4)~liflex

li:first-child:nth-last-child(4) ~ li{
    background: deeppink;
}

圖片描述

所以,有且只有四個列表項的狀況就能夠表示爲:spa

li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li{
    background: deeppink;
}

圖片描述

若是列表項不是四個,則沒有被選中。
圖片描述code

根據兄弟元素的數量範圍來匹配元素

:nth-child()中的參數不只能夠是具體數字,也能夠是an+b這樣的表達式,其中 n 的範圍是0到正無窮。
例如:n+4表示選中從第 4 個開始的全部子元素。(注意: 寫成 4+n是不對的)
圖片描述orm

選中總數是4或是更多時選中全部列表項:圖片

li:first-child:nth-last-child(n+4),
li:first-child:nth-last-child(n+4) ~ li{
    background: deeppink;
}

圖片描述

參數是-n+4能夠選中開頭的4個元素

li:nth-child(-n+4){
    background: deeppink;
}

圖片描述

僅當列表中有4個或更少的列表項時,選中全部的列表項:

li:first-child:nth-last-child(-n+4),
li:first-child:nth-last-child(-n+4) ~ li{
    background: deeppink;
}

圖片描述

兩種技巧混合,能夠表示當列表項有2~6個時,選中全部列表項。

li:first-child:nth-last-child(n+2):nth-last-child(-n+6),
li:first-child:nth-last-child(n+2):nth-last-child(-n+6) ~ li{
    background: deeppink;
}

圖片描述

滿幅的背景,定寬的內容

要實現一個背景佔據整個視口,而內容固定寬度,居中佈局。如:
圖片描述

通常的解決方案是爲每一個區塊準備兩層元素,分別爲其設置樣式:

<footer>
    <div class="wrapper">
        Lorem ipsum dolor ...
    </div>
</footer>

footer{
    background: #333;
    color: white;
    border: 1px solid #333;/*這一行是爲了避免讓父元素和子元素的margin重疊(父元素margin爲0,子元素爲1em,重疊以長的爲準,即爲1em,背景默認background-clip爲border-box,margin下面就會沒有背景顏色。)*/
}
.wrapper{
    max-width: 900px;
    margin: 1em auto;
}

CSS3中增長了一個calc()函數,上面代碼中的 margin 的 auto 能夠替換爲 calc(50%-450px),這是一個長度值,所以能夠做爲父元素的 padding 值,代碼能夠改成:

footer{
        background: #333;
        color: white;
        /*border: 1px solid #333;*//*沒有margin重疊問題,也就不須要這一行*/
        padding: 1em calc(50% - 450px);
    }
    .wrapper{
        /*max-width: 900px;*/
        /*margin: 1em auto;*/
    }

所以,最終咱們再也不須要一個額外的元素:

footer{
    background: #333;
    color: white;
    padding: 1em; /*回退方案*/
    padding: 1em calc(50% - 450px); /*注意:calc中減號兩邊須有空格*/
}

垂直居中

水平居中很簡單:

/*針對行內元素*/
text-align: center; 
/*針對塊級元素*/
margin: auto;

以下結構:

<main>
    <h1>Am I centered yet?</h1>
    <p>Center me, please!</p>
</main>

基於絕對定位的解決方案

這個方案的前提是元素必須有固定的寬度和高度:

main{

position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -5em;
    margin-left: -10em;
    width: 20em;
    height: 10em;
}

若是通常的塊級元素,且父元素不是 <body>, 還須要對父元素進行相對定位。
圖片描述
藉助calc()函數,就能夠省掉兩行

main{
    position: absolute;
    top: calc(50% - 5em);
    left: calc(50% - 10em);
    width: 20em;
    height: 10em;
}

因爲translate()函數中的百分比值是相對於自身的寬高計算的,因此能夠解決固定寬高的問題:

main{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

基於視口單位的解決方案

若是使用 margin 的百分比值和 auto 關鍵字設置垂直水平居中,獲得的效果可能並非咱們想要的:

main{
    width: 20em;
    margin: 50% auto 0;
    transform: translateY(-50%);
}

圖片描述
那是由於 margin 的百分比值是以父元素的寬做爲基準的,即便對 margin-top 和 margin-bottom 也是這樣。
若是隻是想針對視口居中,可使用視口單位解決。
1vw 表示視口寬度的 1%
1vh 表示視口高度的 1%
1vmin 表示視口寬高較小的那個(1vw 或 1vh)
1vmax 表示視口寬高較大的那個(1vw 或 1vh)

main{
    width: 20em;
    margin: 50vh auto 0;
    transform: translateY(-50%);
}

基於Flexbox 的解決方案

body{
    display: flex;
}

main{
    margin: auto;
}

當咱們使用 Flexbox 時,margin:auto 不只在水平方向上將元素居中,垂直方向上也是如此。
也能夠這麼寫:

body{
    display: flex;
    justify-content: center;
    align-items: center;
}

使用這種方法,還能夠將匿名容器垂直居中,如沒有被標籤包裹的文本節點:

<main>Center me, please!</mian>

mian{
    display: flex;
    justify-content: center;
    align-items: center;
    width: 20em;
    height: 15em;
}

圖片描述

緊貼底部的頁腳

咱們會遇到這樣的問題,當頁面內容不夠長時,會出現頁腳不能緊貼在最底部,而是緊跟在內容的下方。以下圖:
圖片描述

固定高度的解決方案

若是頁腳和頁頭的高度固定,首先咱們計算出頁腳和頁頭的高度,分別是7em和2.5em。

mian{
    min-height: calc(100vh - 7em - 2.5em);
    box-sizing: border-box; /*避免內邊距或邊框搞亂高度的計算*/
}

就OK了。
或者用一個額外的元素包裹住 <header> 和 <main> 元素:

#wrapper {
    min-height: calc(100vh - 7em);
}

圖片描述

Flexbox解決方案

將 body 設置爲flex,main 設置爲可伸長。

body{
    display: flex;
    flex-flow: column;
    min-height: 100vh;
}
main{
    flex: 1;
}

搞定~

相關文章
相關標籤/搜索