css的結構與佈局

1.自適應內部元素

在css中,不給元素一個height值時,元素會自適應其內部的元素高度,有時咱們想讓元素的寬度也達到此效果,應用場景以下。css

以下當前的這種佈局,想要改爲最外層的div的寬度由當前的圖片撐開的效果,這時就要用到min-content這個屬性值。html

clipboard.png

css代碼以下:css3

div {
    /*只須要給最層的div的寬度值設置成min-content便可 */
    width: min-content;
}

最終效果:瀏覽器

clipboard.png

min-content將解析這個容器內部最大的不可斷行元素的寬度(即最寬的單詞,圖片或具備固定寬度的盒元素)app

張鑫旭有一篇文章對這個屬性作了詳細的講解,地址以下:
http://www.zhangxinxu.com/wor...wordpress

2.精確的控制表格的列寬

在使用表格佈局時,當表格的內容不肯定時,佈局很難預測,由於表格的列寬是根據它的內容進行計算的,即便顯示的設置了width,也不會生效,仍是會根據它的內容生成寬度。會根據加載的內容不停的重繪,直到加載完。
平時生成的表格以下:佈局

clipboard.png

爲了讓設置的寬度生效,而且能讓過多的文字省略號顯示,解決辦法就是使用table-layout: fixed這個樣式
代碼以下:flex

table {
    table-layout: fixed;
    width: 100%; /*必須指定一個width,不然不生效*/
}

最終的效果以下:this

clipboard.png

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

在一些應用場景中,咱們可能須要根據元素的數量來設置樣式,好比說列表愈來愈長的時候,咱們可能須要調整間隔或者大小,來減小長度,提高用戶的體驗
例如當列表項中共有4項的時候,選中全部列表,能夠經過使用scss這種預處理器,編寫mixin
代碼以下:flexbox

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

/*調用方法*/
li {
/*當列表正好包含四項時 命中全部列表項*/
/*定義樣式*/
  @include n-items(4) {
    width: 40px;
    height: 100px;
    background: red;
    float: left;
    margin: 10px;
  }
}

效果以下:

clipboard.png

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

應該場景同上,解決辦法也是編寫mixin
例如,當列表的總數是4或者更多時,選中全部列表項
代碼以下:

