CSS 面试题合集
文档流
文档流分为定位流、浮动流、普通流三种,普通流其实就是 FC(formating context)。
常见的FC有:BFC(块级格式化上下文)、IFC(行级格式化上下文),还有 GFC(网格布局格式化上下文)和 FFC(自适应格式化上下文)。
BFC可以理解为,满足某些特点的元素,对内部和外部元素会表现出一些特性。就像是拥有了某个开发者不能修改的CSS属性。
满足下列条件之一就可触发BFC
- 根元素,即HTML元素
- float的值不为none
- overflow的值不为visible
- display的值为inline-block、table-cell、table-caption
- position的值为absolute或fixed
BFC 布局规则:
- 内部的Box会在垂直方向,一个接一个地放置。
- Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC的区域不会与float box重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算BFC的高度时,浮动元素也参与计算
BFC 的具体应用:
- 上述规则第四条,float+BFC,可以实现两栏布局
- 上述规则第六条,BFC(float+float),父容器能完全包含子元素
- 上述规则第二条,BFC+BFC不会发生margin重叠
- 上面的三个应用,其实都体现了上述规则第五条
link 和 @import
两者都是外部引用 CSS 的方式,但是存在一定的区别:
- link是XHTML标签,除了能够加载CSS外的其他类型;而@import只可以加载CSS。
- link引用CSS时,在页面载入时同时加载;@import需要页面完全载入以后再加载。
- link是XHTML标签,无兼容问题;@import则是在CSS2.1提出的,低版本的浏览器不支持。
- link支持使用Javascript控制DOM改变样式;而@import不支持。
选择器
- id选择器( #myid)
- 类选择器(.myclassname)
- 标签选择器(div, h1, p)
- 相邻选择器(h1 + p)
- 子选择器(ul > li)
- 后代选择器(li a)
- 通配符选择器( * )
- 属性选择器(a[rel = "external"])
- 伪类选择器(a:hover, li:nth-child)
可继承的样式: font-size font-family color, UL LI DL DD DT;
不可继承的样式:border padding margin width height ;
不同权重的比较规则:
!important > id > class > tag
同权重的情况下
- 定义最近优先级更高:
style=""
><style>
>link
- 其中link方式载入的样式,最后载入的为准
p:first-of-type /*选择属于其父元素的首个 <p> 元素的每个 <p> 元素。*/
p:last-of-type /*选择属于其父元素的最后 <p> 元素的每个 <p> 元素。*/
p:only-of-type /*选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。*/
p:only-child /*选择属于其父元素的唯一子元素的每个 <p> 元素。*/
p:nth-child(2) /*选择属于其父元素的第二个子元素的每个 <p> 元素。*/
:after /*在元素之前添加内容,也可以用来做清除浮动。*/
:before /*在元素之后添加内容*/
:enabled
:disabled /*控制表单控件的禁用状态。*/
:checked /*单选框或复选框被选中。*/
元素布局
水平居中:给div设置一个宽度,然后添加margin:0 auto属性
div{
width:200px;
margin:0 auto;
}
水平+垂直居中(1):通过margin-left、margin-top设置为-half width/half height
div {
position: relative; /* 相对定位或绝对定位均可 */
width:500px;
height:300px;
top: 50%;
left: 50%;
margin: -150px 0 0 -250px; /* 外边距为自身宽高的一半 */
background-color: pink; /* 方便看效果 */
}
水平+垂直居中(2):未知容器宽高,使用transform: translate
div {
position: absolute; /* 相对定位或绝对定位均可 */
width:500px;
height:300px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: pink; /* 方便看效果 */
}
水平+垂直居中(3):flex
.container {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
}
.container div {
width: 100px;
height: 100px;
background-color: pink;
}
新增各种 CSS
选择器,比如 :not(.input)
圆角 border-radius:8px
多列布局 multi-column
阴影和反射 shadow\reflect
文字特效 text-shadow
文字渲染 text-decoration
线性渐变 gradient
旋转 transform
缩放,定位,倾斜,动画,多背景
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS
初始化往往会出现浏览器之间的页面显示差异。
当然,初始化样式会对SEO有一定的影响,但鱼和熊掌不可兼得,但力求影响最小的情况下初始化。
盒子模型包括content+padding+border+margin
标准盒子模型:宽度=内容的宽度(content
)即默认模型:content-box
低版本IE盒子模型:宽度=content+border+padding
即border-box
一般都设置为boxsizing:border-box;
CSS3
弹性盒(Flexible Box
或 flexbox
),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。设为 Flex
布局以后,子元素的float、clear
和vertical-align
属性将失效。
弹性盒子由弹性容器Flex container
和弹性子元素Flex item
组成。
弹性容器通过设置display
属性的值为flex
或inline-flex
将其定义为弹性容器。
属性 | 描述 | 取值 |
---|---|---|
flex-direction | 指定弹性容器中子元素排列方式 | row row-reverse column column-reverse |
flex-wrap | 设置弹性盒子的子元素超出父容器时是否换行 | nowrap wrap wrap-reverse |
flex-flow | flex-direction 属性和flex-wrap 属性的简写形式 | 默认为row nowrap |
justify-content | 设置弹性盒子元素在主轴(横轴)方向上的对齐方式 | flex-start flex-end center space-between space-around |
align-items | 设置弹性盒子元素在侧轴(纵轴)方向上的对齐方式 | flex-start flex-end center baseline stretch |
align-content | 属性定义了多根轴线的对齐方式 | flex-start flex-end center space-between space-around stretch |
设置在项目 item
上的属性
属性 | 描述 | 取值 |
---|---|---|
order | 属性定义项目的排列顺序,数值越小,排列越靠前 | 默认为0 |
flex-grow | 定义项目的放大比例 | 默认为0 (存在剩余空间,也不放大) |
flex-shrink | 定义了项目的缩小比例 | 默认为1 (如果空间不足,该项目将缩小) |
flex-basis | 定义了在分配多余空间之前,项目占据的主轴空间 | 默认值是auto |
flex | flex-grow 、flex-shrink 和flex-basis 的简写 | 默认值0 1 auto 后两个属性可选 |
align-self | 允许单个项目有与其他项目不一样的对齐方式,align-items | 默认值auto |
display: none
隐藏后的元素不占据任何空间
visibility: hidden
- 隐藏后的元素空间依旧保留
- 子元素会继承这个属性,重新给子元素设置
visibility:visible
,则子元素又会显示出来
什么要浮动,什么时候需要清除浮动,清除浮动都有哪些方法
使用浮动之后,父元素的高度会塌陷,变成 0,导致布局有问题,这个时候需要清除浮动。
.clear-fix:after {
display:block;
clear:both;
content:"";
visibility:hidden;
height:0
}
.clear-fix:after {
content: '';
display: table;
clear: both;
}
.triangle-up {
width: 0;
height: 0;
border-bottom: 50px solid red;
border-left: 50px solid #FFF;
border-right: 50px solid #FFF;
border-top: 50px solid #FFF;
}
.triangle-down {
width: 0;
height: 0;
border-bottom: 50px solid #FFF;
border-left: 50px solid #FFF;
border-right: 50px solid #FFF;
border-top: 50px solid red;
}
opacity
会影响到元素到background、color,并且被继承。下面例子中,背景色和字体(本来默认是黑色的),连同.child
,都是灰色的。
.opacity {
background: #000;
opacity:0.5;
}
<div class="opacity">
opacity parent
<div class="child">child</div>
</div>
rgba
被用于设置背景颜色,它不会影响color,不会被子继承。下面的例子中,背景色灰色,字体黑色,.chlid
全然不受影响,背景色是完完整整的红。
.rgba {
background-color: rgba(0,0,0, .5);
}
.rgba .child{
background: red;
}
<div class="rgba">
rgba parent
<div class="child">
child
</div>
</div>
注:图中 opacity 本是看不到的,能看见是因为用光标选中了文字区域。
tranform: scale()
opacity: 0;
display: none;
visibility: hidden;
width: 0;
height: 0;
<input type="hidden" name="看不见我">
能够更快速的编写代码 结构清晰,便于维护
文件切分、模块化、选择符嵌套、变量、运算、函数、Mixin
工程化
display: none
(不占空间,不能点击);场景,显示出原来这里不存在的结构
visibility: hidden
(占据空间,不能点击);场景:显示不会导致页面结构发生变动,不会撑开)
opacity: 0
(占据空间,可以点击);场景:可以跟transition
搭配做过渡效果
已知如下代码,如何修改才能让图片宽度为 300px
?注意下面代码不可修改。
<img src="1.jpg" style="width:480px!important;”>
<img src="1.jpg" style="width:480px!important; max-width: 300px">
<img src="1.jpg" style="width:480px!important; transform: scale(0.625, 1);" >
<img src="1.jpg" style="width:480px!important; width:300px!important;">
transform
2D transform变换方法
translate(x, y)
方法,根据左(X
轴)和顶部(Y
轴)位置给定的参数,从当前元素位置移动。x
, y
的值可以取正负,分别表示表示向不同的方向偏移。rotate(angle)
方法, 表示旋转angle
角度。angle
为正时,按顺时针角度旋转,为负值时,元素逆时针旋转。scale(x, y)
方法,表示元素在x
轴和y
轴上的缩放比例,参数大于1
时,元素放大,小于1
时,元素缩小。skew(x-angle,y-angle)
方法,用来对元素进行扭曲变行,第一个参数是水平方向扭曲角度,第二个参数是垂直方向扭曲角度。其中第二个参数是可选参数,如果没有设置第二个参数,那么Y
轴为0deg
matrix(n,n,n,n,n,n)
方法, 以一个含六值的变换矩阵的形式指定一个2D
变换,此属性值使用涉及到数学中的矩阵
transform-origin 属性
transform
的方法都是基于元素的中心来变换的,也就是元素变换的基点默认是元素的中心。
transition
transition
允许css
的属性值在一定的时间区间内平滑地过渡。这种效果可以在鼠标单击、获得焦点、被点击或对元素任何改变中触发,并圆滑地以动画效果改变CSS
的属性值。transition
属性的值包括以下四个:transition-property
: 指定对HTML
元素的哪个css
属性进行过渡渐变处理,这个属性可以是color、width、height
等各种标准的css
属性。transition-duration
:指定属性过渡的持续时间transition-timing-function
: 指定渐变的速度(linear, ease, ease-out, ease-in, ease-in-out
)等transition-delay
:指定延迟时间
animation
要使用animation
动画,先要熟悉一下keyframes
,Keyframes
的语法规则:命名是由”@keyframes
”开头,后面紧接着是这个“动画的名称”加上一对花括号“{}”,括号中就是一些不同时间段样式规则。不同关键帧是通过from
(相当于0%
)、to(相当于100%
)或百分比来表示(为了得到最佳的浏览器支持,建议使用百分比)animation-name
: 动画名称animation-duration
: 一个动画周期花费的时间animation-timing-function
: linear, ease, ease-out, ease-in, ease-in-out
等animation-delay
: 规定延时animation-iteration-count
: 动画播放次数animation-direction
: 是否在下一周期逆向播放 normal, reverse, alternate
等
区别:
Transform
:对元素进行变形;Transition
:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画。但只有两个关键贞。开始,结束。Animation
:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash
的补间动画。可以设置多个关键贞。
Transition
与Animation
:transition
需要触发一个事件 ,而animation
在不需要触发任何事件的情况下也可以显式的随着时间变化来改变元 素css
的属性值,从而达到一种动画的效果。
它的原因以及解决方法
元素被当成行内元素排版的时候,原来HTML
代码中的回车换行被转成一个空白符,在字体不为0
的情况下,空白符占据一定宽度,所以inline-block
的元素之间就出现了空隙。
解决方法:
1、给父级元素设置font-size: 0
;子元素设置相应的font-size
2、改变书写方式,元素间留白间距出现的原因就是标签段之间的空格,因此,去掉HTML
中的空格,自然间距就消失了
3、margin
负值
4、设置父元素,display:table
和word-spacing
viewport
指视口,浏览器上(或一个app
中的webview
)显示网页的区域。PC
端的视口是浏览器窗口区域,而移动端的则存在三个不同的视口:
layout viewport
:布局视口visual viewport
:视觉视口ideal viewport
:理想视口
layout viewport
布局视口:在PC
端的网页的layout viewport
即浏览器页面显示的整个区域,也可以理解成网页的绘制区域。而在移动端由于其屏幕较小,无法全部显示PC端页面的全部内容,所以默认情况下(不用<meta name="viewport">
去控制),移动端会指定一个大于其浏览器显示区域layout viewport
,一般是980px
;
visual viewport
视觉视口: visual viewport
,顾名思义指浏览器可视区域,即我们在移动端设备上看到的区域
ideal viewport
理想视口: 理想视口,即页面绘制区域可以完美适配设备宽度的视口大小,不需要出现滚动条即可正常查看网站的所有内容,且文字图片清晰,如所有iphone
的理想视口宽度都为320px
,安卓设备的理想视口有320px、360px
等等。
<meta name="viewport" content="width=width-device,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
width
: width
用来设置layout viewport
的宽度,即页面具体绘制区域的宽度,在不使用<meta>
进行控制视口时,以iphone
为例,其会设置视口宽度为980px
。
另外width
可设置为width-device
字符串,表示设置视口宽度为设备的ideal viewport
,如在iphone
上为320px
。
initial-scale
: 指页面初始的缩放值,其值可以通过如下公式进行计算
initial-scale = ideal viewport / visual viewport
A
元素垂直居中,A
元素距离屏幕左右各边各10px
,A
元素里的文字font—size:20px
,水平垂直居中,A
元素的高度始终是A
元素宽度的50%
<div class="box">
<div class="Abox">我是居中元素</div>
</div>
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
.box {
position: relative;
background: red;
width: 100%;
height: 100%;
}
.Abox {
position: absolute;
margin-left: 10px;
width: calc(100vw - 20px);
height: calc(50vw - 10px);
top: 50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
background: yellow;
}
首先要了解CSS
的图层的概念(Chrome
浏览器)
浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小,每个图层上有一个或多个节点。在渲染DOM
的时候,浏览器所做的工作实际上是:
1、计算需要被加载到节点上的样式结果(Recalculate style
--样式重计算)
2、为每个节点生成图形和位置(Layout
--回流和重布局)
3、将每个节点填充到图层中(Paint Setup
和Paint
--重绘)
4、组合图层到页面上(Composite Layers
--图层重组)
触发重布局的属性
盒子模型相关属性会触发重布局:
- width
- height
- padding
- margin
- display
- border-width
- border
- min-height
定位属性及浮动也会触发重布局:
- top
- bottom
- left
- right
- position
- float
- clear
改变节点内部文字结构也会触发重布局:
- text-align
- overflow-y
- font-weight
- overflow
- font-family
- line-height
- vertival-align
- white-space
- font-size
这么多常用属性都会触发重布局,可以看到,他们的特点就是可能修改整个节点的大小或位置,所以会触发重布局
触发重绘的属性
修改时只触发重绘的属性有:
- color
- border-style
- border-radius
- visibility
- text-decoration
- background
- background-image
- background-position
- background-repeat
- background-size
- outline-color
- outline
- outline-style
- outline-width
- box-shadow
opacity
不会触发重绘。translate
这个不会触发重布局。
这个是flex
布局的内容,其实就是一个边距的区别,按水平布局来说,space-between
在左右两侧没有边距,而space-around
在左右两侧会留下边距,垂直布局同理。
三栏布局
三栏布局是很常见的一种页面布局方式。左右固定,中间自适应。实现方式有很多种方法。
第一种:flex
<div class="container">
<div class="left">left</div>
<div class="main">main</div>
<div class="right">right</div>
</div>
.container{
display: flex;
}
.left{
flex-basis:200px;
background: green;
}
.main{
flex: 1;
background: red;
}
.right{
flex-basis:200px;
background: green;
}
第二种:position + margin
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
<div class="main">main</div>
</div>
body,html{
padding: 0;
margin: 0;
}
.left,.right{
position: absolute;
top: 0;
background: red;
}
.left{
left: 0;
width: 200px;
}
.right{
right: 0;
width: 200px;
}
.main{
margin: 0 200px ;
background: green;
}
第三种:float + margin
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
<div class="main">main</div>
</div>
body,html{
padding:0;
margin: 0;
}
.left{
float:left;
width:200px;
background:red;
}
.main{
margin:0 200px;
background: green;
}
.right{
float:right;
width:200px;
background:red;
}
.square {
width: 10vw;
height: 10vw;
background: red;
}
注:需要考虑兼容性
/* 单行: */
.cls {
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
/* 多行: */
.cls {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}
/* 兼容: */
p{position: relative; line-height: 20px; max-height: 40px;overflow: hidden;}
p::after{content: "..."; position: absolute; bottom: 0; right: 0; padding-left: 40px;
background: -webkit-linear-gradient(left, transparent, #fff 55%);
background: -o-linear-gradient(right, transparent, #fff 55%);
background: -moz-linear-gradient(right, transparent, #fff 55%);
background: linear-gradient(to right, transparent, #fff 55%);
<div class="box">
<div class="left">asdfads</div>
<div class="right">asdfasd<br>asdfad<br>adfasdfa<br>asfdas</div>
</div>
/* flex布局默认的align-items属性的值为stretch,所以默认是撑开的 */
.box {
display: flex;
}
.left,.right {
margin: 0 20px;
background: red;
}
/* table table-cell */
.box {
display: flex;
border-spacing: 20px;
}
.left,.right {
display: table-cell;
background: red;
}
section {
width:100%;
padding-bottom: 100%;
background: #333;
}
css
选择器匹配元素是逆向解析
- 因为所有样式规则可能数量很大,而且绝大多数不会匹配到当前的
DOM
元素(因为数量很大所以一般会建立规则索引树),所以有一个快速的方法来判断「这个selector
不匹配当前元素」就是极其重要的。 - 如果正向解析,例如「
div div p em」
,我们首先就要检查当前元素到html
的整条路径,找到最上层的div
,再往下找,如果遇到不匹配就必须回到最上层那个div
,往下再去匹配选择器中的第一个div
,回溯若干次才能确定匹配与否,效率很低。 - 逆向匹配则不同,如果当前的
DOM
元素是div
,而不是selector
最后的em
,那只要一步就能排除。只有在匹配时,才会不断向上找父节点进行验证。
viewport + rem
background-image
scale
border-image
box-shadow
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 网页如何加载、解析、渲染
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论