1. 程式人生 > >CSS 佈局解決方案之延伸篇

CSS 佈局解決方案之延伸篇

然後自己做一點延伸,再把程式碼敲出來,加深下印象。

水平居中:inline-block + text-align

CSS:

 <style>
        .child1 {
            display: inline-block;
            background: khaki;

        }

        .child2 {
            display: inline-block;
            background: hotpink;
        }

        .parent {
            text-align
: center
; background: lightgreen
}
</style>

html:

<div class="parent">
        <div class="child1">demo</div>
        <div class="child2">demo2</div>
    </div>

瀏覽器顯示:

這裡寫圖片描述

優點:相容性好。缺點:.child1,2裡面的字也會居中,這時候需要用text-align:left 來放到左邊,請看例子。
看,如果給.child1,2

一個寬度,連text都居中了:
這裡寫圖片描述

我們再延伸一下,如果.child1裡面再有一個.grandchild的話,如果它是inline-block的話,那麼它也會居中,也就是說只要你父元素設定了text-align:center,裡面所有的子子孫孫節點都會繼承這個居中。
請看:
CSS:

<style>
        .child1 {
            display: inline-block;
            background: khaki;
            width:20%

        }

        .child2 {
            display
: inline-block
; background: hotpink; width:20%
} .grandchild { display: inline-block; background:mediumspringgreen; width:50% } .parent { text-align: center; background: lightgreen }
</style>

html:

  <div class="parent">
        <div class="child1">
            <div class="grandchild">demo</div>
        </div>
        <div class="child2">demo2</div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

如果不想文字居中的話那麼給.child, 或者是 .grandchild設定text-align:left即可

這裡刪掉了.grandchild, .child1中直接新增文字demo1這樣看得更加清晰點:
這裡寫圖片描述

水平居中:margin + table

這種方法其實就是css把html裡面的table標籤借過來用,裡面需要包含table, table-rowtable-header-group, table-cell等。

下面是個簡單的例子:
CSS:

 <style>
        .child1 {
            display: table-cell;
            background: rebeccapurple;
            width: 20%;

        }

        .child2 {
            display: table-cell;
            background: darkgoldenrod;
            width: 20%;

        }

        .child3 {
            display: table-cell;
            background: cyan;
            width: 20%; 
        }

        .parent {
            display: table;
            margin: 0 auto;
            background: blue

        }

        .brother {
            display: table-row;
            text-align: center;
        }

    </style>

html:

<div class="parent">
        <div class='brother'>
            <div class="child1">demo1</div>
            <div class="child2">demo2</div>
            <div class="child3">demo3</div>
        </div>

    </div>

瀏覽器顯示:

這裡寫圖片描述

優點:相容性還行。缺點:需要三層才能佈局,而且.parent,和.brother的寬度取決於table-cell的寬度,所以設定不了background-color

水平居中:absolute + transform

CSS:

<style>
        .child1 {
            position: absolute;
            left: 50%;
            background: lightcoral;
            transform: translateX(-50%);
        }

        .parent {
            position: relative;
        }
    </style>

html:

<div class="parent">
        <div class="child1">demo1</div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

優點:因為設定了absolute所以子元素位置固定,不會影響到兄弟元素。 在定位方面,有的時候我們需要以元素的中心點來定位而不是元素的左側,這是個很好的方法。 確定:因為用到了CSS3的transform,所以有相容性問題。 而且不能用此方法設定多元素的居中排列。

看下面一個例子,就是進行元素的等分排列。
如果有N個元素那麼
left = (100%/N*2) + (100%/N) *n ( n = 0, 1, 2, … N-1);

請看CSS:

 <style>
        .child1 {
            position: absolute;
            left: 10%;
            background: lightcoral;
            transform: translateX(-50%);
        }

         .child2 {
            position: absolute;
            left: 30%;
            background: lightcoral;
            transform: translateX(-50%);
        }

         .child3 {
            position: absolute;
            left: 50%;
            background: lightcoral;
            transform: translateX(-50%);
        }

         .child4 {
            position: absolute;
            left: 70%;
            background: lightcoral;
            transform: translateX(-50%);
        }

         .child5 {
            position: absolute;
            left: 90%;
            background: lightcoral;
            transform: translateX(-50%);
        }

        .parent {
            position: relative;
        }
    </style>

html:

<div class="parent">
        <div class="child1">demo1</div>
        <div class="child2">demo2</div>
        <div class="child3">demo3</div>
        <div class="child4">demo4</div>
        <div class="child5">demo5</div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

