傳統(tǒng)css布局的那些事&轉(zhuǎn)載自【螞蟻號】

float

float 屬性指定一個元素應(yīng)沿其容器的左側(cè)或右側(cè)放置,允許文本和內(nèi)聯(lián)元素環(huán)繞它。該元素從網(wǎng)頁的正常流(文檔流)中移除,盡管仍然保持部分的流動性(與絕對定位相反)。

當一個元素浮動之后,它會被移出正常的文檔流,然后向左或者向右平移,一直平移直到碰到了所處的容器的邊框,或者碰到另外一個浮動的元素。

float最初的設(shè)計目的是為了實現(xiàn)文字環(huán)繞效果,主要指的就是文字環(huán)繞圖片顯示的效果。所以就導致我們用它實現(xiàn)一些復雜的布局時問題一大堆。所以能不用float布局就不用。

float主要有 3 個屬性值none, leftright。

當一個元素浮動時它具有以下特性:

  • 包裹性 - 浮動元素會包裹它的子元素(浮動元素子元素 100x100,則浮動元素也是 100x100)

  • 自適應(yīng) - 如果浮動元素子元素有一堆文字時,它的最終寬度為它的父級寬度。

  • 塊狀話并格式化上下文 - float的屬性值不為none,則其display計算值就是block 或者table

  • 破壞文檔流 - 會讓父元素的高度塌陷

  • 沒有margin合并

float還有一個特性是行框盒子和浮動元素的不可重疊,正常定位狀態(tài)下只會跟隨浮動元素,而不會發(fā)生重疊。

