CSS 中有時候須要一些特殊佈局,用正常流作不出來的效果。這時咱們就可使用破壞流和保護流的那些 CSS 屬性來實現這些效果。css
float
屬性指定一個元素應沿其容器的左側或右側放置,容許文本和內聯元素環繞它。該元素從網頁的正常流(文檔流)中移除,儘管仍然保持部分的流動性(與絕對定位相反)。html
當一個元素浮動以後,它會被移出正常的文檔流,而後向左或者向右平移,一直平移直到碰到了所處的容器的邊框,或者碰到另一個浮動的元素。web
float
最初的設計目的是爲了實現文字環繞效果,主要指的就是文字環繞圖片顯示的效果。因此就致使咱們用它實現一些複雜的佈局時問題一大堆。因此能不用float
佈局就不用。瀏覽器
float
主要有 3 個屬性值none
, left
和right
。佈局
當一個元素浮動時它具備如下特性:ui
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>
複製代碼
咱們能夠看到p
和img
重疊了,可是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 個值,none
,left
,right
和both
。
其中left
和right
是沒什麼做用的,由於在要使用left
和right
的狀況下均可以使用both
替換。
clear
屬性是讓自身不能和前面的浮動元素相鄰,它對後面的元素是無論的,left
和right
是不能同時存在的。
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
的影響。
塊格式化上下文(Block Formatting Context,BFC) 是 Web 頁面的可視化 CSS 渲染的一部分,是塊盒子的佈局過程發生的區域,也是浮動元素與其餘元素交互的區域。
BFC 就像結界,它會造成一個封閉的空間,裏面的子元素不會影響到外面的元素,因此 BFC 也能夠用來清除浮動。
在如下狀況下會觸發 BFC:
float
不是none
)position
的值不爲relative
和static
overflow
值不爲visible
的塊元素display
的值爲table-cell
、table-caption
和inline-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
是最適合清除浮動影響的元素,而不是clear
。可是它的本職工做仍是裁剪。它是overflow-x
和overflow-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-x
和 overflow-y
overflow-x
和overflow-y
屬性中的一個值設置爲visible
而另 外一個設置爲scroll
、auto
或hidden
,則visible
的樣式表現會如同auto
。
也就是說永遠不可能實現一個方向溢出剪裁或滾動,另外一方向內容溢出顯示的效果。
HTML 中只有兩個標籤默承認以產生滾動條,html
和textarea
,由於它們的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;
}
複製代碼
通常實現錨點定位有兩種方法,一種是使用a
的href
和name
屬性,如:
<a href="#1">Title ></a>
<a name="1">Title</a>
複製代碼
還有一種是使用a
的href
和其餘元素的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錨點定位
,它是利用label
的for
屬性和input
的id
屬性。
<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
屬性用於指定一個元素在文檔中的定位方式。top
,right
,bottom
和left
屬性則決定了該元素的最終位置。
position
一共有 5 個值:
static
正常的佈局行爲,即元素在文檔常規流中當前的佈局位置。relative
元素先放置在未添加定位時的位置,再在不改變頁面佈局的前提下調整元素位置absolute
脫離正常文檔流,經過指定元素相對於最近的非static
定位祖先元素的偏移,來肯定元素位置fixed
和absolute
相似,可是它是相對於屏幕視口的位置來指定元素位置。sticky
盒位置根據正常流計算,而後相對於該元素在流中的 flow root(BFC)和最近的塊級祖先元素定位。在全部狀況下,該元素定位均不對後續元素形成影響。定位元素的類型主要有:
相對定位元素
- 是計算後位置屬性爲relative
的元素。絕對定位元素
- 是計算後位置屬性爲absolute
或fixed
的元素。粘性定位元素
- 是計算後位置屬性爲sticky
的元素。absolute
定位和overflow
的裁剪相似,它的定位是相對於祖先定位元素的padding box
的。
absolute
相對於最近的position
不爲static
的祖先元素定位,若是沒有的話,就像對於html
定位。
當一個元素設置了absolute
時候,它的float
屬性是無效的。
absolute
和float
相似它們有幾個共同點:
position
後也會發生塊狀化
,display
的計算值就是block
或table
。absolute
會破壞正常的流來實現本身的特性表現,但自己仍是受普通的流體元素佈局。absolute
也能夠 BFCabsolute
也具備包裹性
無依賴定位定位指的是,absolute
定位,不依賴left
, right
, top
, bottom
和設置父元素爲relative
,來實現元素定位。
absolute
定位元素的位置和沒有設置absolute
時的位置有關。因此咱們能夠經過調整元素的margin
來調整元素的無依賴定位。
若是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
規則和普通流體元素的同樣:
auto
,auto
爲剩餘空間大小;auto
,則平分剩餘空間。.box {
width: 300px; height: 200px;
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
margin: auto;
background: red;
}
複製代碼
這行代碼就可讓box
水平垂直居中。
咱們通常用relative
來限制absolute
定位。讓它相對於設置了relative
的祖先容器定位。
relative
是至關於本身當前的位置定位,通常狀況下它不會影響到周圍的元素。
當relative
同時設置了left
和right
或top
和bottom
時,它不會和absolute
同樣格式化寬高,而是根據文檔流的方向,一個有效而另外一個會無效。
fixed
定位的包含塊只有一個html
根元素,fixed
和absolute
同樣也可以使用無依賴定位。
粘性定位,就好像是relative
和fixed
的結合體。元素在屏幕內,表現爲relative
,就要滾出顯示器屏幕的時候,表現爲fixed
。
sticky
有如下特色:
sticky
的父級元素的overflow
只能是visible
,不然會沒有效果。sticky
元素,若是定位值相等,則會重疊;若是屬於不一樣父元素,則會擠開原來的元素,造成依次佔位的效果。inline-block
是display
的一個屬性值,它可讓元素和行內元素同樣在一行顯示,又能夠和塊級元素同樣設置寬高。
使用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;
}
複製代碼