CSS&HTML面经专题
一、position定位
position:static | relative | absolute | fixed | center | page | sticky
默认值:static,
center、page、sticky是CSS3中新增加的值。
-
static
可以认为静态的,默认元素都是静态的定位,对象遵循常规流。此时4个定位偏移属性不会被应用,也就是使用left,right,bottom,top将不会生效。
-
relative
相对定位,对象遵循常规流,并且参照自身在常规流中的位置通过top,right,bottom,left这4个定位偏移属性进行偏移时不会影响常规流中的任何元素。
-
absolute
a、绝对定位,对象脱离常规流,此时偏移属性参照的是离自身最近的定位祖先元素,如果没有定位的祖先元素,则一直回溯到body元素。盒子的偏移位置不影响常规流中的任何元素,其margin不与其他任何margin折叠。
b、元素定位参考的是离自身最近的定位祖先元素,要满足两个条件,第一个是自己的祖先元素,可以是父元素也可以是父元素的父元素,一直找,如果没有则选择body为对照对象。第二个条件是要求祖先元素必须定位,通俗说就是position的属性值为非static都行。
-
fixed
固定定位,与absolute一致,但偏移定位是以窗口为参考。当出现滚动条时,对象不会随着滚动。
-
center
与absolute一致,但偏移定位是以定位祖先元素的中心点为参考。盒子在其包含容器垂直水平居中。(CSS3)
-
page
与absolute一致。元素在分页媒体或者区域块内,元素的包含块始终是初始包含块,否则取决于每个absolute模式。(CSS3)
-
sticky
对象在常态时遵循常规流。它就像是relative和fixed的合体,当在屏幕中时按常规流排版,当卷动到屏幕外时则表现如fixed。该属性的表现是现实中你见到的吸附效果。(CSS3)
二、盒子模型
1、标准盒模型
box-sizing: content-box /*默认值*/
2、怪异盒模型(IE盒模型)
box-sizing: border-box /*默认值*/
问题:两者哪个效率更高?
- 编码效率后者更高
- 渲染效率前者更高
- 因为后者的话它那个content部分要通过width和height去减padding和border
3、flex弹性盒模型

给一个盒子设置display:flex这个盒子就会变成弹性盒子,有两个轴,一个主轴一个交叉轴,常用属性:
flex-direction属性决定主轴的方向(即项目的排列方向)
flex-wrap属性定义,如果一条轴线排不下,如何换行。
flex-flow
justify-content属性定义了项目在主轴上的对齐方式

align-items属性定义项目在交叉轴上如何对齐

