CSS原生布局方式

css-layout

前言

網頁原生布局的方法其實網上有不少,大概爲Flow(流動佈局模型)、Float(浮動佈局模型)、Layer(層級佈局模型)。
<!--more-->css

Flow佈局

流動佈局模型其實就是默認的網頁佈局模式。也就是說網頁在默認狀態下的HTML網頁元素都是根據流動模型來分佈網頁內容的。
流動佈局將會有兩個比較典型的特徵,
第一,塊級元素都會在所處的最近父級容器元素內自上而下按順序垂直順延分佈,由於在默認狀態下,塊級元素的寬度都是100%(即父級元素寬度的100%)。實際上,塊狀元素都會以行的形式佔據位置。以下代碼所示,html

<html>
    <body>
        <h1>我是h1</h1>
        <div>我是div</div>
    </body>
</html>

如上述代碼所示,在沒有外在樣式的影響下,h1和div的寬度都將是100%(爲頁面的默認寬度)。
第二,在流動模型下,內聯元素都會在所處的最近父級容器元素內從左到右水平分佈顯示。瀏覽器

<html>
    <body>
        <a>我是a</a>
        <span>我是span</span>
    </body>
</html>

內聯元素不會像塊級元素那樣獨自的佔據一行。架構

Float佈局

任何元素在默認的狀況下都是處於整個文檔流中的,不會浮動的。當咱們給某一個元素設置浮動時,便可讓該元素擺脫當前文檔流,成爲浮動元素。
以下代碼,給div元素設置浮動,讓兩個div並排顯示。編輯器

div{
    width:200px;
    height:200px;
    border:2px red solid;
    float:left;
}
<div id="div1">我是div1</div>
<div id="div2">我是div2</div>

這裏有一點須要注意,若是我給div設置的浮動是float: right,那麼div1將會貼在右側,而div2將會貼在div1的左側。佈局

Layer佈局

什麼是層級佈局模型?測試

層級佈局模型就像是圖像軟件PhotoShop中很是流行的圖層編輯功能同樣,每一個圖層可以精肯定位操做,但在網頁設計領域,因爲網頁大小的活動性,層級佈局模型沒能受到熱捧。可是在網頁上局部使用層級佈局仍是有其方便之處的。
應用層級佈局,每每須要定位屬性的配合。CSS中有3種定位類型,flex

  • 絕對定位(position: absolute)ui

  • 相對定位(position: relative)spa

  • 固定定位(position: fixed)

絕對定位

若是想爲元素設置層級佈局模型中的絕對定位,須要設置position:absolute(表示絕對定位),這條語句的做用將元素從文檔流中拖出來,而後使用left、right、top、bottom屬性相對於其最接近的一個具備定位屬性的父包含塊進行絕對定位。若是不存在這樣的包含塊,則相對於body元素,即相對於瀏覽器窗口。

相對定位

若是想爲元素設置層級佈局模型中的相對定位,須要設置position:relative(表示相對定位),它經過left、right、top、bottom屬性肯定元素在正常文檔流中的偏移位置。相對定位完成的過程是首先按static(float)方式生成一個元素(而且元素像層同樣浮動了起來),而後相對於之前的位置移動,移動的方向和幅度由left、right、top、bottom屬性肯定,偏移前的位置保留不動。
相對定位與絕對定位最大的區別在於,前者沒有脫離當前文檔流然後者已經脫離了當前文檔流。脫離當前文檔流的意思是,該元素的先後元素在計算位置和偏移時將再也不計算該元素的大小和位置。

固定定位

position: fixed,表示固定定位,與absolute定位類型相似,但它的相對移動的座標是視圖(屏幕內的網頁窗口)自己。因爲視圖自己是固定的,它不會隨瀏覽器窗口的滾動條滾動而變化,除非你在屏幕中移動瀏覽器窗口的屏幕位置,或改變瀏覽器窗口的顯示大小,所以固定定位的元素會始終位於瀏覽器窗口內視圖的某個位置,不會受文檔流動影響,這與background-attachment:fixed;(用於定位背景圖片的位置)屬性功能相同。
固定定位在某一種場景下頗有用,當咱們須要在頁面的某一位置固定的展現某一元素,且不受頁面滾動條的影響。好比,常見的「返回頂部」之類的按鈕。

混合使用

現代網頁佈局中,常常將相對定位和絕對定位混合使用,以達到更加靈活的目的。以下代碼,