水平居中:margin + …

這裡有幾種用margin: 0 auto來居中的方法:

  1. 設定寬度
<style>
        .child1 {
           width: 10%;
           margin: 0 auto;
           text-align: center;
        }
    </style>
<div class="child1">demo1</div>

只要你設定了寬度就可以用margin: 0 auto來居中,不需要父元素。

2 . 用 display:table

<style>
        .child1 {
            display: table;
            margin: 0 auto;
            background:lightcoral;
        }
    </style>
<div class="child1">demo1</div>

以上兩種方法只要設定居中元素本身就好。

3 . 用 display:flex

 <style>
        .child1 {
            margin: 0 auto;
            background:lightcoral;
        }

        .parent {
            display:flex;
        }
    </style>
<div class="parent">
        <div class="child1">demo1</div>
    </div>

這種方法需要在父級元素設定display:flex, 因為用到了 CSS3的flex所以有可能有相容性問題。

想延伸一下,用 margin: 0 auto, 同樣可以實現多個子元素的垂直居中

  <style>
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            height: 100%;
            font-size: 16px
        }
    </style>
    <style>
        .child1,
        .child2,
        .child3 {
            width: 10%;
            margin: 0 auto;
            background: lightcoral;
        }

        .parent {
            position: relative;
            width: 30%;
            height: 3.4rem;
            background: lightgreen
        }
    </style>
 <div class="parent">
        <div class="child1">demo1</div>
        <div class="child2">demo2</div>
        <div class="child3">demo2</div>
    </div>

瀏覽器顯示:

這裡寫圖片描述

這裡父元素的height用了rem,好處是可以很好的貼合3個子元素的高度。

水平居中:flex+justify-content

CSS:

  <style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }
        .child1,
        .child2,
        .child3 {
            background: lightcoral;
            margin: 1rem
        }

        .parent {
           display:flex;
           justify-content: center;
           height:3rem;
           background: lightgreen
        }
    </style>

html:

<div class="parent">
        <div class="child1">demo1</div>
        <div class="child2">demo2</div>
        <div class="child3">demo3</div>
    </div>

瀏覽器顯示:

這裡寫圖片描述

這裡值得注意的是, 如果你修改父元素的高度,子元素的高度也會一起變化,以滿足子元素在父元素內總是居中:
如果改動父元素的height: 5rem

得到如下顯示結果:
這裡寫圖片描述

垂直居中:table-cell+vertical-align

css:

  <style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }

        .child1, .child2, .child3{
            background: lightcoral;
        }

        .parent {
            display: table-cell;
            vertical-align: middle;
            background: lightgreen;
            height:10rem;
        }
    </style>

html:

 <div class="parent">
       <div class="child1">demo1</div>
       <div class="child2">demo2</div>
       <div class="child3">demo2</div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

相容性很好,沒什麼缺點。

垂直居中:table-cell+vertical-align

CSS:

  <style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }

        .child1{
            position: absolute;
            background: lightcoral;
            top:50%;
            transform: translateY(-50%)
        }

        .parent {
            position: relative;
            width:20%;
            background: lightgreen;
            height:10rem;
        }
    </style>

html:

<div class="parent">
      <div class="child1">demo1</div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

因為用到了css3所以可能有相容性問題,對於多列的垂直居中,參考水平居中的absolute + transform 公式就好。

垂直居中:flex + flex-direction + justify-content

CSS:

<style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }

        .child1{
            background: lightcoral;
            width:50%
        }

        .parent {
            display: flex;
            flex-direction: column;
            justify-content: center;
            background: lightgreen;
            width:20%;
            height:10rem;
        }
    </style>

html:

<div class="parent">
      <div class="child1">demo1</div>
      <div class="child1">demo2</div>
      <div class="child1">demo3</div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

優點是隻需要設定父元素,缺點是CSS3相容性問題。

垂直居中:flex + align+items

CSS:

.parent {
    position:flex;
    align-items:center;
    background: lightgreen;
    width:20%;
    height:10rem;
}

html:

<div class="parent">
      <div class="child1">demo1</div>
</div>

優點是隻需要設定父元素,缺點是CSS3相容性問題,以及只能設定一個子元素。

水平垂直居中:absolute+transform

CSS:

    <style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }

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

        .parent {
            position: relative;
            background: lightgreen;
            width:20%;
            height:10rem;
        }
    </style>

html:

<div class="parent">
      <div class="child1">demo1</div>
    </div>

