關於佈局以及rem的小結

sunshinezhong發表於2018-02-22

rem佈局

動態計算html的font-size,核心是切換不同移動裝置通過js獲取裝置寬度,然後按比例計算html的font-size的值,動態變化。

var d = document.documentElement;//獲取html元素
var cw = d.clientWidth || 750;
d.style.fontSize = (20 * (cw / 375)) > 40 ? 40 + 'px' : (20 * (cw / 375)) + 'px';
複製程式碼
  1. 設計稿橫向解析度為375(iphone6),計劃20px為1rem;
  2. 佈局的時候,各元素的css尺寸= 20 * (裝置寬度/設計稿豎向解析度)。 完整程式碼:
window.addEventListener(('orientationchange' in window ? 'orientationchange' : 'resize'), 
                        (function() {//判斷是螢幕旋轉還是resize
    function c() {
        var d = document.documentElement;//獲取html元素
        var cw = d.clientWidth || 750;
        d.style.fontSize = (20 * (cw / 375)) > 40 ? 40 + 'px' : (20 * (cw / 375)) + 'px';
    }
    c();
    return c;
})(), false);
複製程式碼

元素居中

水平居中

  • 通過margin: 0 auto; text-align: center實現CSS水平居中。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 300px;
            height: 300px;
        }
        #two{
            background: blanchedalmond;
            width: 150px;
            height: 75px;
            margin: 0 auto;
            text-align: center;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="two"></div>
</div>
複製程式碼

這裡需要注意下父元素必須有指定的width和height。

  • 通過display:flex實現CSS水平居中。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 300px;
            height: 300px;
            display: flex;
            flex-direction: column;
        }
        #two{
            background: blanchedalmond;
            width: 150px;
            height: 75px;
            align-self: center;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="two"></div>
</div>
複製程式碼

這裡需要注意下父元素必須有指定的width和height。父元素display:flex;子元素align-sekf:center;

  • 通過display:table-cell和margin-left實現CSS水平居中。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 300px;
            height: 300px;
            display: table-cell;
        }
        #two{
            background: blanchedalmond;
            width: 150px;
            height: 75px;
            margin-left: 75px;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="two"></div>
</div>
複製程式碼

對於父元素和子元素的寬度都確定的情況,適合通過display:table-cell和margin-left實現CSS水平居中。 使用時,父元素display:table-cell,子元素給剩餘寬度一半的margin-left。

  • 通過position:absolute實現CSS水平居中,通過給父元素加絕對定位。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 300px;
            height: 300px;
            position: absolute;
        }
        #two{
            background: blanchedalmond;
            width: 150px;
            height: 75px;
            margin-left: 75px;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="two"></div>
</div>
複製程式碼

對於父元素和子元素的寬度都確定的情況,使用時,父元素position:absolute,子元素給剩餘寬度一半的margin-left。

  • 通過width:fit-content實現CSS水平居中
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 600px;
            height: 300px;
        }
        #two{
            background: blanchedalmond;
            width:fit-content;
            height: 75px;
            margin: 0 auto;
            text-align: center;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="two" style="color: white">我是子元素</div>
</div>
複製程式碼

這種方法可以確保子元素寬度不確定的情況下,也能實現CSS水平居中。需要注意的是,需要配合“margin: 0 auto; text-align: center”使用。

  • 通過display:inline-block和text-align:center實現CSS水平居中。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 600px;
            height: 300px;
            display: inline-block;
        }
        #two{
            background: blanchedalmond;
            width:150px;
            height: 75px;
            margin: 0 auto;
            text-align: center;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="two" style="color: white"></div>
</div>
複製程式碼

display:inline-block能改父元素內的子元素的表達樣式,同樣需要配合“margin: 0 auto; text-align: center”使用。

  • 通過position:relative、float:left和margin-left實現CSS水平居中。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 600px;
            height: 300px;
            position: relative;
        }
        #two{
            background: blanchedalmond;
            width:300px;
            height: 150px;
            float: left;
            margin-left: 150px;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="two" style="color: white"></div>
</div>
複製程式碼

需要注意的是父元素要有固定的width和height。

  • 通過隱藏節點+float的方法實現CSS水平居中。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #one{
            background:seagreen;
            width: 600px;
            height: 300px;
        }
        #hide{
            width: 150px;
            height: 150px;
            float: left;
        }
        #two{
            background: blanchedalmond;
            width:300px;
            height: 150px;
            float: left;
        }
    </style>
</head>
<body>
<div id="one">
    <div id="hide"></div>
    <div id="two"></div>
</div>
複製程式碼

我們可以通過增加一個隱藏節點,然後使其float:left,這樣子元素就會被隱藏節點推著水平居中。 這種增加隱藏節點方法也適用於CSS垂直居中,原理一樣,但是不用float。

垂直居中

  • 把一些 div 的顯示方式設定為表格,因此我們可以使用表格的 vertical-align property 屬性。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #wrapper{
            display: table;
        }
        #cell{
            display: table-cell;
            vertical-align:middle;
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <div id="cell">
            <div class="content">Content goes here</div>
        </div>
    </div>
複製程式碼

這裡關於vertical-align囉嗦兩句:vertical-align屬性只對擁有valign特性的html元素起作用,例如表格元素中的td,th等等,而像div,span這樣的元素是不行的。valign屬性規定單元格中內容的垂直排列方式,語法:td valign="value"

  • 這種方法,在 content 元素外插入一個 div。設定此 div height:50%; margin-bottom:-contentheight;。 content 清除浮動,並顯示在中間。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #content {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
            height: 240px;
            width: 70%;
        }
    </style>