<style>
#box1{
    width:200px;
    height:200px;
    position:relative; /* 前輩元素的定位必須設置爲relative */
}
#box2{
    position:absolute; /* 相對於最近的一個定位設置爲relative的前輩元素的絕對定位 */
    top:20px;
    left:30px;
}
</style>
<div id="box1">
    <div id="box2">相對參照元素進行定位</div>
</div>

即,box2相對於box1是絕對定位的。當改變box1的位置時,box1內部的子元素是不會發生變化的,由於他們都是相對box1絕對定位的。

常見佈局方式(兩列)

兩列狀況暫定左側寬爲100PX

方法一:

float + calc()
.right {
    width: calc(100% - 100px);
}

方法二:

position / float + margin-left
//html部分同上
//css
.left {
  position:absolute;left: 0; /*或 float:left; */
  width: 100px;
  background: blue;
}
.right{
  margin-left: 100px;
  background: red;
  text-align:center;
}

兩列布局中,左邊固定,右邊自適應如何實現。

1.左浮動,右邊用margin-left長度爲左邊的固定寬度,寬爲100%

2.利用的是建立一個新的BFC(塊級格式化上下文)來防止文字環繞的原理來實現的。BFC就是一個相對獨立的佈局環境,它內部元素的佈局不受外面佈局的影響。它能夠經過如下任何一種方式來建立:

  • float的值不爲none

  • position的值不爲static或者relative

  • display的值爲 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一個

  • overflow的值不爲visible

三列布局左右固定中間自適應

聖盃

思路

首先有三行,頭部和尾部各佔一行,中間內容區一行,頭尾不重要
中間內容分爲三列對應三個div,爲了先展現中間的主要內容因此把中間那列放前面,而後是左和右對應的div
中間內容自適應寬度爲100%,此時已經把3個div所在的父容器佔滿了,因此想辦法讓左右2個div放置在左右側,
左側採起margin-left取-100%讓其在最左側,

右側同理取值-200px(像素值爲寬度大小),保證恰好佔滿自身寬度
這時候測試發現已經有自適應效果了,可是縮小到必定程度頁面就出問題了,左右不在了,
因此加上最低寬度就是左右2個DIV的寬度(另外得考慮瀏覽器默認的body下的margin爲8px,作了樣式重置不考慮)
這時候發現中間的內容文字被左右遮擋了,對父容器用pading左右值爲左右元素寬度,
爲何不對中間的DIV設置padding,我發現設置了不得做用,具體的緣由我暫時也搞不懂前因後果,
發現padding後左右有留白,這個時候左邊須要用 left: -200px;position: relative;來設置DIV位置,
辦法確實巧妙。右邊實現同理。

這時候發現已經大體有了點樣子了,效果也看的到,此時典型的三欄佈局,左右固定,中間內容自適應已經完成。

總結:

其實這個佈局已經有點年頭(聖盃佈局),經過左右兩塊DIV來遮擋了中間div寬度爲100%的區域,
而後壓縮了三個DIV共有的父容器,來實現對中間內容展現的完善,也使左右2個不在遮擋中間了。
而後我又趁機試了下z-index屬性,這裏有個小問題要注意(要讓z-index起做用有個小小前提,
就是元素的position屬性要是relative,absolute或是fixed)

我以前的想法是讓中間的內容置於頂層,不受div會由於某種hack致使位置變動遮擋了中間內容。
只須要設置下z-index屬性值便可,左右可不設置,也能夠設置以防萬一,不一樣瀏覽器對z-index的默認值解析不一樣,可能會致使問題。

基本的佈局架構就是如此,根據實際項目需求在此架構上完善,或者之後遇到這種相似的問題能打開思路,便算是有點收穫了。

核心代碼

<style>
        body {
            /*由於瀏覽器默認body爲margin:8px因此多加了16px*/
            min-width: 616px;
        }
        
        header {
            width: 100%;
            height: 40px;
            background-color: darkseagreen;
        }
        
        .container {
            /*height: 200px;*/
            /*overflow: hidden;*/
            padding: 0 200px;
        }
        
        .middle {
            width: 100%;
            height: 200px;
            background-color: deeppink;
            float: left;
            /*position: relative;*/
        }
        
        .left {
            width: 200px;
            height: 200px;
            background-color: blue;
            float: left;
            margin-left: -100%;
            left: -200px;
            position: relative;
        }
        
        .right {
            width: 200px;
            height: 200px;
            background-color: darkorchid;
            float: left;
            margin-left: -200px;
            right: -200px;
            position: relative;
        }
        
        footer {
            clear: both;
            width: 100%;
            height: 30px;
            background-color: darkslategray;
        }
    </style>