瀏覽器顯示:

這裡寫圖片描述

優缺點相信不用贅述了。 這種方法只能設一個子元素。

水平垂直居中:(inline-block+text-align)+(table-cell+vertical-align)

這其實很好理解 inline-block+text-align 是水平居中用的,able-cell+vertical-align 是垂直居中用的。

對於單個元素的演示過於簡單,就不贅述了,下面展示下多個元素的水平垂直居中:

CSS:

  <style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }

        .child1 {
            display: inline-block;
            background: lightcoral;
        }

        .parent {
            display: table-cell;
            vertical-align: middle;
            background: lightgreen;
            text-align: center;
            width: 50rem;
            height: 10rem;
        }
    </style>

html:

<div class="parent">
        <div class="row">
            <div class="child1">demo1</div>
            <div class="child1">demo2</div>
            <div class="child1">demo3</div>
        </div>
        <div class="row">
            <div class="child1">demo1</div>
            <div class="child1">demo2</div>
            <div class="child1">demo3</div>
        </div>
        <div class="row">
            <div class="child1">demo1</div>
            <div class="child1">demo2</div>
            <div class="child1">demo3</div>
        </div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

這裡有幾點需要注意的:
1. .row這個元素只是起到換行的作用。
2. 當.parent 設定成 display:table-cell的時候,width進行百分比設定是沒有用的。 所以用rem, 當然直接設px也是可以的。
3. 可以看到同一行的.child1中間是有空白的,可以通過對.child1設定margin:0 -0.11rem 來清除,具體數值是調整出來的。

調整以後效果如下:
這裡寫圖片描述

優點是相容性好,缺點就是需要設定負的margin值來抵消子元素之間的空白部分。

水平垂直居中:flex+flex-direction+justify-content+align-items

如果我們只需要單個元素水平垂直居中的話,下面這樣就可以了:

<style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }
        .parent {
            display: flex;
            justify-content: center;
            align-items: center;
            background: lightgreen;
            width: 50%;
            height: 10rem;
        }
    </style>

這個很簡單,參照之前flex的水平居中和垂直居中就好了。
假如我們有多個子元素進行二維排列呢。請看下面:
CSS:

  <style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }

        .child1 {
            background: lightcoral;
        }

        .row {
            display: flex;
        }
        .parent {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            background: lightgreen;
            width: 50%;
            height: 10rem;
        }
    </style>

html:

 <div class="parent">
        <div class="row">
            <div class="child1">demo1</div>
            <div class="child1">demo2</div>
            <div class="child1">demo3</div>
        </div>
        <div class="row">
            <div class="child1">demo1</div>
            <div class="child1">demo2</div>
            <div class="child1">demo3</div>
        </div>
        <div class="row">
            <div class="child1">demo1</div>
            <div class="child1">demo2</div>
            <div class="child1">demo3</div>
        </div>
    </div>

瀏覽器顯示:
這裡寫圖片描述

我們看到,和之前的佈局比起來有很多優點。

  1. 子元素緊緊挨在一起,不需要設定負的margin值去抵消空白部分。
  2. 父元素的width可以用百分比設定了。

這裡父元素首先設定了flex-direction:column, 保證 .row子元素是按照豎列排列。 同時兩個center.row水平垂直居中。

如果不對 .row子元素設定 display: flex的話,那麼所有child1元素都都將垂直排列,因為繼承了父元素設的排列方式。設定以後,則child1預設是水平排列。
這樣使得所有child1.row的分行中垂直水平居中。

多列布局之定寬+自適應:float + overflow

CSS:

    <style>
        html,
        body {
            height: 100%;
            font-size: 16px
        }
        .left{
            float:left;
            width: 20%;
            margin-right:5%;
            background: lightblue;
        }
        .right {
            overflow: hidden;
            background:lightcoral;
        }
        .parent {
            background: lightcyan;
        }
    </style>

html:

<div class="parent">
      <div class="left">
          <p>left</p>
      </div>
      <div class="right">
          <p>right</p>
          <p>right</p>
      </div>
  </div>

瀏覽器顯示:
這裡寫圖片描述

如果你不對.right 設定 overflow:hidden

結果顯示出來是這樣:

這裡寫圖片描述

為什麼用了float就要用overflow:hidden

因為這牽涉到BFC 概念, 下面的這篇文章我覺得是說得很簡潔明瞭的。

多列布局之定寬+自適應:float + margin

CSS:

   <style>
        html,
        body {
            height: 100%;