CSS 中的 float、BFC、position 和 inline-block

CSS 中有時候須要一些特殊佈局,用正常流作不出來的效果。這時咱們就可使用破壞流和保護流的那些 CSS 屬性來實現這些效果。css

float

float 屬性指定一個元素應沿其容器的左側或右側放置,容許文本和內聯元素環繞它。該元素從網頁的正常流(文檔流)中移除,儘管仍然保持部分的流動性(與絕對定位相反)。html

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

float最初的設計目的是爲了實現文字環繞效果,主要指的就是文字環繞圖片顯示的效果。因此就致使咱們用它實現一些複雜的佈局時問題一大堆。因此能不用float佈局就不用。瀏覽器

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

當一個元素浮動時它具備如下特性:ui

  • 包裹性 - 浮動元素會包裹它的子元素(浮動元素子元素 100x100,則浮動元素也是 100x100)
  • 自適應 - 若是浮動元素子元素有一堆文字時,它的最終寬度爲它的父級寬度。
  • 塊狀話並格式化上下文 - float的屬性值不爲none,則其display計算值就是block 或者table
  • 破壞文檔流 - 會讓父元素的高度塌陷
  • 沒有margin合併

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

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

咱們能夠看到pimg重疊了,可是p中的行框盒子則是跟隨浮動元素。設計

流體佈局

float能夠很方便的實現多欄佈局。3d

<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屬性適用於浮動和非浮動元素。code

它一共有 4 個值,noneleftrightboth

其中leftright是沒什麼做用的,由於在要使用leftright的狀況下均可以使用both替換。

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

clear屬性只有塊級元素纔有效的,因此咱們用::after僞類時都要將它的display設置爲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 渲染的一部分,是塊盒子的佈局過程發生的區域,也是浮動元素與其餘元素交互的區域。

BFC 就像結界,它會造成一個封閉的空間,裏面的子元素不會影響到外面的元素,因此 BFC 也能夠用來清除浮動。

在如下狀況下會觸發 BFC:

  • 根元素或包含根元素的元素
  • 浮動元素(元素的float不是none
  • position的值不爲relativestatic
  • overflow值不爲visible的塊元素
  • display的值爲table-celltable-captioninline-block中的任何一個
  • 彈性元素和網格元素

流體佈局

BFC 能夠實現更健壯、更智能的自適應佈局。

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

普通流體元素在設置了overflow:hidden後,會自動填滿容器中除了浮 動元素之外的剩餘空間,造成自適應佈局效果。

overflow

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

overflow裁剪是沿着border內邊緣裁剪的。

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

它經常使用屬性有:

  • visible 默認值。內容不會被修剪,會呈如今元素框以外
  • hidden 內容會被修剪,而且其他內容不可見
  • scroll 內容會被修剪,瀏覽器會顯示滾動條以便查看其他內容,滾動條區域一直在
  • auto 由瀏覽器定奪,若是內容被修剪,就會顯示滾動條

overflow-xoverflow-y

overflow-xoverflow-y屬性中的一個值設置爲visible而另 外一個設置爲scrollautohidden,則visible的樣式表現會如同auto

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

滾動條

HTML 中只有兩個標籤默承認以產生滾動條,htmltextarea,由於它們的overflow不是visible

滾動欄佔據寬度的特性最大的問題就是頁面加載的時候水平居中的佈局可能會產生晃動,由於窗體默認是沒有滾動條的,而 HTML 內容是自上而下加載的,就會發生一開始沒有 滾動條,後來忽然出現滾動條的狀況,此時頁面的可用寬度發生變化,水平居中從新計算,導 致頁面發生晃動。

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

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 內層軌道
  • ::-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;
}
複製代碼

錨點定位

通常實現錨點定位有兩種方法,一種是使用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 值能夠在頁面中找到對應的元素,而且是非隱藏狀態,不然不會發生定位行爲。

咱們也可使用一個簡單的#來實現返回頂部功能,它能夠將頁面是定位到頂部。

錨點定位行爲的發生,本質上是經過改變容器滾動高度或者寬度來實現的。水平和垂直方向同樣,通常發生垂直滾動的多。