</head>
<body>
<div id="floater">
    <div id="content">Content here</div>
</div>
複製程式碼

需要注意的是 IE(IE8 beta)中無效 無足夠空間時,content 被截斷,但是不會有滾動條出現

  • 這個方法只能將單行文字置中。只需要簡單地把 line-height 設定為那個物件的 height 值就可以使文字居中了。
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #content {
            height: 100px;
            line-height: 100px;
        }
    </style>
</head>
<body>
<div id="content"> Content here</div>
複製程式碼

需要注意的是隻對文字有效,塊級元素無效。多行時,斷詞比較糟糕。

  • 使用絕對定位和負外邊距對塊級元素進行垂直居中
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
            position: relative;
        }
        #child {
            width: 150px;
            height: 100px;
            background: orange;
            position: absolute;
            top: 50%;
            margin: -50px 0 0 0;
            line-height: 100px;
        }
    </style>
</head>
<body>
<div id="box">
    <div id="child">我是測試DIV</div>
</div>
複製程式碼

這個方法相容性不錯,但是有一個小缺點:必須提前知道被居中塊級元素的尺寸,否則無法準確實現垂直居中。

  • 使用絕對定位和transform
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
            position: relative;
        }
        #child {
            background: #93BC49;
            position: absolute;
            top: 50%;
            transform: translate(0, -50%);
        }
    </style>
</head>
<body>
<div id="box">
    <div id="child">
        我是一串很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長的文字
    </div>
</div>
複製程式碼
  • 另外一種使用絕對定位和負外邊距進行垂直居中的方式
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
            position: relative;
        }
        #child {
            width: 50%;
            height: 30%;
            background: pink;
            position: absolute;
            top: 50%;
            margin: -15% 0 0 0;
        }
    </style>
</head>
<body>
<div id="box">
    <div id="child">我也是個測試DIV</div>
</div>
複製程式碼

margin的取值也可以是百分比,這時這個值規定了該元素基於父元素尺寸的百分比,可以根據實際的使用場景來決定是用具體的數值還是用百分比。

  • 絕對定位結合margin: auto
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
            position: relative;
        }
        #child {
            width: 200px;
            height: 100px;
            background: #A1CCFE;
            position: absolute;
            top: 0;
            bottom: 0;
            margin: auto;
            line-height: 100px;
        }
    </style>
</head>
<body>
<div id="box">
    <div id="child">呆呆今天退役了(。﹏。)</div>
</div>
複製程式碼

把要垂直居中的元素相對於父元素絕對定位,top和bottom設為相等的值,我這裡設成了0,當然你也可以設為99999px或者-99999px無論什麼,只要兩者相等就行,這一步做完之後再將要居中元素的margin設為auto,這樣便可以實現垂直居中了。被居中元素的寬高也可以不設定,但不設定的話就必須是圖片這種自身就包含尺寸的元素,否則無法實現。

  • 使用padding實現子元素的垂直居中

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            background: #ddd;
            padding: 100px 0;
        }
        #child {
            width: 200px;
            height: 100px;
            background: #F7A750;
            line-height: 50px;
        }
    </style>
</head>
<body>
<div id="box">
    <div id="child">今天西安的霾嚴重的嚇人,剛看了一眼PM2.5是422</div>
</div>
複製程式碼

這種實現方式非常簡單,就是給父元素設定相等的上下內邊距,則子元素自然是垂直居中的,當然這時候父元素是不能設定高度的,要讓它自動被填充起來,除非設定了一個正好等於上內邊距+子元素高度+下內邊距的值,否則無法精確的垂直居中。

  • 設定第三方基準
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
        }
        #base {
            height: 50%;
            background: #AF9BD3;
        }
        #child {
            height: 100px;
            background: rgba(131, 224, 245, 0.6);
            line-height: 50px;
            margin-top: -50px;
        }
    </style>
</head>
<body>
<div id="box">
    <div id="base"></div>
    <div id="child">今天寫了第一篇部落格,希望可以堅持寫下去!</div>
</div>
複製程式碼

首先設定一個高度等於父元素高度一半的第三方基準元素,那麼此時該基準元素的底邊線自然就是父元素縱向上的中分線,做完這些之後再給要垂直居中的元素設定一個margin-top,值的大小是它自身高度的一半取負,則實現垂直居中。

  • 使用flex佈局
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
            display: flex;
            align-items: center;
        }
    </style>
</head>
<body>
<div id="box">
    <p>霧霾天氣,太久沒有打球了</p>
</div>
複製程式碼
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
            display: flex;
            align-items: center;
        }
        #child {
            width: 300px;
            height: 100px;
            background: #8194AA;
            line-height: 100px;
        }
    </style>
</head>
<body>
<div id="box">
    <div id="child">
        程式設計師怎麼才能保護好眼睛?
    </div>
</div>
複製程式碼
  • 第二種使用彈性佈局的方式
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background: #ddd;
            display: flex;
            flex-direction: column;
            justify-content: center;
        }
        #child {
            width: 300px;
            height: 100px;
            background: #08BC67;
            line-height: 100px;
        }
    </style>
</head>
<body>
<div id="box">
    <div id="child">
        答案當然是多用綠色的背景哈哈
    </div>
</div>
複製程式碼
  • 使用 line-height 和 vertical-align 對圖片進行垂直居中
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #box{
            width: 300px;
            height: 300px;
            background: #ddd;
            line-height: 300px;
        }
        #box img {
            vertical-align: middle;
        }
    </style>
</head>
<body>
<div id="box">
    <img src="duncan.jpeg">
</div>
複製程式碼

相關文章