<header>
        <h4>Header內容區</h4>
    </header>
    <div class="container">
        <div class="middle">
            <h4>中間彈性區</h4>
            <p>
                我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容
            </p>
        </div>
        <div class="left">
            <h4>左邊欄</h4>
        </div>
        <div class="right">
            <h4>右邊欄</h4>
        </div>
    </div>
    <footer>
        <h4>Footer內容區</h4>
    </footer>

雙飛翼

思路

雙飛翼佈局的方式跟聖盃在前部分是同樣,不一樣之處主要在於如何處理中間的內容塊被遮擋的問題
聖盃用padding的思路,使之壓縮,可是父容器壓縮,左右DIV位置變動,只能用相對位置進行left
設置位移爲元素寬度來調整
而雙飛翼的路線爲採用的方式相比聖盃的父容器padding,
改變的是中間內容的內層div的外邊框,相對來講對佈局的破壞不大,
可是要採用這種方式又不破壞頁面結構,就只能在中間內容div內部的再加個DIV設置margin或padding.
使以內容變相「壓縮」等同padding效果,而且不會改變中間內容DIV外部的結構,只是內部的。
細心的人留意下我註釋的代碼,這裏其實還有個CSS浮動的樣式問題,出現這種狀況有各類方式清除浮動,
我就很少講解。大概有6種。

清除浮動(經常使用)

1.通常目前經常使用就是用:after僞元素給使用的浮動的父容器設置。

新浪使用方式
        .clearfix:after{ 
            content: '';
            display: block;
            clear: both;
            height: 0;
            visibility: hidden;
        }
        .clearfix:after{  /*最簡方式*/
            content: '';
            display: block;
            clear: both;
        }

2.給父元素定高

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .outer{
            border: 1px solid black;
            width: 300px;
            height: 50px;
        }
        .inner{
            width: 50px;
            height: 50px;
            background-color: #ff4400;
            margin-right: 20px;
            float: left;
        }
        .footer{
            background-color: #005FC3;
            width: 200px;
            height: 100px;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
    </div>
    <div class="footer"></div>
</body>
</html>

3.利用 overflow:hidden 屬性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        .outer{
            border: 1px solid black;
            width: 300px;
            overflow: hidden;
            zoom: 1;/*兼容 IE*/
        }
        .inner{
            width: 50px;
            height: 50px;
            background-color: #ff4400;
            margin-right: 20px;
            float: left;
        }
        .footer{
            background-color: #005FC3;
            width: 200px;
            height: 100px;
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
    </div>
    <div class="footer"></div>
</body>
</html>

核心代碼

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>雙飛翼</title>
    <style>
        header {
            width: 100%;
            height: 40px;
            background-color: darkseagreen;
        }
        
        .container {
            /*height: 200px;*/
            /*overflow: hidden;*/
        }
        
        .middle {
            width: 100%;
            height: 200px;
            background-color: deeppink;
            float: left;
            word-break: break-all;
        }
        
        .left {
            width: 200px;
            height: 200px;
            background-color: blue;
            float: left;
            margin-left: -100%;
        }
        
        .right {
            width: 200px;
            height: 200px;
            background-color: darkorchid;
            float: left;
            margin-left: -200px;
        }
        
        footer {
            width: 100%;
            height: 30px;
            background-color: darkslategray;
            clear: both;
        }
        
        .div-middle {
            margin: 0 200px;
            /*padding: 0 200px;*/
        }
    </style>
</head>

<body>
    <header>
        <h4>Header內容區</h4>
    </header>
    <div class="container">

        <div class="middle">
            <div class="div-middle">
                <h4>中間彈性區</h4>
                <p>
                    我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容我是各類內容
                </p>
            </div>
        </div>
        <div class="left">
            <h4>左邊欄</h4>
        </div>
        <div class="right">
            <h4>右邊欄</h4>
        </div>
    </div>
    <footer>
        <h4>Footer內容區</h4>
    </footer>
</body>

</html>

End

本篇只作階段性的初級總結,原諒我沒有貼出代碼的效果圖,之後有機會再擴展並進行效果圖片展現,但願你們本身在編輯器下嘗試效果。

相關文章
相關標籤/搜索