本文對應(yīng)github地址:https://github.com/956159241/TuJieQianDuan/ 前端面試CSS中。
在面試的過程中,經(jīng)常會(huì)被問到有關(guān)CSS的一個(gè)問題,那便是居中問題。

首先是如何進(jìn)行水平居中,然后如何進(jìn)行垂直居中,最后如何進(jìn)行水平垂直居中。
接下來,一個(gè)問題一個(gè)問題研究~
水平居中,是基于兩個(gè)或多個(gè)元素之間的位置關(guān)系??赡芤粋€(gè)父元素和一個(gè)子元素,可能一個(gè)父元素或多個(gè)子元素。
那么父元素和子元素可能存在哪些情況呢?
- 父元素為行內(nèi)元素,子元素為行內(nèi)元素
- 父元素為行內(nèi)元素,子元素為塊級元素
- 父元素為塊級元素,子元素為行內(nèi)元素
- 父元素為塊級元素,子元素為塊級元素
在設(shè)置水平居中的過程中,父元素或者子元素的寬度、高度,子元素單行/多行有時(shí)也需要考慮其中。
在研究水平居中/垂直居中之前,先把一些不需要考慮的特殊情況挑出來:
父元素為行內(nèi)元素,子元素為行內(nèi)元素(不存在居中問題)
由于父元素,子元素都是行內(nèi)元素。且行內(nèi)元素基本都是不可設(shè)置寬高的(除去替換元素),所以沒有居中的概念。
父元素為行內(nèi)元素,子元素為塊級元素
由于行內(nèi)元素包含塊級元素,導(dǎo)致行內(nèi)元素也獨(dú)占一行,可以使用在父元素內(nèi)添加text-align: center,但是不符合開發(fā)規(guī)范。
注意:不建議在行內(nèi)元素中嵌套塊元素,這樣不僅不符合開發(fā)規(guī)范,還會(huì)導(dǎo)致行內(nèi)元素也獨(dú)占一行。
水平居中
父元素為塊級元素,子元素為行內(nèi)元素
解決方案一:在父元素內(nèi)添加text-align: center。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
}
.parent1 {
background-color: white;
text-align: center;
}
.child1 {
background-color:red;
}
.parent2 {
background-color: blue;
text-align: center;
width: 300px;
}
.child2 { background-color: red; }
</style>
</head>
<body>
<div class="parent parent1">
<code class="child1">1class ClassName {}</code>
</div>
<div class="parent parent2">
<code class="child2">2class ClassName {}</code>
</div>
</body>
</html>

解決方案二: 在父元素添加display: flex; justify-content: center,子元素如果不希望高度擴(kuò)展,在子元素上設(shè)置子元素的高度。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
}
.parent1 {
background-color: white;
display: flex;
justify-content: center;
}
.child1 {
background-color:red;
height: 20px;
}
.parent2 {
background-color: blue;
display: flex;
justify-content: center;
width: 300px;
}
.child2 { background-color: red; height: 20px; }
</style>
</head>
<body>
<div class="parent parent1">
<code class="child1">1class ClassName {}</code>
</div>
<div class="parent parent2">
<code class="child2">2class ClassName {}</code>
</div>
</body>
</html>

父元素為塊級元素,子元素為塊級元素
解決方案一: 在父元素添加display: flex; justify-content: center,子元素如果不希望高度擴(kuò)展,在子元素上設(shè)置子元素的高度。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
}
.parent1 {
background-color: white;
display: flex;
justify-content: center;
}
.child1 {
background-color:red;
height: 20px;
}
.parent2 {
background-color: blue;
display: flex;
justify-content: center;
width: 300px;
}
.child2 { background-color: red; height: 20px; }
</style>
</head>
<body>
<div class="parent parent1">
<div class="child1">1class ClassName {}</div>
</div>
<div class="parent parent2">
<div class="child2">2class ClassName {}</div>
</div>
</body>
</html>

解決方案二: 如果子元素寬度固定,在子元素添加margin: 0 auto。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
}
.parent1 {
background-color: white;
}
.child1 {
background-color:red;
height: 20px;
width: 200px;
margin: 0 auto;
}
.parent2 {
background-color: blue;
}
.child2 { background-color: red; height: 20px; width: 30%; margin: 0 auto; }
</style>
</head>
<body>
<div class="parent parent1">
<div class="child1">1class ClassName {}</div>
</div>
<div class="parent parent2">
<div class="child2">2class ClassName {}</div>
</div>
</body>
</html>

