一、CSS盒模型:
盒模型即把html元素看作一个个小盒子,盒子里面还可以嵌套其他的盒子。盒模型分为两种:W3C盒模型和IE盒模型。
- W3C盒模型:属性width、height只包括内容content,不包括padding、border。
width = 内容的宽度
height = 内容的高度 - IE盒模型:属性width、height包括content、padding和border,是content+padding+border。
width = border + padding + 内容的宽度
height = border + padding + 内容的高度
在IE8+浏览器中,使用哪个盒模型可以由box-sizing
进行设置。默认值为content-box
,即W3C标准盒模型,还可设置为border-box
,即IE盒模型。注意要声明!DOCTYPE。
注意: 盒模型包括content、padding、border和margin,但是盒大小不包括margin,把margin算进去是盒子占据的位置,不是盒子大小。
二、怎么在高清屏上画一条0.5px的边?
像素即一个一个的单位色块,由rgba四个通道组成。
像素是有大小的,在相同大小的屏幕上,像素越小需要的像素点越多,像素点越密集,显示也就越细腻高清。
在macbook上,retina屏幕默认屏幕分辨率为设备实际分辨率的一半,即长宽方向将2px当作1px来用,此时就可以在高清屏上画出0.5px的边(也就是高清屏物理像素1px的边)。方法如下:
1. 直接将高度设置为0.5px:
此时由于不同浏览器对小数点的px有不同处理,不同浏览器表现差异较大。
<!DOCType html>
<html>
<head>
<meta charset="utf-8">
<style>
.hr {
width: 300px;
background-color: #000;
}
.hr.half-px {
height: 0.5px;
</style>
</head>
<body>
<p>0.5px</p>
<div class="hr half-px"></div>
</body>
</html>
2. 将高度设置为1px并进行缩放:
<!DOCType html>
<html>
<head>
<meta charset="utf-8">
<style>
.hr {
width: 300px;
background-color: #000;
}
.hr.half-px {
height: 1px;
transform:scaleY(0.5);
transform-origin:50% 100%;
</style>
</head>
<body>
<p>0.5px</p>
<div class="hr half-px"></div>
</body>
</html>
3. 利用box-shadow
垂直方向阴影设置为0.5px.
<!DOCType html>
<html>
<head>
<meta charset="utf-8">
<style>
.hr {
width: 300px;
background-color: #000;
}
.hr.half-px {
background:none;
height:1px;
box-shadow:0 0.5px 0 black;
</style>
</head>
<body>
<p>0.5px</p>
<div class="hr half-px"></div>
</body>
</html>
4. 利用渐变的方法
由于高清屏上用2px来表示1px,采用渐变时渐变角度从下往上,从白色#fff到黑色#000,所以只能下面的1px像素为#fff,上面为#000,由此达到画一半的目的。
<!DOCType html>
<html>
<head>
<meta charset="utf-8">
<style>
.hr {
width: 300px;
background-color: #000;
}
.hr.half-px {
background:linear-gradient(0deg,#fff,#000);
height:1px;
</style>
</head>
<body>
<p>0.5px</p>
<div class="hr half-px"></div>
</body>
</html>
5. 利用svg
6. 利用viewport
width=devide-width
即viewport
视窗宽度为设备宽度,initial-scale
即缩放比例。
如果把缩放比例设置为1,视窗宽度等于设备宽度,以iphone6为例,设备的物理竖屏宽度为750px,dpr=2,显示宽度为375px,此时viewport宽度即为375px,这时就需要使用前面的方法。
但如果将缩放比例设置为0.5,则viewport宽度就是原来的750px,那么此时1px就是1px,按正常画就行。
当设备dpr为3时,就需要将scale改为0.3333了。
<meta name="viewport" content="width=devide-width,initial-scale=0.5">
三、@import与link引入样式的区别
- 从属关系不同
link
是HTML标签,不仅仅可以导入样式表,@import
是CSS提供的语法,只能导入样式表。 - 加载顺序不同
页面加载时,link
引入的CSS与页面同时加载,@import
引入的CSS在页面加载完后才进行加载。 - 兼容性不同
@import
是CSS2.1后才有的语法,兼容性不好,link
不存在兼容性问题。 - DOM可控性不同
link
作为HTML标签可以通过JS操控DOM进行插入,由于DOM是基于文档的,@import
不能用DOM操控。
注意:link
与@import
的权重取决于代码加载顺序,后面的样式会覆盖前面的样式。
来源:https://juejin.cn/post/6844903581649207309
来源:https://blog.csdn.net/weixin_42864357/article/details/114687546
四、flex布局
flex布局即弹性盒布局。
flex出现以前,通常是采用display+float+position进行定位。以往进行布局时通常采用的方式为:
- 正常文档流,块级元素从上到下,行内元素从左到右
- float+clear
- relative定位+absolute定位
- 设置margin为负
- dispaly:inline-block
但操作麻烦,不够灵活。采用flex布局能够将布局变得简单灵活,实现自适应。
弹性盒布局包括:容器
(container,采用flex布局的父元素)、项目
(item,子元素)、容器中默认存在主轴
(main axis)、交叉轴
(cross axis)。`
在父元素采用flex布局时,子元素的float、clear、vertical-align都会失效。
容器的6个属性:
- flex-direction决定主轴的方向(即项目的排列方向)
flex-direction: row | row-reverse | column | column-reverse;
- flex-wrap 决定容器内项目是否可换行
flex-wrap: nowrap | wrap | wrap-reverse;
- flex-flow: flex-direction 和 flex-wrap 集合
flex-flow: flex-direction flex-wrap;
- justify-content:指定主轴方向项目的对齐方式
justify-content: flex-start | flex-end | center | space-between | space-around;
- align-items: 指定交叉轴上项目的对齐方式
align-items:flex-start | flex-end | center | baseline | stretch;
- align-content: 多根轴线指定对齐方式
align-content:flex-start | flex-end | center | space-between | space-around | stretch;
项目的6个属性:
- align-self: 指定项目和其他项目不一样的对齐方式
align-self: align-self: auto | flex-start | flex-end | center | baseline | stretch;
- order: 定义项目在容器中的排列顺序数值越小,排列越靠前,默认值为 0
order:0;
- flex-grow 指定项目放大比例默认为0,即如果存在剩余空间,也不放大;所有项目的flex-grow属性都为1,项目将平分剩余空间;有一个项目的flex-grow属性为4,其他项目都为1,则前者占据的剩余空间将比其他项多4倍。
flex-grow:1;
- flex-shrink 指定项目缩小比例默认为1,即如果空间不足,该项目将缩小;所有项目的flex-shrink属性都为1,都将等比例缩小;有一个项目的flex-shrink属性为0,其他项目都为1,前者不缩小。
flex-shrink:0
- flex-basis: 在分配多余空间前,指定项目占据的主轴空间。浏览器根据这个属性,计算主轴是否有多余空间,默认值为auto,即项目的本来大小。会使原来设置的height或者width失效。
flex-basis:300px
- flex是多个属性的连写。子容器是有弹性的,会自动填充剩余空间。
flex:flex-grow flex-shrink flex-basis;
常用简化写法
flex:1 —> flex:1 1 0%;
flex:3 —> flex:3 1 0%;
各属性设置优先级详见第三个链接。
来源:https://juejin.cn/post/6844904004728668168
来源:https://https://juejin.cn/post/6866914148387651592
来源:https://juejin.cn/post/6844903614280908807
五、animation、transition、transform、translate的区别
1. animation:
CSS3动画,对transition
的扩展,对时间轴的控制更强大。通过定义@(-webkit-)keyframe
定义动画名称及关键帧,然后设置animation
中相关属性来完成动画。
(-webkit-)animation: name duration timing-function delay iteration-count direction fill-mode play-state;
@(-webkit-)keyframes animationname {keyframes-selector {css-styles;}}
比transition
多了播放次数、是否轮流反向播放、不播放时元素样式、动画状态等。
可以定义循环播放的动画:用infinite
。
可以定义多个动画串联执行,定义多个@keyframe
,并在animation
中动画用逗号分开即可。
2. transition:
对CSS中的属性变化产生过渡动画。可以设置发生变化的属性或transform
,发生变化花费的时间,变化转速曲线,延迟时间。
transition: property duration timing-function delay;
各属性详细取值见链接1。
3. transform:
对元素的变形。包括scale
(缩放)、rotate
(旋转)、translate
(平移)、skew
(扭曲)、matrix
(矩阵变换)。可以用transition
或js来动态改变transform
的属性值来实现动画过渡。
transform: scale(1.2) rotate(30deg);
transform-origin转换基点:定义发生转换的中心点。
transform-origin: x-axis y-axis z-axis;
transform-style定义嵌套元素在二维还是三维空间呈现。
transform-style: flat|preserve-3d;
4. tanslate:
是transform中的一个属性,即平移。
区别:
- transform本身没有过渡动画效果,只有到达态。通过与transition、animation或JS定时器结合产生中间态及动画。
- transition定义CSS属性发生变化的过渡动画,需要触发变化才能执行,而animation在页面加载完成后就开始执行。
- transition每次只能执行一次,多次执行需要多次触发,animation可以规定动画执行次数。
- transition一次只能规定一个初始态和到达态,animation可通过设置关键帧设置多个中间态。
六、CSS动画与JS动画的区别
CSS3时补间动画,JS动画是逐帧动画
- 动画运行时,控制程度不同。JS是逐帧动画,可以在动画过程进行暂停、取消、终止等操作,CSS动画不能。
- JS动画运行在主线程上,但主线程上还需要运行其他JS脚本,如计算、交互、布局、样式等,可能出现线程阻塞,出现掉帧。CSS动画运行在composite层线程上,由composite线程自动生成。且浏览器会对CSS动画做出优化,会占用更少cpu资源。(css 动画通过GUI解析,js 动画需要经过j s 引擎代码解析,然后再进行 GUI 解析渲染??)
- JS大多情况下没有兼容性问题,CSS3有兼容性问题。
- 对于简单动画来说,CSS代码会更简单,JS会复杂一些,而对于复杂动画,CSS会变得冗长,JS更优。
来源:https://www.zhihu.com/question/63437509
来源:https://www.jianshu.com/p/8128014998dc
七、实现多行省略
- 利用
-webkit-line-clamp
,仅webkit内核浏览器支持:
div {
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 2; 设置多少行进行省略
}
- 利用绝对定位+前后伪元素。
文本框父元素通过设置line-height和max-height来间接设置显示行数,另外可以设置overflow为hidden。
定义前后两个伪元素,一个伪元素content为省略号,另一个为空,两者宽度高度相同。
带省略号的伪元素绝对定位在右下角,定义right与bottom距离,空元素定义right距离,bottom距离不设置。
这样当文字内容不超过最大高度时,文本框高度不断增大,该元素相当于随着文本框底部位置同步移动,超过最大高度时,该元素即溢出,不再遮挡省略号框。
八、display:none; visibility:hidden; opacity:0; 区别
display:none;
- DOM布局:会影响布局,
display
为none
时浏览器不渲染,不占据空间 - DOM事件监听:隐藏时不能进行DOM事件监听
- 性能:会引发重排,性能较差
- 继承:不会继承给子元素,因为子元素也不渲染
transition
:不支持display
visibility:hidden;
- DOM布局:隐藏时不影响布局,占据空间
- DOM事件监听:隐藏时不能进行DOM事件监听
- 性能:会引发重绘,性能较好
- 继承:会继承给子元素,但子元素能设置
visibility:visible;
来进行显示。 transition
:visible
会立即显示,hidden
会延时隐藏。
opacity:0;
- DOM布局:隐藏时不影响布局,占据空间
- DOM事件监听:隐藏时能进行DOM事件监听
- 性能:不引发重排重绘,提升为合成层,性能好
- 继承:会继承给子元素,子元素不能设置
opacity:1;
来显示。 transition
:能够延时显示各种透明度。
九、BFC
BFC
Block formatting context(块级格式化上下文),是一个独立的渲染区域,只有block-level box会参与。一个BFC中,元素的布局不受外界影响,也不影响外界。
box
box是css布局的对象和基本单位。box的类型由其元素类型和display属性决定。不同类型的box会参与不同的formatting context(格式化上下文)。
block-level box:display
为block、table、list-item
的元素,会参与block formatting context
inline-level box:display
为inline、inline-block、inline-table
的元素,会参与inline-formatting context
Formatting Context
是页面中的一块渲染区域,有自己的渲染方式,决定了其子元素如何定位,与其他元素的关系和相互作用。
BFC的布局规则:
- 内部的box会在垂直方向一个一个排列
- 属于同一个BFC的相邻box的margin会发生重叠
- 所有box的margin box的左边都与包含块的border box紧贴,即便存在浮动也是这样
- BFC不会与float box重叠
- BFC相当于一个隔离的容器,内部的元素不会影响到外部的元素,反之亦然
- 浮动元素高度也在BFC高度的计算范围内
创建BFC的方法
- 根元素(< html >)
float
不为none
display
为inline-block、table-cell、flex、table-caption、inline-flex
position
不为static
或relative
overflow
不为visible
BFC的作用
- 避免margin重叠
<!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>防止margin重叠</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
p {
color: #f55;
background: yellow;
width: 200px;
line-height: 100px;
text-align:center;
margin: 30px;
}
</style>
<body>
<p>看看我的 margin是多少</p>
<p>看看我的 margin是多少</p>
</body>
</html>
此时两个< p >的margin发生了重叠。
由: 属于同一个BFC的相邻box的margin会发生重叠。
这包括相邻元素、嵌套元素,当它们之间没有阻挡(如边框、非空内容、padding)时就会发生重叠。
我们将第二个元素设置为另一个BFC,用div包起来即可。
<!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>防止margin重叠</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
p {
color: #f55;
background: yellow;
width: 200px;
line-height: 100px;
text-align:center;
margin: 30px;
}
div{
overflow: hidden;
}
</style>
<body>
<p>看看我的 margin是多少</p>
<div>
<p>看看我的 margin是多少</p>
</div>
</body>
</html>
- 消除元素内部浮动
<!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>清除浮动</title>
</head>
<style>
.par {
border: 5px solid rgb(91, 243, 30);
width: 300px;
}
.child {
border: 5px solid rgb(233, 250, 84);
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
</html>
①当不给父节点设置高度,子节点设置浮动时,会发生高度坍塌,此时就要清除浮动。
由:浮动元素高度也在BFC高度的计算范围内
给父节点激活BFC即可,设置overflow: hidden
;
<!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>清除浮动</title>
</head>
<style>
.par {
border: 5px solid rgb(91, 243, 30);
width: 300px;
overflow: hidden;
}
.child {
border: 5px solid rgb(233, 250, 84);
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
</html>
②在container后加::after
伪元素,清除左右浮动来防止坍塌。
.container::after {
content: "";
display: block; /* 不能少 */
clear: left;
}
③在父元素后加块级元素并清除浮动。
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
<div style="clear: both;"></div>
</div>
- 不与浮动元素重叠,自适应两栏布局
在这里插入代码片<!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>
</head>
<style>
*{
margin: 0;
padding: 0;
}
body {
width: 100%;
position: relative;
}
.left {
width: 100px;
height: 150px;
float: left;
background: rgb(139, 214, 78);
text-align: center;
line-height: 150px;
font-size: 20px;
}
.right {
height: 300px;
background: rgb(170, 54, 236);
text-align: center;
line-height: 300px;
font-size: 40px;
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>
</html>
①由:所有box的margin box的左边都与包含块的border box紧贴,即便存在浮动也是这样。
两者再同一个BFC中,所以重合了。
且:BFC不会与float box重叠
我们设置overflow:hidden;
使得右边box成为BFC。
<!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>
</head>
<style>
*{
margin: 0;
padding: 0;
}
body {
width: 100%;
position: relative;
}
.left {
width: 100px;
height: 150px;
float: left;
background: rgb(139, 214, 78);
text-align: center;
line-height: 150px;
font-size: 20px;
}
.right {
overflow: hidden;
height: 300px;
background: rgb(170, 54, 236);
text-align: center;
line-height: 300px;
font-size: 40px;
}
</style>
<body>
<div class="left">LEFT</div>
<div class="right">RIGHT</div>
</body>
</html>
右边会自动适应宽度,形成自适应两栏布局。
②也可以通过clear:both;来清除浮动,但效果与BFC不同,元素会下移清除左右浮动。
总结:
BFC是页面上的隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
如:BFC外部存在浮动时,不该影响BFC内部布局,BFC变窄,不与浮动有重叠。
BFC内部有浮动时,不应该影响BFC外部布局,计算高度包括幅度元素。
来源:https://blog.csdn.net/sinat_36422236/article/details/88763187
十、外边距折叠
发生外边距折叠的情况:
- 相邻元素之间的外边距会发生折叠;
- 父元素和第一个子元素之间:当两者之间不存在边框、内边距、行内内容、BFC、清除浮动将两者
margin-top
分开; - 父元素和最后一个子元素之间:当两者之间不存在边框、内边距、行内内容、
height
、min-height
、max-height
将两者margin-bottom
分开;
采取的方法:
1、父元素添加边框
2、父元素添加padding
3、父子元素之间添加行内元素< span >
4、父子元素之间存在触发BFC的元素(插入一个display:flex;
的块级元素)
5、父元素触发BFC(overflow:auto;
)
一些规则:
1、两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值;(如父子元素上边距分别为10px和20px,结果会两者都是20px并齐)
2、两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值;
3、两个外边距一正一负时,折叠结果是两者的相加的和。
十一、清除浮动
//html
<div class="topDiv">
<div class="floatDiv">float left</div>
<div class="textDiv">...</div>
</div>
<div class="bottomDiv">...</div>
//CSS:
.topDiv {
width: 500px;
border: 2px solid black;
}
.floatDiv {
width: 100px;
height: 100px;
border: 2px dotted red;
color: red;
margin: 4px;
float: left;
}
.bottomDiv {
width: 500px;
height: 100px;
margin: 5px 0;
border: 2px dotted black;
}
.textDiv {
color: blue;
border: 2px solid blue;
}
- 浮动元素与
.textDiv
发生重叠,且影响其文字排版。 - 浮动元素超出了父元素范围,父元素高度坍塌,假如没有文字支撑,没有边框,父元素高度将变为0。
- 浮动元素对父元素的兄弟元素产生影响。
方案:
1、.texDiv
添加clear:both;
或clear:left
;
由于.textDiv在文档流中,顺便高度坍塌得到解决。
当两者位置互调时,会变成:
失败。
2、 在末尾加一个没有内容的块级元素,设置clear:both;
相当于还是添加一个块级元素来撑起高度,必须是块级元素,否则无法撑起。
3、利用伪元素(clearfix)
通过为元素清除浮动,为元素也必须是块级元素,也可以用table,table也是块级元素。
<div class="topDiv clearfix">
<div class="textDiv">...</div>
<div class="floatDiv">float left</div>
</div>
<div class="bottomDiv">...</div>
// 省略基本的样式
// 区别在这里
.clearfix:after {
content: '.';
height: 0;
display: block;
clear: both;
}
4、用overflow
父级元素触发BFC,可以解决高度坍塌。设为display:inlineblock;
也一样。
.topDiv {
width: 500px;
padding: 4px;
border: 2px solid black;
// 区别在这里
overflow: auto;
}