盒模型详解+遗漏点
什么是css盒子模型
可以说,页面就是由一个个盒模型堆砌起来的,每个HTML元素都可以叫做盒模型,盒模型由外而内包括:边距(margin)、边框(border)、填充(padding)、内容(content)。它在页面中所占的实际宽度是margin + border + paddint + content 的宽度相加。
盒模型是有两种标准的,一个是标准模型,一个是IE模型
W3C盒子模型(标准盒模型)
IE盒模型(怪异盒模型)
标准盒模型与IE盒模型区别
-
标准模型中,盒模型的宽高只是内容(
content)的宽高, -
IE模型:在IE6/5的低版本IE中盒模型的宽高是内容(
content)+填充(padding)+边框(border)的总宽高,
css如何设置两种模型:(css3的属性 box-sizing)
通常情况下,在不设置box-sizing时,默认box-sizing:content-box;
-
标准模型:
box-sizing:content-box; -
IE模型:
box-sizing:border-box;
一些注意点
-
页面渲染时,
DOM元素所采用的布局模型。可通过BOX-SIZING进行设置 -
width和height:内容的宽度、高度(不是盒子的宽度、高度)。盒子的内容,显示文本和图像。 -
padding:内边距。 清除内容周围的区域,内边距是透明的。 -
border:边框。围绕在内边距和内容外的边框。 -
margin:外边距。清除边框外的区域,外边距是透明的。 -
根据 W3C 的规范,元素内容占据的空间是由
width属性设置的,而内容周围的padding和border值是另外计算的。但 IE5 和 6 在怪异模式中使用自己的非标准模型。这些浏览器的width属性不是内容的宽度,而是内容、内边距和边框的宽度的总和。 -
IE8 及更早IE版本不支持设置填充的宽度和边框的宽度属性。 解决IE8及更早版本不兼容问题可以在HTML页面声明
<!DOCTYPE html>即可。 假如不用doctype声明,那么各个浏览器会根据自己的标准去解析网页,即ie浏览器会采用ie盒子模型去解析盒子模型,而Chrome浏览器会采用标准w3c盒子模型解析盒子, -
使用
doctype声明,那么所有浏览器都会采用标准w3c盒子模型解析盒子,网页就能在各个浏览器统一显示。 -
在使用
doctype声明情况下,设置属性box-sizing:border-box就可以定义使用ie盒模型。盒子模型主要适用于块级元素 -
<body>标签也有margin:很多人以为<body>标签占据的是整个页面的全部区域,其实是错误的,正确的理解是这样的:整个网页最大的盒子是<document>,即浏览器。而<body>是<document>的儿子。浏览器给<body>默认的margin大小是8个像素,此时<body>占据了整个页面的一大部分区域,而不是全部区域。
BFC(块级格式化上下文)+常见布局方案
三种常见的布局方案方案:
- 普通流 (normal flow)
在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。
- 浮动 (float)
在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。
- 绝对定位 (absolute positioning)
在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定。
什么是BFC:
在解释什么是BFC之前,我们需要先知道Box、Formatting Context的概念。
Box:css布局的基本单位
Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。让我们看看有哪些盒子:
-
block-level box:display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context;
-
inline-level box:display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;
-
run-in box: css3 中才有, 这儿先不讲了。
Formatting Context
Formatting context 是 W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的 Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。
-
BFC是一个独立的布局环境,其中的元素布局是不受外界的影响,并且在一个BFC中,块盒与行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。
-
可以把 BFC 理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。
-
浮动元素和绝对定位元素,非块级盒子的块级容器(例如
inline-blocks``table-cells和table-captions),以及overflow值不为visiable的块级盒子,都会为他们的内容创建BFC(块级格式化上下文)。 -
BFC触发条件:
【1】根元素,即
HTML元素
【2】float的值不为none
【3】overflow的值不为visible(overflow的其他值:hidden、auto、scroll)
【4】display的值为inline-block、table-cell、table-caption、flow-root、flex或者inline-flex
【5】position的值为absolute或fixe
BFC布局规则:
1.内部的Box会在垂直方向,一个接一个地放置(不设置浮动,设置浮动那肯定是左右一行排列了)。
2.Box垂直方向的距离由margin决定。属于同一个BFC两个相邻Box的margin会发生重叠(正常的不设置浮动,两个块元素
margin重叠,仅仅是垂直方向,左右不是这个样子的),会发生外边距合并,指的是当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
3.每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。(不设置浮动,不设置左边距,块级子元素,一律靠左竖直向下排列,内联子元素一律从左向右排列,想想,正常写代码,都是这样,设置左浮动的靠近父元素的左边,设置右浮动,靠近父元素的右边。)
4.BFC的区域不会与float盒子重叠。BFC区域的子元素不受外面的影响,外面的也不受BFC区域里面的影响(这个挺重要的,设置的浮动的元素,脱离了文档流,正常的相邻的元素会跑到它下面(靠左)。设置成BFC,自己独成一块,不会跑到它下面,自己依然占一块。)
5.计算BFC的高度时,浮动元素也参与计算(就是子元素设置浮动,脱离文档流,父元素高度塌陷,给父元素设置BFC,那么父元素高度就不会忽略浮动的子元素,从而高度就不会塌陷,这样理解,好像是BFC又把脱离文档流的元素,又拉回来了,但保持了浮动的特点。)
BFC主要用途:
外边距折叠
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
</div>
.container {
background-color: red;
overflow: hidden;
}
p {
background-color: lightgreen;
margin: 10px 0;
}
在上图中,一个红盒子(div)包含着两个兄弟元素(p),一个BFC已经创建了出来。
理论上,两个p元素之间的外边距应当是二者外边距之和(20px)但实际上却是10px,这是外边距折叠(Collapsing Margins)的结果。
产生折叠的必备条件:margin必须是邻接的。
在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。
外边距折叠(外边距合并)的计算方式
-
1、两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
-
2、两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
-
3、两个外边距一正一负时,折叠结果是两者的相加的和。
利用BFC避免外边距折叠
<div class="container">
<p>Sibling 1</p>
<div class="container1">
<p>Sibling 2</p>
</div>
</div>
.container {
background-color: red;
overflow: hidden;
}
p {
background-color: lightgreen;
margin: 10px 0;
}
.container1{
overflow: hidden;
}
因为第一个和第二个P元素现在分属于不同的BFC,它们之间就不会发生外边距折叠了。
BFC清除浮动
- 浮动元素是会脱离文档流的(绝对定位元素会脱离文档流)。
- 如果一个没有高度或者
height是auto的容器的子元素是浮动元素,则该容器的高度是不会被撑开的。 - 我们通常会利用伪元素(
:after或者:before)来解决这个问题。 - BFC能包含浮动,也能解决容器高度不会被撑开的问题。
<div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
.container {
background-color: blue;
overflow: hidden; // 添加后才能实现BFC,才能包住浮动元素
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
未添加overflow: hidden
添加overflow: hidden
阻止元素被浮动元素覆盖
<div style="height: 100px;width: 100px;float: left;background: lightblue">
我是一个左浮动的元素 one
</div>
<div style="width: 200px; height: 200px;background: grey">
我是一个没有设置浮动,也没有触发 BFC,我想你这次只是生气时间久了一点,是的。
</div>
<div style="height: 100px;width: 100px;float: left;background: lightblue">
我是一个左浮动的元素 two
</div>
<div style="width: 200px; height: 200px;background: grey;overflow:hidden">
我是一个没有设置浮动,触发 BFC 元素,我想你这次只是生气时间久了一点,是的。
</div>
由于左侧块级元素发生了浮动,所以和右侧未发生浮动的块级元素不在同一层内,所以会发生div遮挡问题。可以给右侧元素添加 overflow: hidden触发BFC来解决遮挡问题。
清除浮动的九中方法-高度塌陷理解-伪元素使用
浮动的定义
使元素脱离文档流,按照指定方向发生移动,遇到父级边界或者相邻的浮动元素停了下来。
- 浮动的框可以左右移动,直到遇到另一个浮动框或者遇到它外边缘的包含框。
- 浮动框不属于文档流中的普通流,当元素浮动之后,不会影响块级元素的布局,只会影响内联元素布局
- 当包含框的高度小于浮动框的时候,此时就会出现“高度塌陷”。
为什么要清除浮动?
清除浮动主要是为了解决,父元素因为子级元素浮动引起的内部高度为0的问题。
当父元素不给高度的时候,内部元素不浮动时会撑开,而浮动的时候,父元素变成一条线。
-
clear:both:在左右两侧均不允许浮动元素。本质就是闭合浮动, 就是让父盒子闭合出口和入口,不让子盒子出来 -
clear:left | right | both | none | inherit:元素的某个方向上不能有浮动元素 -
如果我们清除了浮动,父元素自动检测子盒子最高的高度,然后与其同高。
高度塌陷
如果父元素只包含浮动元素,且父元素未设置高度和宽度的时候。那么它的高度就会塌缩为零
解决方法:
1.父级div定义伪类:after和zoom
原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
缺点:ie6-7不支持伪元素:after,使用zoom:1触发hasLayout
<div>
<div class="div1 clearfloat">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2">
div2
</div>
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
/*清除浮动代码*/
.clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
.clearfloat{zoom:1}
</style>
2.使用before和after双伪元素清除浮动
<div>
<div class="div1 clearfloat">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2">
div2
</div>
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;}
.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
/*清除浮动代码*/
.clearfloat:after, .clearfloat:before {content: ""; display: table;}
.clearfloat:after {clear: both;}
.clearfloat {*zoom: 1;}
</style>
3.在结尾处添加空div标签clear:both
原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
缺点:如果页面浮动布局多,就要增加很多空div,让人感觉很不爽,添加无意义标签,语义化差
<div class="div1">
<div class="left">Left</div>
<div class="right">Right</div>
<div class="clearfloat"></div>
</div>
<div class="div2">
div2
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red}
.div2{background:#800080;border:1px solid red;height:100px; }
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
/*清除浮动代码*/
.clearfloat{clear:both}
</style>
4.父级div定义height
原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题
缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题
建议:不推荐使用,只建议高度固定的布局时使用
<div class="div1">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2">
div2
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解决代码*/height:200px;}
.div2{background:#800080;border:1px solid red;height:100px; }
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
</style>
5.父级div定义overflow:hidden 通过触发BFC方式,实现清除浮动
内容增多的时候容易造成不会自动换行导致内容被隐藏掉,无法显示要溢出的元素
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
缺点:不能和position配合使用,因为超出的尺寸的会被隐藏
建议:只推荐没有使用position或对overflow:hidden理解比较深的朋友使用
<div class="div1">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2">
div2
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解决代码*/width:98%;overflow:hidden}
.div2{background:#800080;border:1px solid red;height:100px; width:98%}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
</style>
6.父级div定义overflow:auto
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:auto时,浏览器会自动检查浮动区域的高度
缺点:内部宽高超过父级div时,会出现滚动条。
建议:不推荐使用,如果你需要出现滚动条或者确保你的代码不会出现滚动条就使用吧。
<div class="div1">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2">
div2
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解决代码*/width:98%;overflow:auto}
.div2{background:#800080;border:1px solid red;height:100px; width:98%}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
</style>
7.父级div也一起浮动
原理:所有代码一起浮动,就变成了一个整体 优点:没有优点
缺点:会产生新的浮动问题。
建议:不推荐使用,只作了解。
<div class="div1">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2">
div2
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解决代码*/width:98%;float:left}
.div2{background:#800080;border:1px solid red;height:100px;width:98%;/*解决代码*/clear:both}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
</style>
8.父级div定义display:table
原理:将div属性变成表格 优点:没有优点
缺点:会产生新的未知问题
建议:不推荐使用,只作了解
<div class="div1">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
<div class="div2">
div2
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;/*解决代码*/width:98%;display:table;}
.div2{background:#800080;border:1px solid red;height:100px;width:98%;}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
</style>
9.结尾处加br标签clear:both
<div class="div1">
<div class="left">Left</div>
<div class="right">Right</div>
<br class="clearfloat"/>
</div>
<div class="div2">
div2
</div>
<style type="text/css">
.div1{background:#000080;border:1px solid red;zoom:1}
.div2{background:#800080;border:1px solid red;height:100px}
.left{float:left;width:20%;height:200px;background:#DDD}
.right{float:right;width:30%;height:80px;background:#DDD}
.clearfloat{clear:both}
</style>
css3弹性盒子模型-flex布局详解
弹性盒子是CSS3的一种新布局模式。
-
CSS3弹性盒(Flexible Box或flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。 -
引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。
-
弹性盒子由弹性容器(
Flex container)和弹性子元素(Flex item)组成。 -
弹性容器通过设置
display属性的值为flex或inline-flex将其定义为弹性容器。 -
弹性容器内包含了一个或多个弹性子元素。
-
设为
Flex布局以后,子元素的float、clear和vertical-align属性将失效。 -
flex容器有两根轴:水平主轴就是x轴(main axis)和竖直轴也是y轴(cross axis) -
采用
Flex布局的元素,被称为Flex容器(flex * container),简称“容器”。其所有子元素自动成为容器成员,成为Flex项目(Flex * item),简称“项目”。 -
注意:弹性容器外及弹性子元素内是正常渲染的。弹性盒子只定义了弹性子元素如何在弹性容器内布局。
用法详解:
flex-direction属性:决定主轴的方向(即项目的排列方向)
-
row(默认):主轴水平方向,起点在左端;
-
row-reverse:主轴水平方向,起点在右端;
-
column:主轴垂直方向,起点在上边沿;
-
column-reserve:主轴垂直方向,起点在下边沿。
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
flex-wrap属性:定义换行情况
默认情况下,项目都排列在一条轴线上,但有可能一条轴线排不下。
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap(默认):不换行;
wrap:换行,第一行在上方;
wrap-reverse:换行,第一行在下方。
flex-flow属性:flex-direction和flex-wrap的简写,默认row nowrap
.box{
flex-flow: <flex-direction> || <flex-wrap>;
}
justify-content属性:定义项目在主轴上的对齐方式。
对齐方式与轴的方向有关,本文中假设主轴从左到右。
.box {
justify-content: start | end | flex-start | flex-end | center | left | right | space-between | space-around | space-evenly | stretch | safe | unsafe | baseline | first baseline | last baseline;
}
align-items属性:定义在交叉轴上的对齐方式
对齐方式与交叉轴的方向有关,假设交叉轴从下到上。
.box{
align-items: flex-start | flex-end | center | baseline | stretch;
}
align-content属性:定义多根轴线的对齐方式
修改 flex-wrap 属性的行为,类似 align-items, 但不是设置子元素对齐,而是设置行对齐,如果项目只有一根轴线,该属性不起作用。所以,容器必须设置flex-wrap:···;
项目的属性:设置在项目上的属性也有6个。
order - flex-grow - flex-shrink - flex-basis - flex - align-self
order属性:定义项目的排列顺序。
数值越小,排列越靠前,默认为0,可以是负值。
.item {
order: <整数>;
}
flex-grow属性:定义项目的放大比例 设置或检索弹性盒子元素的扩展比率。
-
默认值为0,即如果空间有剩余,也不放大。可以是小数,按比例占据剩余空间。
-
若所有项目的
flex-grow的数值都相同,则等分剩余空间 -
若果有一个项目
flex-grow为2,其余都为1,则该项目占据剩余空间是其余的2倍
flex-shrink属性:定义项目的缩小比例
-
默认值都为1,即如果空间不足将等比例缩小。
-
如果有一个项目的值为0,其他项目为1,当空间不足时,该项目不缩小。
-
负值对该属性无效,容器不应该设置
flex-wrap。 -
flex元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据flex-shrink的值。 -
如果所有项目都为0,则当空间不足时,项目撑破容器而溢出。
flex-basis属性:定义在分配多余空间之前,项目占据的主轴空间。
-
默认值为
auto,浏览器根据此属性检查主轴是否有多余空间。 -
注意设置的
flex-basis是分配多余空间之前项目占据的主轴空间,如果空间不足则默认情况下该项目也会缩小。
flex属性是flex-grow,flex-shrink和flex-basis的简写
默认值为0 1 auto,第一个属性必须,后两个属性可选。
.item{
flex: none | [<flex-grow><flex-shrink><flex-basis>];
}
可以用 flex:auto 代替 flex: 1 1 auto;;
可以用 flex: none 代替 flex: 0 0 auto;
align-self: 在弹性子元素上使用。覆盖容器的 align-items 属性。
单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch
align-self: auto | flex-start | flex-end | center | baseline | stretch;
实用例子
flex-内容宽度等分
//css
.box {
display: flex;
}
.box div {
flex: 1;
border: 1px solid red;
}
//html
<div class="box">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
未知高宽上下左右居中
html,
body {
height: 100%
}
.main {
display: flex;
height: 100%;
justify-content: center;
align-items: center
}
.box {
width: 300px;
border: 1px solid red;
}
//html
<div class="main">
<div class="box">未知高度上下左右居中</div>
</div>
CSS实现水平垂直居中的1024种方式(史上最全)
效果图如下
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="../../jquery-1.7.2.min.js"></script>
</head>
<body>
<div style="display: flex">
<!--水平居中-->
<div style="width: 33%">
<!--行级元素:为该行级元素的父元素设置text-align:center配合line-height样式-->
<div style="width: 500px;height: 100px;line-height: 100px;border: 1px solid green;text-align:center;">
<span>水平居中行级元素</span>
</div>
<!--块级元素:为其自身设置margin:auto样式-->
<div style="width: 500px;height: 100px;border: 1px solid red;">
<div style="line-height: 100px;text-align: center;margin:auto;width: 200px;height: 100px;border: 1px solid gold">
水平居中块级元素
</div>
</div>
</div>
<!--垂直居中-->
<div style="width: 33%">
<!--方法一: display:table;此元素会作为块级表格来显示(类似 <table>),表格前后带有换行符.
display:table-cell;此元素会作为一个表格单元格显示(类似 <td> 和 <th>)-->
<div style="display: table;width: 500px;height: 200px;border: 1px solid red;">
<div style="display: table-cell;vertical-align: middle;text-align:center;">垂直居中方法一</div>
</div>
<!--方法二:利用flex布局使内部块级元素水平,垂直居中(display:flex;justify-content: center; align-items:center;)-->
<div style="display:flex;justify-content: center; align-items:center; width: 500px;height: 200px;border: 1px solid green;text-align:center;line-height:150px">
<div style="width: 150px;height: 150px;border: 1px solid gold">垂直居中方法二</div>
</div>
<!--方法三: 利用定位实现,父元素:position:relative; ,子元素:position: absolute;top:50%;left:50%;transform:translate(-50%,-50%);-->
<div style="position:relative; width: 500px;height: 200px;border: 1px solid red;">
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width: 150px;height: 150px;border: 1px solid gold;text-align:center;line-height:150px">
垂直居中方法三
</div>
</div>
<!--方法四: 绝对定位, left:50%,top: 50% + margin-left:-(自身宽度的一半),margin-top:-(自身高度的一半)-->
<!--缺点:要自己计算容器的宽高,万一容器的宽高改变还要修改css样式-->
<div style="position:relative; width: 500px;height: 200px;border: 1px solid red;">
<div style="position:absolute;top:50%;left:50%;margin-left: -75px;margin-top: -75px;
width: 150px;height: 150px;border: 1px solid gold;text-align:center;line-height:150px">
垂直居中方法四
</div>
</div>
</div>
<div style="width: 33%">
<!--方法五: 绝对定位,left: 0,right: 0, top: 0, bottom: 0 + margin:auto-->
<div style="position:relative; width: 500px;height: 200px;border: 1px solid red;">
<div style="position:absolute;top: 0;left: 0;right: 0;bottom: 0;margin: auto;
width: 150px;height: 150px;border: 1px solid gold;text-align:center;line-height:150px">
垂直居中方法五
</div>
</div>
<!--方法六: 固定定位position:fixed;并设置一个较大的z-index层叠属性值。-->
<div style="position:fixed;top: 50%;left: 50%;margin-left: -75px;margin-top: -75px;z-index: 999;
width: 150px;height: 150px;border: 1px solid red;text-align:center;line-height:150px">
垂直居中方法六
</div>
<!--方法七: Flex加margin:auto-->
<div style="display: flex;width: 500px;height: 200px;border: 1px solid red;">
<div style="margin: auto;width: 150px;height: 150px;border: 1px solid gold;text-align:center;line-height:150px">
垂直居中方法七
</div>
</div>
<!--方法八: absolute + calc 缺点:依赖calc的兼容性-->
<div style="position: relative;width: 500px;height: 200px;border: 1px solid red;">
<div style="position: absolute;top: calc(50% - 75px);left: calc(50% - 75px);width: 150px;height: 150px;border: 1px solid gold;text-align:center;line-height:150px;">
垂直居中方法八
</div>
</div>
<!--方法九: display: grid 缺点:代码量也很少,但兼容性不如flex,不推荐使用-->
<div style="display: grid;width: 500px;height: 200px;border: 1px solid red;">
<div style="align-self: center;justify-self: center;;width: 150px;height: 150px;border: 1px solid gold;text-align:center;line-height:150px;">
垂直居中方法九
</div>
</div>
</div>
</div>
</body>
</html>
优缺点 || 兼容性 总结
-
PC端有兼容性要求,宽高固定,推荐absolute + 负margin
-
PC端有兼容要求,宽高不固定,推荐css-table
-
PC端无兼容性要求,推荐flex
-
移动端推荐使用flex
| 方法 | 居中元素定宽高固定 | PC端兼容性 | 移动端兼容性 |
|---|---|---|---|
| absolute + 负margin | 是 | ie6+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
| absolute + margin auto | 是 | ie6+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
| absolute + calc | 是 | ie9+, chrome19+, firefox4+ | 安卓4.4+, iOS6+ |
| absolute + transform | 否 | ie9+, chrome4+, firefox3.5+ | 安卓3+, iOS6+ |
| table | 否 | ie6+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
| flex | 否 | ie10+, chrome4+, firefox2+ | 安卓2.3+, iOS6+ |
| grid | 否 | ie10+, chrome57+, firefox52+ | 安卓6+, iOS10.3+ |
CSS面试点五-css隐藏元素方法大全,visibility的collapse属性值详解