1、css中有哪些方式可以隐藏页面元素?区别是什么?
1.1 display:none
元素在页面上将彻底消失,元素本身占有的空间会被其他元素占有,导致浏览器的重排和重绘。
特点:元素不可见,不占据空间,不会触发点击事件。
1.2 visibility:hidden
元素会隐藏,DOM结果仍然存在,只是一个不可见的状态。不会触发重排,会触发重绘。
特点:元素不可见,占据页面空间,无法响应点击事件。
1.3 opacity:0
设置元素的透明度为0.不会触发重排,一般情况下会触发重绘。(如果利用animation动画,对opacity做变化【animation会默认触发GPU加速】,则只会触发GPU层面的composite,不会触发重绘。
特点:改变元素透明度,元素不可见,占据页面空间,可以响应点击事件。
1.4 设置height与width属性为0
将元素的marign、border、padding、height和width等影响元素盒模型的属性设置为0,如果元素内有子元素或内容,还应该设置其overflow:hidden来隐藏其子元素。
特点:元素不可见,不占据页面空间,无法响应点击事件。
1.5 position:absolute将元素移出可见区域
.hide{
position:absolute;
top:-9999px;
left:-9999px;
}
特点:元素不可见,不影响页面布局。
1.6 clip-path:通过裁剪的方式
.hide{
clip-path:polygon(0px 0px,0px 0px,0px 0px,0px 0px)
}
特点:元素不可见,占据页面空间,无法响应点击事件。
display:none | visibility:hidden | opacity:0 | |
页面中 | 不存在 | 存在 | 存在 |
重排 | 会 | 不会 | 不会 |
重绘 | 会 | 会 | 不一定 |
自身绑定事件 | 不会触发 | 不会触发 | 可触发 |
transition | 不支持 | 支持 | 支持 |
子元素可复原 | 不能 | 能 | 不能 |
被遮挡的元素可触发事件 | 能 | 能 | 不能 |
2、BFC(Block Formatting Context)
(1)定义和渲染规则
块级格式化上下文,是页面中的一块渲染区域,并且有一套属于自己的渲染规则(6个):
内部的盒子在垂直方向上会一个接一个排列。
同一个BFC上相邻两个盒子的margin会发生重叠,与方向无关。
每个元素的左外边距和包含块的左边界相接触(从左到右),即使浮动元素也是如此。
BFC的区域不会与float元素区域发生重叠
计算BFC的高度时,浮动子元素也参与计算。
BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
(2)触发条件
根元素,即HTML
浮动元素,即float值为left或right
overflow值不为visible,为auto、scroll、hidden
display的值为inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
position的值为absolute或fixed
(3)应用场景
防止内部坍塌、清除内部浮动、自适应多栏布局
防止margin重叠(塌陷):在同一级的一个中加div块
清除内部浮动:(父元素添加overflow:hidden样式)
.par {
border: 5px solid #fcc;
width: 300px;
}
.child {
border: 5px solid #f66;
width: 100px;
height: 100px;
float: left;
}
<div class="par">
<div class="child" />
<div class="child" />
</div>
而BFC在计算高度时,浮动元素也会参与,可以触发.par元素才能BFC,则内部浮动元素计算高度时也会计算:
.par{
overflow:hidden;
}
自适应多栏布局
例如:两栏布局:
.outter {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
}
<div class="outter">
<div class="aside" />
<div class="main" />
</div>
每个元素的左外边距与包含块的左边界相接触。因此,虽然.aside为浮动元素,但是.main的左边依然会与包含块的左边相接触。而BFC的区域不会与浮动盒子重叠,可以通过触发main生成BFC,以此适应两栏布局。
.main{
overflow:hidden;
}
3、元素居中的实现方式
(1)定位+marign:auto(不需要知道自身元素的宽高)
父级元素设置为相对定位,子级元素设置为绝对定位、定位属性值设置为0以及margin:auto
/* 水平垂直居中 */
.father {
width: 200px;
height: 200px;
background: skyblue;
position: relative;
/* relative元素相对于其正常位置进行定位。 */
}
.son {
width: 100px;
height: 100px;
background: red;
position: absolute;
/* absolute相对于最近的定位祖先元素进行定位 */
margin: auto;
/* 水平垂直都居中 */
top: 0;
right: 0;
bottom: 0;
left: 0;
}
<div class="father">
<div class="son" />
</div>
(2)定位+margin:负值(不要求知道父元素宽高,但需要知道子元素自身的宽高,负值为子元素宽度的一半)
父元素设置为相对定位,子元素设置绝对定位,移动自身50%实现水平垂直居中。
/* 水平垂直居中 */
.father {
width: 200px;
height: 200px;
background: skyblue;
position: relative;
/* relative元素相对于其正常位置进行定位。 */
}
.son {
width: 120px;
height: 120px;
background: red;
position: absolute;
left: 50%;
top: 50%;
margin-left: -60px;
margin-top: -60px;
}
初始位置为方块1的位置;当设置left、top为50%的时候,内部子元素为方块2的位置;设置margin为负数时,内部子元素即到方块3的位置,即中间位置。
这种方案不要求父元素的高度,即使父元素的高度变化了,仍然可以保持在父元素的垂直居中位置,水平方向上同理。
(3)定位+transform(不需要知道自身元素的宽高)
父元素设置为相对定位,子元素绝对定位且transform:translate(-50%,-50%)将元素位移自己宽高的-50%,等价于margin-left:-50px; margin-top:-50px;(-50px为自身元素的宽高一半)
/* 水平垂直居中 */
.father {
width: 300px;
height: 300px;
background: skyblue;
position: relative;
/* relative元素相对于其正常位置进行定位。 */
}
.son {
width: 120px;
height: 120px;
background: red;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
transform属性向元素应用2D或3D转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜。
(4)table布局
设置父元素display:table-cell、vertical-align:middle、text-align:center,子元素设置为display:inline-block
/* 水平垂直居中 */
.father {
width: 300px;
height: 300px;
background: skyblue;
display: table-cell;
/* 让标签元素以表格单元格的形式呈现,使元素类似于td标签。 */
vertical-align: middle;
text-align: center;
}
.son {
width: 120px;
height: 120px;
background: red;
display: inline-block;
}
(5)flex弹性布局(不需要知道自身元素的宽高)
父元素设置为display:flex; justify-content:center(垂直居中); align-items:center(水平居中);
/* 水平垂直居中 */
.father {
width: 200px;
height: 200px;
background: skyblue;
display: flex;
/* 水平居中 */
justify-content: center;
/* 垂直居中(定义在交叉轴上如何对齐) */
align-items: center;
}
.son {
width: 100px;
height: 100px;
background: red;
}
<div class="father">
<div class="son" />
</div>
(6)grid网格布局(不需要知道自身元素的宽高)
父元素设置display:grid; justify-content:center(垂直居中); align-items:center(水平居中);
/* 水平垂直居中 */
.father {
width: 200px;
height: 200px;
background: skyblue;
display: grid;
/* 水平居中 */
justify-content: center;
/* 垂直居中(定义在交叉轴上如何对齐) */
align-items: center;
}
.son {
width: 100px;
height: 100px;
background: red;
}
<div class="father">
<div class="son" />
</div>
总结:内联元素居中布局、块级元素居中布局
内联元素:
水平居中:
行内元素可设置:text-align:center;
flex布局设置父元素display:flex; justify-content:center;
垂直居中:
单行文本父元素确认高度:height===line-height
多行文本父元素确认高度:display:table-cell; vertical-align:middle
块级元素:
水平居中:
定宽:marign:0 auto; 绝对定位+left:50%+margin:负自身一半
垂直居中:
position:absolute设置left、top、margin-left、margin-top(定高)
display:table-cell;
transform:translate(x,y)
flex(不定高、不定宽)
grid(不定高、不定宽),兼容性相对较差
4、如何实现两栏布局,右侧自适应?三栏布局中间自适应呢?
(1)两栏布局
适用于内容上具有明显主次关系的网页,如左侧定宽右侧自适应
实现思路:
使用float左浮左边栏;右边模块使用margin-left撑出内容块做内容展示;为父级元素添加BFC,防止下方元素飞到上方内容。
.box{
overflow:hidden;
}
.left{
float:left;
width:200px;
background-color:gray;
height:400px;
}
.right{
margin-left:210px;
height:200px;
background-coloe:lightgray;
}
使用flex弹性布局
.box{
display:flex;
}
.left{
width:100px;
}
.right{
flex:1
}
注意flex容器的一个默认属性值:align-items:stretch;这个属性导致列等高的效果,为了让两个盒子高度自动,需要设置align-items: flex-start;
(2)三栏布局
按照左中右的顺序进行排列,通常中间列最宽,左右两列次之。
实现三栏布局中间自适应的布局方式有:
两边使用float,中间使用margin;两边使用absolute,中间使用margin;两边使用float和负margin; display:table属性;flex实现; grid实现