<div>???<img?src="http://">?</div>?
<p>文字文字文字文字文字文字文字文字文字文字文字文
字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字</p>?
<style>?
div?{padding-top:?10px;?background:?#ccc;}?
img?{?width:?100px;?float:?left;}?
</style>



我們可以看到pimg重疊了,但是p中的行框盒子則是跟隨浮動元素。

流體布局

float可以很方便的實現(xiàn)多欄布局。

<div?class='page'>???
????<div?class="float">?????
????????<p>float</p>???
????</div>???
????<div?class="a">?????文字文字文字文字文字文字文字文字文字文
????字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字???
????</div>?
</div>?
<style>?
.float?{?float:?left;?width:?60px;background:?green;}?
.a?{?margin-left:?70px;?background:?red;?}?</style>



<div>???
????<div?class="l">left</div>???
????<div?class="r">right</div>???
????<h1>title</h1>?</div>?
<style>?
.l?{?float:?left;?}??
.r?{?float:?right;?}?
h1?{?margin:?0?50px;?text-align:?center;}?
</style>



清除浮動

clear屬性是專門來處理float帶來的高度塌陷等問題的。 它指定一個元素是否必須移動(清除浮動后)到在它之前的浮動元素下面。clear屬性適用于浮動和非浮動元素。

它一共有 4 個值,noneleft,rightboth。

其中leftright是沒什么作用的,因為在要使用leftright的情況下都可以使用both替換。

clear屬性是讓自身不能和前面的浮動元素相鄰,它對后面的元素是不管的,leftright是不能同時存在的。

clear屬性只有塊級元素才有效的,所以我們用::after偽類時都要將它的display設(shè)置為block。

.clear:after?{?????
????content:?'';?????
????display:?block;?????
????clear:?both;?}

clear其實并沒有清除浮動而是讓自己不和float元素在一行顯示。

<div?class="page">?????
????<img?src="https://">?????文字文字文字文字文字文字?</div>?
????<div>?????文字文字文字文字文字文字文字文字文字文字文字文
????字文字文字文字文字文字文字文字?</div>?
?<style>?
?????.page:after?{?????
?????????content:?'';?????
?????????display:?table;?????
?????????clear:?both;?
?????}?
?????.page?img?{?????
?????????float:left;?????
?????????width:?100px;?
??????}?
??????.page?+?div?{?????margin-top:?-2px;?}?
?</style>



可以看到雖然使用了clear,但是clear后面的元素任有可能受float的影響。

BFC

塊格式化上下文(Block Formatting Context,BFC) 是 Web 頁面的可視化 CSS 渲染的一部分,是塊盒子的布局過程發(fā)生的區(qū)域,也是浮動元素與其他元素交互的區(qū)域。

BFC 就像結(jié)界,它會形成一個封閉的空間,里面的子元素不會影響到外面的元素,所以 BFC 也可以用來清除浮動。

在以下情況下會觸發(fā) BFC:

  • 根元素或包含根元素的元素

  • 浮動元素(元素的float不是none

  • position的值不為relativestatic

  • overflow值不為visible的塊元素

  • display的值為table-cell、table-captioninline-block中的任何一個

  • 彈性元素和網(wǎng)格元素

流體布局

BFC 可以實現(xiàn)更健壯、更智能的自適應(yīng)布局。

<div>?????<div></div>?????
<p>文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字文字</p>?
</div>?<style>?
div?>?div?{???
????width:?50px;???
????height:?50px;???
????float:?left;???
????background:?red;?
}?
p?{?overflow:?hidden;?}?</style>



普通流體元素在設(shè)置了overflow:hidden后,會自動填滿容器中除了浮 動元素以外的剩余空間,形成自適應(yīng)布局效果。

overflow

overflow是最適合清除浮動影響的元素,而不是clear。但是它的本職工作還是裁剪。它是overflow-xoverflow-y的簡寫屬性。

overflow裁剪是沿著border內(nèi)邊緣裁剪的。

<div>???<p>文字文字文字文字文字文字文字文字文字文字文字文字</p>?</div>?
<style>?
div?{???border:?10px?solid;???padding:?10px;???overflow:?hidden;?}?
p?{???white-space:?nowrap;?}?
</style>



它常用屬性有:

  • visible 默認值。內(nèi)容不會被修剪,會呈現(xiàn)在元素框之外

  • hidden 內(nèi)容會被修剪,并且其余內(nèi)容不可見

  • scroll 內(nèi)容會被修剪,瀏覽器會顯示滾動條以便查看其余內(nèi)容,滾動條區(qū)域一直在

  • auto 由瀏覽器定奪,如果內(nèi)容被修剪,就會顯示滾動條

overflow-xoverflow-y

overflow-xoverflow-y屬性中的一個值設(shè)置為visible而另 外一個設(shè)置為scroll、autohidden,則visible的樣式表現(xiàn)會如同auto。

也就是說永遠不可能實現(xiàn)一個方向溢出剪裁或滾動,另一方向內(nèi)容溢出顯示的效果。

滾動條

HTML 中只有兩個標簽?zāi)J可以產(chǎn)生滾動條,htmltextarea,因為它們的overflow不是visible。

滾動欄占據(jù)寬度的特性最大的問題就是頁面加載的時候水平居中的布局可能會產(chǎn)生晃動,因為窗體默認是沒有滾動條的,而 HTML 內(nèi)容是自上而下加載的,就會發(fā)生一開始沒有 滾動條,后來突然出現(xiàn)滾動條的情況,此時頁面的可用寬度發(fā)生變化,水平居中重新計算,導 致頁面發(fā)生晃動。

這里有一個防止晃動的小技巧。

html?{?????
????overflow-y:?scroll;?/*?for?IE8?*/?}?
:root?{?????
????overflow-y:?auto;?????
????overflow-x:?hidden;?
???}?:root?body?{?????position:?absolute;?}?
body?{?????width:?100vw;?????overflow:?hidden;?}

對于支持-webkit-前綴的瀏覽器,我們可以用以下偽類自定義滾動條。

  • ::-webkit-scrollbar 整體部分

  • ::-webkit-scrollbar-button 兩端按鈕

  • ::-webkit-scrollbar-track 外層軌道

  • ::-webkit-scrollbar-track-piece 內(nèi)層軌道

  • ::-webkit-scrollbar-thumb 滾動滑塊

  • ::-webkit-scrollbar-corner 邊角

::-webkit-scrollbar?{???width:?8px;?}?
::-webkit-scrollbar-thumb?{???
????background-color:?rgba(0,0,0,.3);???
????border-radius:?10px;?
?}?
?::-webkit-scrollbar-track?{???
?????????background-color:?transparent;???
?????????border-radius:?10px;?
?}



文字溢出

CSS 中有很多屬性要想生效都必須要有其他 CSS 屬性配合。比如文字溢出顯示...。

.ell?{?????
????text-overflow:?ellipsis;?????
????white-space:?nowrap;?????
????overflow:?hidden;?????/*?這?3?個聲明缺一不可?*/?
}?/*?多行文字省略,無需依賴?overflow?*/?
.ell2?{?????
????display:?-webkit-box;?????
????-webkit-box-orient:?vertical;?????
????-webkit-line-clamp:?2;?}

錨點定位

一般實現(xiàn)錨點定位有兩種方法,一種是使用ahrefname屬性,如:

<a?href="#1">Title?></a>?<a?name="1">Title</a>

還有一種是使用ahref和其他元素的id屬性。

<a?href="#1">Title?></a>?<h2?id="1">Title</h2>

它的原理是當我們點擊一個鏈接,改變了地址欄的 hash 值,而且這個 hash 值可以在頁面中找到對應(yīng)的元素,并且是非隱藏狀態(tài),否則不會發(fā)生定位行為。

我們也可以使用一個簡單的#來實現(xiàn)返回頂部功能,它可以將頁面是定位到頂部。

錨點定位行為的發(fā)生,本質(zhì)上是通過改變?nèi)萜鳚L動高度或者寬度來實現(xiàn)的。水平和垂直方向一樣,一般發(fā)生垂直滾動的多。

