CSS結構與佈局


title: 結構與佈局
date: 2016-12-11
tags: CSS Secrets瀏覽器


0x00 min-content 寬度自適應

CSS3 新增寬度屬性值 width:min-content 能夠將容器的寬度值設置爲容器內最大的不可斷行的寬度(最寬的單詞,圖片,或者具備固定寬度的盒元素)app

figure{
    width:min-content;
    margin: auto;    
}

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

咱們知道僞元素選擇器 :only-child,其實,它能夠等效於:first-child:last-child,便是第一項的同時也是最後一項,因此從邏輯上來說它是惟一的。而:last-child 也是:nth-last-child(1)的快捷寫法。函數

那麼接下來思考一個問題,li:first-chidl:nth-last-child(4) 表明什麼?結果是 _一個正好有四個列表項的列表中的第一項_,ok,再結合兄弟選擇符~來命中它以後的每一項,就能夠達到這樣一個目標在正好包含四個列表項的時候,命中它的每一項佈局

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

結合 SASS,將其簡化複用flex

/*定義混合器*/
@mixin n-items($n){
    &:first-child:nth-last-child(#{$n}),
    &:first-child:nth-last-child(#{$n}) ~ &{
        @content;
    }
}

/*調用*/
li {
    @include n-items(4){
        /*屬性與值寫在這裏*/
        background: red;
    }
}

:nth-child()

nth-child()的強大之處在於以接受an+b形式的表達式,那麼天然即可以使用其變種 nth-child(n+4) 這種形式,它將會選擇除了第1,2,3個子元素以外的全部子元素。spa

ul li:first-child:nth-last-child(n+4),
ul li:first-child:nth-last-child(n+4) ~ li{
    /*當列表中至少包含四項時,命中包括該項以後的全部列表項*/
}

固然,不止於此,:nth-child()的玩法徹底取決於你的腦洞。設計


0x02 calc

有時,若須要去實現一個 背景寬度滿屏,內容寬度固定 的佈局,也許咱們會去這樣設計 DOM 結構code

<footer>
    <div class="wrapper">        
    </div>
</footer>

CSS 樣式:orm

footer{
    background: #333;
}

.wrapper{
    max-width: 900px;
    margin: 1em auto;
    height: 200px;
}

使用 calc() 方法之後,就沒必要如此麻煩了,咱們只需三行代碼便可實現:圖片

footer{
  background:#333;
  padding:1em calc(50% - 50px);
 }

使用了 clac() 即可以在 CSS 中進行簡單的算術運行,這使得 DOM 結構變得很是簡潔,沒有任何的冗餘,固然,缺點也是顯而易見的,這裏的代碼只會在 footer 元素的父級超過 900 px 纔會看出效果。

calc() 中的百分比是基於其父級進行解析的

但,咱們初次瞭解到了CSS3 中cacl() 這個魔法技巧。


0x03 垂直居中


基於絕對定位的解決方案

CSS 中有一個很常見的現象,真正的解決方法每每來自於咱們最意想不到的地方。好比,能夠結合 positon:absolutetransform:translate() 屬性來實現垂直居中

由於 translate() 變形函數中的百分比是根據這個元素自身的寬度和高度爲基準進行換算的,如此一來,即可以完全解除對固定尺寸的依賴。

示例:DOM 結構

<body>
    <div class="main">
        <h1>Am i center?</h1>
        <p>Center me ,please!</p>
    </div>
</body>

CSS代碼:

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

position-transform垂直居中

不過,該方法也是存在不足的:
1.在某些瀏覽器中,可能會致使模糊顯示,由於元素有可能被放置在半個像素上。
2.在並不適合使用絕對定位的狀況下。並且絕對定位對整個佈局的影響也太過強烈。


基於 FlexBox 的解決方案

毫無疑問,這算是目前最佳的解決方案了。而且,現代瀏覽器對 FlexBox 的支持已經至關高了。

對基於 FlexBox 容器的 items 使用 margin:auto 不只能夠在水平方向方居中,垂直方向上亦是如此,即便不指定任何寬度,由於這個元素分配到的寬度等於 max-content.

FlexBox垂直居中,完美!

FlexBox 的另外一個好處是能夠文本也進行垂直居中, 只需對使用display:flex 的元素添加 align-items:centerjustify-content:center

.main{
    background: deeppink;
    width: 50%;
    height: 50%;
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: center;
}

FlexBox文本居中


0x04 緊貼底部的頁腳

有時,咱們指望頁頭和頁腳的高度由其內部因素來決定,而內容區塊的高度能夠自動收縮並佔滿全部可用的空間。一樣,利用 FlexBox 這很容易。

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

    header{
        /*heaer style*/
    }
    
    .main{
        flex:1;
    }

    footer{
        /*footer style*/
    }
}

咱們給了 body 一個 min-height:100vh 的高度這樣它至少會佔據整個視口的高度,而後賦予 main 一個大於 0 的 flex 值就能夠了。

問題:若是頁腳是固定在屏幕的底部的呢?如何解決當頁面滾動到最後的時候保證頁腳不會覆蓋內容區?

對於這個問題,純屬我的想法,能夠在 footer 以後添加一個 div#_footer

此時的 DOM 結構以下:

<body>
    <header><header>
    <div class="main"></div>
    <footer></footer>
    <div id="_footer"></div>
</body>

而對於 div#_footer 而言,不須要爲其中添加任何的內容和樣式,只須要它的高度等於 footer 的高度就能夠了,而對於這點,使用 jQuery 就能夠輕鬆搞定。

$('#_footer').height($('footer').height())

如此,對於響應佈局也能夠不用擔憂了,雖然有點點hack,但也算完美的解決了,Bingo!

相關文章
相關標籤/搜索