align-content
flexbox中的align-self
align-items在伸缩容器上使用它,伸缩容器内部所有的元素都一致地受制于align-items的值。
但是有些时候,我们希望伸缩容器内部某个元素在侧轴上的排列方式有所差异。此时就不能使用align-items,因为align-items作用于整体。
我们希望作用于部分。这就是align-self的发挥场地。
可取值:align-self: auto|stretch|center|flex-start|flex-end|baseline|initial|inherit;
4、columns盒模型(不常考,略)
三、盒子水平垂直居中方案
(回答问题的小技巧,比如这个盒子水平垂直居中的问题,可以从项目说起,说我在项目中就经常会遇到需要元素居中的问题,一开始我总用...后来学习了好用的弹性布局...再后来逛博客比如掘金啊什么的,看到了什么什么方法,觉得也挺好用好实现的...)
基本代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body{
height: 100%;
overflow: hidden;
}
.box{
box-sizing: border-box;
width: 100px;
height: 50px;
border: 1px solid #000;
background: brown;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
方案一:(定位的三种实现)
/* 定位1 */
/* 缺点,必须知道具体的宽高, 但很多时候都不是具体的宽高 */
body{
position: relative;
}
.box{
position: absolute;
top: 50%;
left: 50%;
margin-top: -25px;
margin-left: -50px;
}
/* 定位2 */
/* 缺点,盒子必须有宽高,不需要考虑具体宽高 */
body{
position: relative;
}
.box{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
/* 定位3 CSS3里的translate神器 */
/* 缺点,浏览器兼容性不好 */
body{
position: relative;
}
.box{
position: absolute;
top: 50%;
left: 50%;
transform:translate(-50%, -50%);
}
方案二(flex)
/*移动端常用
缺点:浏览器兼容性不好*/
body{
display: flex;
/* 主轴居中 */
justify-content: center;
/* 交叉轴居中 */
align-items: center;
}
方案三(JS)
获取当前屏幕的宽高,获取盒子的宽和高,(屏幕宽高-盒子宽高)/2
<style>
body{
position: relative;
}
.box{
position: absolute;
}
</style>
<script>
let HTML = document.documentElement,
winW = HTML.clientWidth,
winH = HTML.clientHeight,
boxW = box.offsetWidth,
boxH = box.offsetHeight;
box.style.position = "absoluteH";
box.style.left = (winW-boxW) / 2 + 'px';
box.style.top = (winH-boxH) / 2 + 'px';
</script>
方案四(盒子 变inline-block 转为文档属性使用)
/* 缺点,要求父级有固定宽高, 不能是百分比 */
body{
display: table-cell;
vertical-align: middle;
text-align: center;
/* 固定宽高 */
width: 500px;
height: 500px;
border: 1px solid #000;
}
.box{
display: inline-block;
}
水平居中
-
对于
行内元素:text-align: center; -
对于确定宽度width的块级元素:
-
width和margin实现。
margin: 0 auto; -
子元素绝对定位和
margin-left: -width/2, 前提是 父元素position: relative
- 对于宽度未知的块级元素
-
table标签配合margin左右auto实现水平居中。使用table标签(或直接将块级元素设值为display:table),再通过给该标签添加左右margin为auto。
-
inline-block实现水平居中方法。
display:inline-block和text-align:center实现水平居中。 -
绝对定位 +
transform,translateX可以移动本身元素的50%。 -
flex布局使用
justify-content:center
垂直居中
-
通过设置父容器
相对定位,子级设置绝对定位,标签通过margin实现自适应居中 -
弹性布局
flex:父级设置display: flex; 子级设置margin为auto实现自适应居中 -
父级设置相对定位,子级设置绝对定位,并且通过位移
transform实现 -
table布局,父级通过转换成表格形式,然后子级设置vertical-align实现。(需要注意的是:vertical-align: middle使用的前提条件是内联元素以及display值为table-cell的元素)。 -
flex方案:
align-items: center;
子Q:文字大小根据屏幕大小自适应
结合响应式rem那些
四、经典布局
1、两列布局——左边固定,右边自适应
flex属性
flex属性:是 flex-grow、flex-shrink、flex-basis三个属性的缩写。
(1)flex-grow:定义项目的的放大比例
- 默认为0,即使存在剩余空间,也不会放大;
- 所有项目的flex-grow为1:等分剩余空间(自动放大占位);
- flex-grow为n的项目,占据的空间(放大的比例)是flex-grow为1的n倍。
(2)flex-shrink:定义项目的缩小比例
- 默认为1,如果空间不足,该项目将缩小
- 所有项目的flex-shrink为1:当空间不足时,缩小的比例相同;
- flex-shrink为0:空间不足时,该项目不会缩小;
- flex-shrink为n的项目,空间不足时缩小的比例是flex-shrink为1的n倍。
(3)flex-basis: 定义在分配多余空间之前,项目占据的主轴空间(main size),浏览器根据此属性计算主轴是否有多余空间
- 默认值为auto,即项目原本大小;
- 设置后项目将占据固定空间。
flex: 1 相当于:
flex-grow:1自动放大占位flex-shrink:1如果空间不足,项目缩小flex-basis:0%
<style>
#flex-container {
display: flex; /* 采用 flex 布局 */
flex-direction: row; /* 按行排列 */
}
.box-left {
background: orange;
width: 500px;
}
.box-right {
background: blue;
flex: 1;
}
</style>
</head>
<body>
<div id="flex-container">
<div class="box-left">left</div>
<div class="box-right">right</div>
</div>
</body>
2、圣杯布局
(1) 浮动和负margin
<head>
<style>
html,body {
height: 100%;
/* 超出一屏隐藏 */
overflow: hidden;
}
.container{
height: 100%;
/*左右两边要设置200的宽度,所以这边padding左右留出200*/
padding: 0 200px;
}
.left,.right {
width: 200px;
min-height: 200px;
background: lightblue;
}
.center{
/* center其实是占满了container 留出padding之后的全部 */
width: 100%;
min-height: 400px;
background: lightsalmon;
}
.left,.right, .center {
/* 如果不加这个浮动,那么center,left,right这三个就会依次一行一行排下去 */
/* 加了浮动之后,由于center已经占满了第一行,所以left和right会在第二行依次排开 */
float: left;
}
.left{
margin-left: -100%;
position: relative;
left: -200px;
}
.right{
margin-right: -200px;
}
</style>
</head>
<body>
<!-- 圣杯布局 -->
<div class="container clearfix">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
(2) 使用CALC
(不推荐使用,兼容到IE9,一般来说禁止在css里使用表达式去算,因为渲染的很慢,影响性能,所以css里这种运算表达式尽量少写)
.center {
width: calc(100%-400px);
min-height: 400px;
background: #ffa07a;
}
(3) Flex布局
<head>
<style>
html, body {
overflow: hidden;
}
.container {
display: flex;
justify-content: space-between;
height: 100%;
}
.left, .right {
/* flex是个组合写法
第一个:放大的比例
第二个:缩小的比例
第三个: 在整个容器里占空间的大小 */
flex: 0 0 200px ;
height: 200px;
background: lightblue;
}
.center {
/* 这里写1的意思是把剩余空间全部占满 */
flex : 1;
min-height: 400px;
background: lightsalmon;
}
</style>
</head>
<body>
<div class="container">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
</body>
</html>
(4) 定位
<head>
<style>
html, body {
height: 100%;
overflow: hidden;
}
.container {
position: relative;
height: 100%;
}
.left, .right {
position: absolute;
top: 0;
width: 200px;
min-height: 200px;
background: lightskyblue;
}
.left{
left: 0;
}
.right{
right: 0;
}
.center {
margin: 0 200px;
min-height: 400px;
background: lightsalmon;
}
</style>
</head>
<body>
<div class="container">
<div class="center"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
3、双飞翼布局
(1) 浮动和负margin
<head>
<style>
html,body{
height: 100%;
overflow: hidden;
}
.container, .left, .right {
/* 浮动,使container,left,right都并排排列 */
/* 但由于container占了百分之百了,所以只有container在第一行 */
/* left和right在第二行 */
float: left;
}
.container {
width: 100%;
}
.container .center {
margin: 0 200px;
min-height: 400px;
background: lightsalmon;
}
.left, .right {
width: 200px;
min-height: 200px;
background: lightblue;
}
.left {
margin-left: -100%;
}
.right {
margin-left: -200px;
}
</style>
</head>
<body>
<!--container2里面只包含中间部分,两边翅膀脱离container-->
<div class="container">
<div class="center"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</body>
</html>
4、品字布局
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>品字布局</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
div {
margin: auto 0;
width: 100px;
height: 100px;
background: red;
font-size: 40px;
line-height: 100px;
color: #fff;
text-align: center;
}
.div1 {
margin: 100px auto 0;
}
.div2 {
margin-left: 50%;
background: green;
float: left;
transform: translateX(-100%);
}
.div3 {
background: blue;
float: left;
transform: translateX(-100%);
}
</style>
</head>
<body>
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>品字布局</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100%;
height: 100px;
background: red;
font-size: 40px;
line-height: 100px;
color: #fff;
text-align: center;
}
.div1 {
margin: 0 auto 0;
}
.div2 {
background: green;
float: left;
width: 50%;
}
.div3 {
background: blue;
float: left;
width: 50%;
}
</style>
</head>
<body>
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
</body>
</html>
5、布局题:div垂直居中,左右10px,高度始终为宽度一半
子题目:(较简单)纯CSS实现一个长宽比始终为2:1的长方形。
问题描述: 实现一个div垂直居中, 其距离屏幕左右两边各10px, 其高度始终是宽度的50%。同时div中有一个文字A,文字需要水平垂直居中。
思路一:利用height:0; padding-bottom: 50%;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
html, body {
height: 100%;
width: 100%;
}
.outer_wrapper {
margin: 0 10px;
height: 100%;
/* flex布局让块垂直居中 */
display: flex;
align-items: center;
}
.inner_wrapper{
background: red;
position: relative;
width: 100%;
height: 0;
padding-bottom: 50%;
}
.box{
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
}
</style>
</head>
<body>
<div class="outer_wrapper">
<div class="inner_wrapper">
<div class="box">A</div>
</div>
</div>
</body>
</html>
强调两点:
-
padding-bottom究竟是相对于谁的?
答案是相对于
父元素的width值。那么对于这个out_wrapper的用意就很好理解了。 CSS呈流式布局,div默认宽度填满,即100%大小,给out_wrapper设置margin: 0 10px;相当于让左右分别减少了10px。
-
父元素相对定位,那绝对定位下的子元素宽高若设为百分比,是相对谁而言的?
相对于父元素的(content + padding)值, 注意不含border
延伸:如果子元素不是绝对定位,那宽高设为百分比是相对于父元素的宽高,标准盒模型下是content, IE盒模型是content+padding+border。
思路二: 利用calc和vw
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.wrapper {
position: relative;
width: 100%;
height: 100%;
}
.box {
margin-left: 10px;
/* vw是视口的宽度, 1vw代表1%的视口宽度 */
width: calc(100vw - 20px);
/* 宽度的一半 */
height: calc(50vw - 10px);
position: absolute;
background: red;
/* 下面两行让块垂直居中 */
top: 50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="box">A</div>
</div>
</body>
</html>
五、浮动布局,清除浮动
浮动布局简介:
当元素浮动以后可以向左或向右移动,直到它的外边缘碰到包含它的框或者另外一个浮动元素的边框为止。
元素浮动以后会脱离正常的文档流,所以文档的普通流中的框就变的好像不存在一样。
优点
-
只会影响它这个元素后面的元素
-
内容默认提升半层
-
默认宽由其中的内容决定,会换行排列
-
这样做的优点就是在图文混排的时候可以==很好的使文字环绕在图片周围==。
-
另外当元素浮动了起来之后,它有着块级元素的一些性质:例如可以设置宽高等。
但它与inline-block还是有一些区别的,第一个就是关于横向排序的时候,float可以设置方向而inline-block方向是固定的;还有一个就是inline-block在使用时,有时会有空白间隙的问题。
缺点
最明显的缺点就是浮动元素一旦脱离了文档流,就无法撑起父元素,会造成父级元素的高度塌陷。
清除浮动
-
额外添加一个标签
- 注:clear可选值:left right both
<div class="parent"> //添加额外标签并且添加clear属性 <div style="clear:both"></div> //也可以加一个br标签 </div> -
父级添加overflow属性,或者设置高度
缺点:如果有子元素想溢出,那么会受到影响。
<div class="parent" style="overflow:hidden"> //将父元素的overflow设置为hidden <div class="f"></div> </div> -
after伪类 : 推荐,是空标签的加强版,目前各大公司的做法。
<style> #box1{ width:200px; border:1px black solid; } #box2{ width:100px; height:200px; background:red; float:left; } .clear:after{ /* 设置添加子元素的内容是空 */ content:''; /* 设置添加的子元素的高度0 */ height: 0; /* 设置添加子元素看不见 */ visibility: hidden; /* 设置添加子元素为块级元素 */ display: block; clear:both; } </style> <body> <div id="box1" class="clear"> <div id="box2"></div> </div> aaaaaaa </body>
六、BFC
BFC定义
W3C对BFC的定义如下:浮动元素和绝对定位元素,非块级盒子的块级容器(例如inline-blocks, table-cells, 和table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(Block Fromatting Context, 即块级格式上下文)
触发条件
一个HTML元素要创建BFC,则满足下列的任意一个或多个条件即可:
下列方式会创建块格式化上下文:
- 根元素()
- 浮动元素(元素的float不是none)
- 绝对定位元素(元素的position为absolute或fixed)
- 行内块元素(元素的display为inline-block)
- 表格单元格(元素的display为table-cell, HTML表格单元格默认为该值)
- 表格标题(元素的display为table-caption,HTML表格标题默认为该值)
- 匿名表格单元格元素(元素的display为table、table-row、table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或inline-table)
- overflow 值不为 visible 的块元素 - 弹性元素 (display为flex 或 inline-flex元素的直接子元素)
- 网络元素(display 为 grid 或 inline-grid 元素的直接子元素)
BFC渲染规则
- BFC垂直方向边距重叠
- BFC的区域不会与浮动元素的box重叠
- BFC是一个独立的容器,外面的元素不会影响里面的元素
- 计算BFC高度的时候浮动元素也会参与计算
应用场景
(1) 避免外边距折叠
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
background-color: green;
overflow: hidden;
}
.inner {
background-color: lightblue;
margin: 10px 0;
}
</style>
</head>
<body>
<div class="container">
<div class="inner">1</div>
<div class="bfc">
<div class="inner">2</div>
</div>
<div class="inner">3</div>
</div>
</body>
</html>
这时边距是叠在一起的,只会取到10px
/*style 添加*/
.bfc{
overflow: hidden;
}
<div class="container">
<div class="inner">1</div>
<div class="bfc">
<div class="inner">2</div>
</div>
<div class="inner">3</div>
</div>
这时可以看到,边距不会叠在一起了,是正常的20px。
(2) 防止浮动导致父元素高度塌陷
现有如下页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
border: 10px solid red;
}
.inner {
background: #08BDEB;
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="inner"></div>
</div>
</body>
</html>
接下来将inner元素设为浮动:
.inner {
float: left;
background: #08BDEB;
height: 100px;
width: 100px;
}
但如果我们对父元素设置BFC后, 这样的问题就解决了:
.container {
border: 10px solid red;
overflow: hidden;
}
同时这也是清除浮动的一种方式。