錨點定位也可以發(fā)生在普通的容器元素上,而且定位行為的發(fā)生是由內(nèi)而外的。由內(nèi)而外指的是,普通元素和窗體同時可滾動的時候,會由內(nèi)而外觸發(fā)所有可滾動窗體的錨點定位行為。

<div>???
????<div?class="overflow">?????
????????<p>文字</p>?????<p>文字</p>?????<p>文字</p>?????
????????<h2?id="1">Title</h2>???
????</div>???
????<a?href="#1">title?></a>??
????<div?style="height:?500px;"></div>?
</div>?
<style>?
.overflow?{???
????overflow:?hidden;???
????height:?2em;???
????background:?#ccc;?}?
</style>





我們發(fā)現(xiàn)overflow滾動到了h2元素位置(雖然沒有滾動條),頁面的滾動條也滾動到了可以顯示h2元素的位子。

用這個特點我們可以實現(xiàn)一個無需js的幻燈片效果。但是當我們點擊切換按鈕的時候,頁面的滾動條也會自動滾動。

這時候我們就可以使用focus錨點定位,它是利用labelfor屬性和inputid屬性。

<div>?????<div><input?id="one">1</div>?????<div><input?id="two">2</div>?????<div><input?id="three">3</div>?</div>?<div>?????<label?for="one">1</label>?????<label?for="two">2</label>?????<label?for="three">3</label>?</div>?復制代碼

除了點擊按鈕切換,我們還可以使用tab鍵切換。

position

position屬性用于指定一個元素在文檔中的定位方式。top,right,bottomleft屬性則決定了該元素的最終位置。

position一共有 5 個值:

  • static 正常的布局行為,即元素在文檔常規(guī)流中當前的布局位置。

  • relative 元素先放置在未添加定位時的位置,再在不改變頁面布局的前提下調(diào)整元素位置

  • absolute 脫離正常文檔流,通過指定元素相對于最近的非static定位祖先元素的偏移,來確定元素位置

  • fixedabsolute類似,但是它是相對于屏幕視口的位置來指定元素位置。

  • sticky 盒位置根據(jù)正常流計算,然后相對于該元素在流中的 flow root(BFC)和最近的塊級祖先元素定位。在所有情況下,該元素定位均不對后續(xù)元素造成影響。

定位元素的類型主要有:

  • 相對定位元素 - 是計算后位置屬性為relative的元素。

  • 絕對定位元素 - 是計算后位置屬性為absolutefixed的元素。

  • 粘性定位元素 - 是計算后位置屬性為sticky的元素。

absolute

absolute定位和overflow的裁剪類似,它的定位是相對于祖先定位元素的padding box的。

absolute相對于最近的position不為static的祖先元素定位,如果沒有的話,就像對于html定位。

當一個元素設(shè)置了absolute時候,它的float屬性是無效的。

absolutefloat類似它們有幾個共同點:

  1. 當元素設(shè)置了position后也會發(fā)生塊狀化,display的計算值就是blocktable。

  2. absolute會破壞正常的流來實現(xiàn)自己的特性表現(xiàn),但本身還是受普通的流體元素布局。

  3. absolute也可以 BFC

  4. absolute也具有包裹性

無依賴定位

無依賴定位定位指的是,absolute定位,不依賴left, right, top, bottom和設(shè)置父元素為relative,來實現(xiàn)元素定位。

absolute定位元素的位置和沒有設(shè)置absolute時的位置有關(guān)。所以我們可以通過調(diào)整元素的margin來調(diào)整元素的無依賴定位。

absolute 與 overflow

如果overflow不是定位元素,同時絕對定位元素和overflow容器之間也沒有定位元素,則overflow無法對absolute元素進行剪裁。

<div?style="overflow:?hidden;">?????
????<img?src="a.jpg"?style="position:?absolute;">?????
<!--?不會被剪裁?-->?</div>?
<div?style="overflow:?hidden;?position:?relative;">?????
????<img?src="a.jpg"?style="position:?absolute;">?????
<!--?被剪裁?-->?</div>?<div?style="overflow:?hidden;">?????
<div?style="position:?relative;">?????????
????<img?src="a.jpg"?style="position:?absolute;">?????????
<!--?被剪裁?-->????
</div>?
</div>

如果overflow的屬性值不是hidden而是auto,即使絕對定位元素高寬 比overflow元素高寬還要大,也都不會出現(xiàn)滾動條。

流體特性

absolute元素的left/top/right/bottom屬性都設(shè)置的時候,absolute元素才真正變成 絕對定位元素。它會格式化元素的寬度和高度。

.box?{?????
????position:?absolute;?????
????left:?0;?
????right:?0;?
????top:?0;
????bottom:?0;?
}

如果box父定位元素是html的話,它的寬和高會隨著瀏覽器窗口大小變化而變化。

當絕對定位元素處于流體狀態(tài)的時候,各個盒模型相關(guān)屬性的解析和普通流體元素都是一 模一樣的,并且可以使用margin:auto讓絕對定位元素保持居中。

絕對定位元素的margin:auto規(guī)則和普通流體元素的一樣:

  • 如果一側(cè)定值,一側(cè)auto,auto為剩余空間大小;

  • 如果兩側(cè)均是auto,則平分剩余空間。

.box?{???
????width:?300px;?
????height:?200px;???
????position:?absolute;???
????left:?0;?
????right:?0;?
????top:?0;?
????bottom:?0;???
????margin:?auto;???
????background:?red;?
}

這行代碼就可以讓box水平垂直居中。

relative

我們一般用relative來限制absolute定位。讓它相對于設(shè)置了relative的祖先容器定位。

relative是相當于自己當前的位置定位,一般情況下它不會影響到周圍的元素。

relative同時設(shè)置了leftrighttopbottom時,它不會和absolute一樣格式化寬高,而是根據(jù)文檔流的方向,一個有效而另一個會無效。

fixed

fixed定位的包含塊只有一個html根元素,fixedabsolute一樣也可使用無依賴定位。

sticky

粘性定位,就好像是relativefixed的結(jié)合體。元素在屏幕內(nèi),表現(xiàn)為relative,就要滾出顯示器屏幕的時候,表現(xiàn)為fixed

sticky有以下特點:

  1. sticky的父級元素的overflow只能是visible,否則會沒有效果。

  2. 同一個父容器中的sticky元素,如果定位值相等,則會重疊;如果屬于不同父元素,則會擠開原來的元素,形成依次占位的效果。

inline-block

inline-blockdisplay的一個屬性值,它可以讓元素和行內(nèi)元素一樣在一行顯示,又可以和塊級元素一樣設(shè)置寬高。

空隙

使用inline-block有點小問題,那就是inline-block元素間有空格或是換行產(chǎn)生了間隙。

<style>?<div></div>?<div></div>?
div?{???
????display:?inline-block;???
????width:?100px;???
????height:?100px;???
????background:?red;?
}?
</style>



空格相當于字符,那么我們可以使用font-size: 0;去除它們之間的空隙。

除了font-size我們還可以使用letter-spacing,它用來設(shè)置字符之間的空隙寬度。我們可以設(shè)置word-spacing: -1em;來去除inline-block之間的空隙。

我們還可以使用word-spacing,它用來設(shè)置單詞間距,它和letter-spacing相似,我們設(shè)置它為負值來去除空隙。

YUI 3 CSS Grids 是這樣去除inline-block之間的空隙的。

.yui3-g?{?????
????letter-spacing:?-0.31em;?/*?webkit?*/?????
????*letter-spacing:?normal;?/*?IE?<?8?*/?????
????word-spacing:?-0.43em;?/*?IE?<?8?&&?gecko?*/?
}?
.yui3-u?{?????
????display:?inline-block;?????
????zoom:?1;?
????*display:?inline;?/*?IE?<?8?*/?????
????letter-spacing:?normal;?????
????word-spacing:?normal;?????
????vertical-align:?top;?
?}

作者:wopen
鏈接:https://juejin.im/post/5c86213ee51d452fee00c131
來源:掘金


原文地址:https://www.v5ant.com/details/8s7zjCtbr.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容