CSS 佈局解決方案之延伸篇
然後自己做一點延伸,再把程式碼敲出來,加深下印象。
水平居中:inline-block + text-align
CSS:
<style>
.child1 {
display: inline-block;
background: khaki;
}
.child2 {
display: inline-block;
background: hotpink;
}
.parent {
text-align : center;
background: lightgreen
}
</style>
html:
<div class="parent">
<div class="child1">demo</div>
<div class="child2">demo2</div>
</div>
瀏覽器顯示:
優點:相容性好。缺點:.child1,2
裡面的字也會居中,這時候需要用text-align:left
來放到左邊,請看例子。
看,如果給.child1,2
text
都居中了: 我們再延伸一下,如果.child1
裡面再有一個.grandchild
的話,如果它是inline-block
的話,那麼它也會居中,也就是說只要你父元素設定了text-align:center
,裡面所有的子子孫孫節點都會繼承這個居中。
請看:
CSS:
<style>
.child1 {
display: inline-block;
background: khaki;
width:20%
}
.child2 {
display : inline-block;
background: hotpink;
width:20%
}
.grandchild {
display: inline-block;
background:mediumspringgreen;
width:50%
}
.parent {
text-align: center;
background: lightgreen
}
</style>
html:
<div class="parent">
<div class="child1">
<div class="grandchild">demo</div>
</div>
<div class="child2">demo2</div>
</div>
瀏覽器顯示:
如果不想文字居中的話那麼給.child
, 或者是 .grandchild
設定text-align:left
即可
這裡刪掉了.grandchild, .child1
中直接新增文字demo1這樣看得更加清晰點:
水平居中:margin + table
這種方法其實就是css把html裡面的table
標籤借過來用,裡面需要包含table, table-row
, table-header-group
, table-cell
等。
下面是個簡單的例子:
CSS:
<style>
.child1 {
display: table-cell;
background: rebeccapurple;
width: 20%;
}
.child2 {
display: table-cell;
background: darkgoldenrod;
width: 20%;
}
.child3 {
display: table-cell;
background: cyan;
width: 20%;
}
.parent {
display: table;
margin: 0 auto;
background: blue
}
.brother {
display: table-row;
text-align: center;
}
</style>
html:
<div class="parent">
<div class='brother'>
<div class="child1">demo1</div>
<div class="child2">demo2</div>
<div class="child3">demo3</div>
</div>
</div>
瀏覽器顯示:
優點:相容性還行。缺點:需要三層才能佈局,而且.parent
,和.brother
的寬度取決於table-cell
的寬度,所以設定不了background-color
水平居中:absolute + transform
CSS:
<style>
.child1 {
position: absolute;
left: 50%;
background: lightcoral;
transform: translateX(-50%);
}
.parent {
position: relative;
}
</style>
html:
<div class="parent">
<div class="child1">demo1</div>
</div>
瀏覽器顯示:
優點:因為設定了absolute
所以子元素位置固定,不會影響到兄弟元素。 在定位方面,有的時候我們需要以元素的中心點來定位而不是元素的左側,這是個很好的方法。 確定:因為用到了CSS3的transform
,所以有相容性問題。 而且不能用此方法設定多元素的居中排列。
看下面一個例子,就是進行元素的等分排列。
如果有N個元素那麼
left = (100%/N*2) + (100%/N) *n ( n = 0, 1, 2, … N-1);
請看CSS:
<style>
.child1 {
position: absolute;
left: 10%;
background: lightcoral;
transform: translateX(-50%);
}
.child2 {
position: absolute;
left: 30%;
background: lightcoral;
transform: translateX(-50%);
}
.child3 {
position: absolute;
left: 50%;
background: lightcoral;
transform: translateX(-50%);
}
.child4 {
position: absolute;
left: 70%;
background: lightcoral;
transform: translateX(-50%);
}
.child5 {
position: absolute;
left: 90%;
background: lightcoral;
transform: translateX(-50%);
}
.parent {
position: relative;
}
</style>
html:
<div class="parent">
<div class="child1">demo1</div>
<div class="child2">demo2</div>
<div class="child3">demo3</div>
<div class="child4">demo4</div>
<div class="child5">demo5</div>
</div>
瀏覽器顯示:
水平居中:margin + …
這裡有幾種用margin: 0 auto
來居中的方法:
- 設定寬度
<style>
.child1 {
width: 10%;
margin: 0 auto;
text-align: center;
}
</style>
<div class="child1">demo1</div>
只要你設定了寬度就可以用margin: 0 auto
來居中,不需要父元素。
2 . 用 display:table
<style>
.child1 {
display: table;
margin: 0 auto;
background:lightcoral;
}
</style>
<div class="child1">demo1</div>
以上兩種方法只要設定居中元素本身就好。
3 . 用 display:flex
<style>
.child1 {
margin: 0 auto;
background:lightcoral;
}
.parent {
display:flex;
}
</style>
<div class="parent">
<div class="child1">demo1</div>
</div>
這種方法需要在父級元素設定display:flex
, 因為用到了 CSS3的flex所以有可能有相容性問題。
想延伸一下,用 margin: 0 auto
, 同樣可以實現多個子元素的垂直居中。
<style>
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
font-size: 16px
}
</style>
<style>
.child1,
.child2,
.child3 {
width: 10%;
margin: 0 auto;
background: lightcoral;
}
.parent {
position: relative;
width: 30%;
height: 3.4rem;
background: lightgreen
}
</style>
<div class="parent">
<div class="child1">demo1</div>
<div class="child2">demo2</div>
<div class="child3">demo2</div>
</div>
瀏覽器顯示:
這裡父元素的height
用了rem
,好處是可以很好的貼合3個子元素的高度。
水平居中:flex+justify-content
CSS:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.child1,
.child2,
.child3 {
background: lightcoral;
margin: 1rem
}
.parent {
display:flex;
justify-content: center;
height:3rem;
background: lightgreen
}
</style>
html:
<div class="parent">
<div class="child1">demo1</div>
<div class="child2">demo2</div>
<div class="child3">demo3</div>
</div>
瀏覽器顯示:
這裡值得注意的是, 如果你修改父元素的高度,子元素的高度也會一起變化,以滿足子元素在父元素內總是居中:
如果改動父元素的height: 5rem
得到如下顯示結果:
垂直居中:table-cell+vertical-align
css:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.child1, .child2, .child3{
background: lightcoral;
}
.parent {
display: table-cell;
vertical-align: middle;
background: lightgreen;
height:10rem;
}
</style>
html:
<div class="parent">
<div class="child1">demo1</div>
<div class="child2">demo2</div>
<div class="child3">demo2</div>
</div>
瀏覽器顯示:
相容性很好,沒什麼缺點。
垂直居中:table-cell+vertical-align
CSS:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.child1{
position: absolute;
background: lightcoral;
top:50%;
transform: translateY(-50%)
}
.parent {
position: relative;
width:20%;
background: lightgreen;
height:10rem;
}
</style>
html:
<div class="parent">
<div class="child1">demo1</div>
</div>
瀏覽器顯示:
因為用到了css3所以可能有相容性問題,對於多列的垂直居中,參考水平居中的absolute
+ transform
公式就好。
垂直居中:flex + flex-direction + justify-content
CSS:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.child1{
background: lightcoral;
width:50%
}
.parent {
display: flex;
flex-direction: column;
justify-content: center;
background: lightgreen;
width:20%;
height:10rem;
}
</style>
html:
<div class="parent">
<div class="child1">demo1</div>
<div class="child1">demo2</div>
<div class="child1">demo3</div>
</div>
瀏覽器顯示:
優點是隻需要設定父元素,缺點是CSS3相容性問題。
垂直居中:flex + align+items
CSS:
.parent {
position:flex;
align-items:center;
background: lightgreen;
width:20%;
height:10rem;
}
html:
<div class="parent">
<div class="child1">demo1</div>
</div>
優點是隻需要設定父元素,缺點是CSS3相容性問題,以及只能設定一個子元素。
水平垂直居中:absolute+transform
CSS:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.child1{
position: absolute;
left:50%;
top:50%;
transform: translate(-50%, -50%);
background: lightcoral;
}
.parent {
position: relative;
background: lightgreen;
width:20%;
height:10rem;
}
</style>
html:
<div class="parent">
<div class="child1">demo1</div>
</div>
瀏覽器顯示:
優缺點相信不用贅述了。 這種方法只能設一個子元素。
水平垂直居中:(inline-block+text-align)+(table-cell+vertical-align)
這其實很好理解 inline-block
+text-align
是水平居中用的,able-cell
+vertical-align
是垂直居中用的。
對於單個元素的演示過於簡單,就不贅述了,下面展示下多個元素的水平垂直居中:
CSS:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.child1 {
display: inline-block;
background: lightcoral;
}
.parent {
display: table-cell;
vertical-align: middle;
background: lightgreen;
text-align: center;
width: 50rem;
height: 10rem;
}
</style>
html:
<div class="parent">
<div class="row">
<div class="child1">demo1</div>
<div class="child1">demo2</div>
<div class="child1">demo3</div>
</div>
<div class="row">
<div class="child1">demo1</div>
<div class="child1">demo2</div>
<div class="child1">demo3</div>
</div>
<div class="row">
<div class="child1">demo1</div>
<div class="child1">demo2</div>
<div class="child1">demo3</div>
</div>
</div>
瀏覽器顯示:
這裡有幾點需要注意的:
1. .row
這個元素只是起到換行的作用。
2. 當.parent
設定成 display:table-cell
的時候,width
進行百分比設定是沒有用的。 所以用rem
, 當然直接設px
也是可以的。
3. 可以看到同一行的.child1
中間是有空白的,可以通過對.child1
設定margin:0 -0.11rem
來清除,具體數值是調整出來的。
調整以後效果如下:
優點是相容性好,缺點就是需要設定負的margin值來抵消子元素之間的空白部分。
水平垂直居中:flex+flex-direction+justify-content+align-items
如果我們只需要單個元素水平垂直居中的話,下面這樣就可以了:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.parent {
display: flex;
justify-content: center;
align-items: center;
background: lightgreen;
width: 50%;
height: 10rem;
}
</style>
這個很簡單,參照之前flex
的水平居中和垂直居中就好了。
假如我們有多個子元素進行二維排列呢。請看下面:
CSS:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.child1 {
background: lightcoral;
}
.row {
display: flex;
}
.parent {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: lightgreen;
width: 50%;
height: 10rem;
}
</style>
html:
<div class="parent">
<div class="row">
<div class="child1">demo1</div>
<div class="child1">demo2</div>
<div class="child1">demo3</div>
</div>
<div class="row">
<div class="child1">demo1</div>
<div class="child1">demo2</div>
<div class="child1">demo3</div>
</div>
<div class="row">
<div class="child1">demo1</div>
<div class="child1">demo2</div>
<div class="child1">demo3</div>
</div>
</div>
瀏覽器顯示:
我們看到,和之前的佈局比起來有很多優點。
- 子元素緊緊挨在一起,不需要設定負的
margin
值去抵消空白部分。 - 父元素的
width
可以用百分比設定了。
這裡父元素首先設定了flex-direction:column
, 保證 .row
子元素是按照豎列排列。 同時兩個center
讓 .row
水平垂直居中。
如果不對 .row
子元素設定 display: flex
的話,那麼所有child1
元素都都將垂直排列,因為繼承了父元素設的排列方式。設定以後,則child1
預設是水平排列。
這樣使得所有child1
在.row
的分行中垂直水平居中。
多列布局之定寬+自適應:float + overflow
CSS:
<style>
html,
body {
height: 100%;
font-size: 16px
}
.left{
float:left;
width: 20%;
margin-right:5%;
background: lightblue;
}
.right {
overflow: hidden;
background:lightcoral;
}
.parent {
background: lightcyan;
}
</style>
html:
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>
瀏覽器顯示:
如果你不對.right
設定 overflow:hidden
結果顯示出來是這樣:
為什麼用了float
就要用overflow:hidden
?
因為這牽涉到BFC 概念, 下面的這篇文章我覺得是說得很簡潔明瞭的。
多列布局之定寬+自適應:float + margin
CSS:
<style>
html,
body {
height: 100%;