錨點定位也能夠發生在普通的容器元素上,並且定位行爲的發生是由內而外的。由內而外指的是,普通元素和窗體同時可滾動的時候,會由內而外觸發全部可滾動窗體的錨點定位行爲。

<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>
複製代碼

咱們發現overflow滾動到了h2元素位置(雖然沒有滾動條),頁面的滾動條也滾動到了能夠顯示h2元素的位子。

用這個特色咱們能夠實現一個無需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屬性用於指定一個元素在文檔中的定位方式。toprightbottomleft屬性則決定了該元素的最終位置。

position一共有 5 個值:

  • static 正常的佈局行爲,即元素在文檔常規流中當前的佈局位置。
  • relative 元素先放置在未添加定位時的位置,再在不改變頁面佈局的前提下調整元素位置
  • absolute 脫離正常文檔流,經過指定元素相對於最近的非static定位祖先元素的偏移,來肯定元素位置
  • fixedabsolute相似,可是它是相對於屏幕視口的位置來指定元素位置。
  • sticky 盒位置根據正常流計算,而後相對於該元素在流中的 flow root(BFC)和最近的塊級祖先元素定位。在全部狀況下,該元素定位均不對後續元素形成影響。

定位元素的類型主要有:

  • 相對定位元素 - 是計算後位置屬性爲relative的元素。
  • 絕對定位元素 - 是計算後位置屬性爲absolutefixed的元素。
  • 粘性定位元素 - 是計算後位置屬性爲sticky的元素。

absolute

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

absolute相對於最近的position不爲static的祖先元素定位,若是沒有的話,就像對於html定位。

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

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

  1. 當元素設置了position後也會發生塊狀化display的計算值就是blocktable
  2. absolute會破壞正常的流來實現本身的特性表現,但自己仍是受普通的流體元素佈局。
  3. absolute也能夠 BFC
  4. absolute也具備包裹性

無依賴定位

無依賴定位定位指的是,absolute定位,不依賴left, right, top, bottom和設置父元素爲relative,來實現元素定位。

absolute定位元素的位置和沒有設置absolute時的位置有關。因此咱們能夠經過調整元素的margin來調整元素的無依賴定位。

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元素高寬還要大,也都不會出現滾動條。

流體特性

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

.box {
    position: absolute;
    left: 0; right: 0; top: 0; bottom: 0;
}
複製代碼

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

當絕對定位元素處於流體狀態的時候,各個盒模型相關屬性的解析和普通流體元素都是一 模同樣的,而且可使用margin:auto讓絕對定位元素保持居中。

絕對定位元素的margin:auto規則和普通流體元素的同樣:

  • 若是一側定值,一側autoauto爲剩餘空間大小;
  • 若是兩側均是auto,則平分剩餘空間。
.box {
  width: 300px; height: 200px;
  position: absolute;
  left: 0; right: 0; top: 0; bottom: 0;
  margin: auto;
  background: red;
}
複製代碼

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

relative

咱們通常用relative來限制absolute定位。讓它相對於設置了relative的祖先容器定位。

relative是至關於本身當前的位置定位,通常狀況下它不會影響到周圍的元素。

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

fixed

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

sticky

粘性定位,就好像是relativefixed的結合體。元素在屏幕內,表現爲relative,就要滾出顯示器屏幕的時候,表現爲fixed

sticky有如下特色:

  1. sticky的父級元素的overflow只能是visible,不然會沒有效果。
  2. 同一個父容器中的sticky元素,若是定位值相等,則會重疊;若是屬於不一樣父元素,則會擠開原來的元素,造成依次佔位的效果。

inline-block

inline-blockdisplay的一個屬性值,它可讓元素和行內元素同樣在一行顯示,又能夠和塊級元素同樣設置寬高。

空隙

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

<style> <div></div> <div></div> div { display: inline-block; width: 100px; height: 100px; background: red; } </style>
複製代碼

空格至關於字符,那麼咱們可使用font-size: 0;去除它們之間的空隙。

除了font-size咱們還可使用letter-spacing,它用來設置字符之間的空隙寬度。咱們能夠設置word-spacing: -1em;來去除inline-block之間的空隙。

咱們還可使用word-spacing,它用來設置單詞間距,它和letter-spacing類似,咱們設置它爲負值來去除空隙。

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;
}
複製代碼
相關文章
相關標籤/搜索