方案三: 利用position進(jìn)行定位
父元素添加position: relative, 子元素添加position: absolute;transform: translateX(-50%);。如果不不適用transform: translateX(-50%);就不是真正意義上的居中顯示,而是從居中位置開始向后顯示,如下實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
}
.parent1 {
background-color: white;
position: relative;
}
.child1 {
background-color: red;
width: 30%;
position: absolute;
left: 50%;
}
.parent2 {
background-color: blue;
position: relative;
}
.child2 {
background-color: red;
width: 30%;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
</style>
</head>
<body>
<div class="parent parent1">
<div class="child1">1class ClassName {}</div>
</div>
<div class="parent parent2">
<div class="child2">2class ClassName {}</div>
</div>
</body>
</html>

垂直居中
父元素為塊級元素,子元素為行內(nèi)元素
子元素為單行時(shí),可以使用: line-height 為父元素的height,然后設(shè)置vertical-align:middel或者父元素設(shè)置: dispaly:table-cell;vertical-align: midde;
子元素為多行時(shí): 父元素設(shè)置: dispaly:table-cell;vertical-align: midde;
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
margin: 10px 0;
}
.parent1 {
background-color: white;
height: 100px;
}
.child1 {
background-color: red;
line-height: 100px;
vertiacl-align: middel;
}
.parent2 {
background-color: yellow;
width: 100px;
display: table-cell;
vertical-align: middle;
}
.child2 {
background-color: red;
}
.parent3 {
background-color: blue;
height: 100px;
display: table-cell;
vertical-align: middle;
}
.child3 {
background-color: red;
}
</style>
</head>
<body>
<div class="parent parent1">
<span class="child1">單行</span>
</div>
<div class="parent parent2">
<span class="child2">單行</span>
</div>
<div class="parent parent3">
<span class="child3">多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行多行</span>
</div>
</body>
</html>

父元素為塊級元素,子元素為塊級元素
方案一: position定位
方案二:table-cell
方案三: flex
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
margin: 10px 0;
}
/* 方案一: 絕對定位 */
.parent1 {
background-color: white;
height: 100px;
position: relative;
}
.child1 {
background-color: red;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* 方案二:table-cell */
.parent2 {
background-color: yellow;
width: 100px;
display: table-cell;
vertical-align: middle;
}
.child2 {
background-color: red;
}
/*方案三: flex */
.parent3 {
background-color: blue;
height: 100px;
display: flex;
align-items:center;
}
.child3 {
background-color: red;
}
</style>
</head>
<body>
<div class="parent parent1">
<div class="child1">內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容</div>
</div>
<div class="parent parent2">
<div class="child2">內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)</div>
</div>
<div class="parent parent3">
<div class="child3">內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)</div>
</div>
</body>
</html>

水平垂直居中
垂直水平居中就可以利用上面的方法進(jìn)行組合就好啦,下面推薦使用一些常見的方式:
方案一 flex
align-items:center;
方案二 position定位
方案三 grid
align-items: center;
justify-items:center;
place-items: center;
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
height: 80px;
margin: 10px;
margin: 10px 0;
}
/* 方案一: 絕對定位 */
.parent1 {
background-color: white;
height: 100px;
position: relative;
}
.child1 {
background-color: red;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 50%;
transform: translateX(-50%);
}
/* 方案二:flex */
.parent2 {
background-color: yellow;
display: flex;
align-items: center;
justify-content: center;
}
.child2 {
background-color: red;
}
/*方案三: gird 1 */
.parent3 {
background-color: blue;
display: grid;
align-items: center;
justify-items: center;
/* 或者簡寫: place-items: center; */
}
.child3 {
background-color: red;
}
</style>
</head>
<body>
<div class="parent parent1">
<div class="child1">內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容</div>
</div>
<div class="parent parent2">
<div class="child2">內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)</div>
</div>
<div class="parent parent3">
<div class="child3">內(nèi)容內(nèi)內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)</div>
</div>
</body>
</html>

參考網(wǎng)址:
https://zhuanlan.zhihu.com/p/83553320
https://blog.csdn.net/weixin_37580235/article/details/82317240