/*定義mixin*/
@mixin n-items($n) {
  /*當列表的總數是4或者更多時,選中全部列表項*/
  &:first-child:nth-last-child(#{$n + 4}),
  &:first-child:nth-last-child(#{$n + 4}) ~ & {
    @content;
  }
}

// 改寫成 -n + 4 表示列表中有4個或者小於4時,選中全部

// 同理,如2 ~ 6時,設置 n + 2 ~ -n + 6
@mixin n-items($n) {
  &:first-child:nth-last-child(#{$n + 2}):nth-last-child(#{$ -n + 6}),
  &:first-child:nth-last-child(#{$n + 2}):nth-last-child(#{$ -n + 6}) ~ & {
    @content;
  }
}

5.滿幅的背景,定寬的內容

頁面上有不少佈局是那種內容是固定寬的,背景是佔滿整個視口的寬的,好比下面這種佈局:

clipboard.png
實現方式有不少種,通常咱們實現的代碼結構都是這種的:

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

/* css樣式*/
footer {
    background: "#333";
}
.wrapper {
    max-width: 900px;
    margin: 1em auto;
}

其中margin: 1em auto;就是爲了讓內容div居中,咱們有一種更好的方式,只用一層DOM結構實現上面的佈局,就是使用calc這個屬性。
實現代碼以下:

<footer>
  /* 內容 */
</footer>

/* css樣式*/
footer {
    background: "#333";
    /* 當瀏覽器不支持calc的時候回退一下*/
    padding: 1em;
    padding: 1em calc(50% - 450px);
}

原理:百分比是按照視口的寬度來解析的,因此即便裏面的內容不設置寬,也會給裏面的內容留出 450*2的空間,達到了以前設置 max-width: 900px;的效果。

6.垂直居中

在css中水平居中比較簡單,對於行級元素,對它的父元素使用text-align: center;對於塊級元素,就對它自身使用margin: auto;對於垂直居中比較難處理,目前的解決方法有:

1.基於絕對定位的方法

(1) 當元素是定寬高的時候:

div {
    width: 200px;
    height: 100px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -50px;
    margin-left: -100px;
}

經過calc代碼能夠簡化成下面這樣:

div {
    width: 200px;
    height: 100px;
    position: absolute;
    top: calc(50% - 50px);
    left: calc(50% - 100px);
}

(2) 對於那些寬高不定的元素,實現方法以下:

div {
    position: absolute;
    top: 50%;
    left: 50%;
    transfrom: translate(-50%, -50%);
}

以上方案也有一個弊端就是必須是絕對定位的元素。

2.基於視口單位的方法

css3中定義了一些視口相關的單位:

  • vw 是與視口寬度相關的。1vw 實際上表示視口寬度的1%,而不是100%。
    „

  • 一樣,1vh表示視口高度的 1%

  • 當視口寬度小於高度時,1vmin等於 1vw,不然等於 1vh。

  • 當視口寬度大於高度時,1vmax等於 1vw,不然等於 1vh。
    因此咱們的垂直居中能夠這樣實現:

div {
    width: 200px;
    padding: 2px 4px;
    margin: 50vh auto 0;
    transform: translateY(-50%);
}
**注:這裏不使用50%,而是視口單位的緣由是,margin的百分比是以父元素的寬度做爲解析基準的,不管是margin-top or margin-left**

這種的方法是有侷限性的,只能用在視口中居中的場景。

3.基於flex的方法

這種應該算是最佳的解決辦法:
實現方法:

body {
    display: flex;
}

div {
    margin: auto;
}

當使用flex佈局時,使用margin: auto; 在水平和垂直方向都會居中。在不指定width的狀況下,width: max-content;

flexbox還有一個公共就是能夠將匿名的容器(就是那些沒有被標籤包住的文本節點)垂直居中:

<div>text</div>

div {
    width: 100px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center; 
}

7.緊貼底部的頁腳

具備塊級樣式的頁腳,當頁面內容足夠長的時候,頁腳會緊貼視口的底部;可是當頁面內容的長度 < 視口height - 頁腳height的時候,頁腳就會緊貼在內容的下面。通常的設計是給頁腳一個固定的height,這種顯然不健壯,在css3中有更好的解決方案。

(1) 最原始的固定高度的解決方案

html結構以下:

<header>
    <h1>hello</h1>
</header>
<main>
    <p>this is ...</p>
</main>
<footer>
    <p>Made in ...</p>
    <p>Made in ...</p>
</footer>

header {
    height: 10px
}
footer p {
    line-height: 1.5px;
    padding: 1px;
    margin: 1px;
}

假設當前的頁腳文字永遠不會折行,能夠計算當前的頁腳的高度是:2 * 行高 + 3 * 段落垂直外邊距 + 頁腳垂直內邊距 = 2 * 1.5px + 3 * 1px + 1px = 7px;

main {
    min-height: calc(100vh - 7px - 10px);
    /* 避免內邊距或外邊距對高度記得算影響 */
    border-sizing: border-box;
}

當header和main放在一個div裏時,css樣式能夠直接寫成 div{min-height: calc(100vh - 7px)};
這種方法的侷限性是不容許文字折行,而且佈局是這種簡單的佈局,而且每當頁腳的尺寸變化時,都須要跟着調整min-height的值。

(2)基於flex的解決方案

body {
    display: flex;
    flex-flow: columm;
    min-height: 100vh; /* 至少會佔據整個視口的高度 */
}

main {
    flex: 1;
}
相關文章
相關標籤/搜索