css中的常见知识点
本文总结下面试中常被问到的 css 问题。
BFC
盒模型中对一个元素设置css需要元素是block类型还是inline类型。BFC就是用来格式化块级(block)盒子,还有管理inline类型的盒子IFC,以及其他的FC。FC(Formatting Context)指页面中的一个渲染区域并且拥有一套渲染规则(决定了其他子元素如何定位以及与其他元素的相互关系和作用)。BFC即块级格式化上下文,指一个独立的块级渲染区域,只有Block-level Box参与,该区域拥有一套渲染规则来约束块级盒子的布局且与区域外部无关。
BFC的生成
css2.1中规定满足下列css声明之一的元素便会生成BFC:
- float的值不为none
- overflow的值不为visible
- display的值为inline-block、table-cell、table-caption(display为table也可以生成,但在于Table会默认生成一个匿名的table-cell)
- position的值为absolute或fixed
BFC的约束规则
浏览器对BFC区域的约束规则:
-
生成BFC元素的子元素会一个接一个的放置,垂直方向上它们的起点是一个包含块的顶部,两个相邻子元素之间垂直距离取决于元素margin特性。在BFC中相邻的块级元素外边距会折叠。
-
生成BFC元素的子元素中,每一个子元素的外边距和包含块的左边界相接触(对于从右到左的格式化右外边距和右边界相接触),除非这个子元素也创建了一个新的BFC(如它自身也是一个浮动元素)。
详细说明:
- 内部的Box会在垂直方向上一个接一个的放置
- 垂直方向上的距离由margin决定(属于同一个BFC的两个相邻Box的margin会发生重叠,与方向无关)
- 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此(说明BFC中的子元素不会超过它的包含块,而position为absolute的元素可以超过它的包含块边界)
- BFC的区域不会与float的元素区域重叠
- 计算BFC的高度时,浮动子元素也参与计算。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
类似css规则:
- Block元素会扩展到与父元素同宽,所有block元素会垂直排列
- 垂直方向上两个相邻div的margin会重叠,而水平方向可能不会
- 浮动元素会尽量往左上方(或右下方)
- 为父元素设置overflow:hidden或浮动父元素,则会包含浮动元素
BFC在布局中的应用
-
防止margin相互重叠
同一个BFC中两个相邻的Box才会发生重叠,与方向无关。阻止margin重叠只要将两个元素别放在一个BFC中即可(可以让相邻元素其中一个生成BFC),我们甚少看到水平方向的margin重叠,但可以设置writing-mode(文本水平或垂直排布以及块级元素中文本的行进方向)使其水平排列的时候可能会出现margin水平方向重叠,水平方向外边距合并 demo bfc 解决外边距合并 demo
-
浮动相关问题
为了使父元素包含子浮动元素,常见的方式是父元素设置overflow:hidden或浮动父元素。根本原因在于将父元素变为BFC,子浮动元素就会参与其高度计算(即不会产生高度塌陷问题),overflow:hidden与正常流最接近。bfc 解决高度塌陷 demo
-
多栏布局的一种方式
与浮动元素相邻的已生成BFC元素不能与浮动元素相互覆盖,可以实现多栏布局,demo
水平居中
-
文本、行内元素、行内块级元素:text-align(text-align只控制行内内容如何相对他的块父元素对齐)
简单快捷,容易理解,兼容性好,但只对行内内容有效,属性会继承影响到后代行内内容,当子元素宽度大于父元素宽度则无效。
-
单个块级元素:利用margin中auto,在margin有节余的同时如果左右margin设置了auto,将会均匀分配剩余空间。如果上下的margin设置了auto,其计算值为0。
缺点是必须定宽,并且值不能为auto,宽度要小于父元素(否则无效)。
-
多个块级元素:将块级元素display属性指定为行内或者行内块级形式,然后利用text-align控制行内块级元素来控制块级元素的水平居中。但块级元素改为inline-block换行、空格会产生元素间隔。
-
使用绝对定位:子元素绝对定位,父元素相对定位,top、right、bottom、left的值是相对于父元素尺寸的,
margin和transform是相对于自身尺寸,组合使用达到水平居中。可以将left设为50%(父元素宽度的一半),然后将子元素向右平移50%(自身宽度的一半)。不管是块级元素还是行内元素都可以实现,但是脱离了文档流。
-
任意个元素:flex,设置当前主轴的对齐方式为居中即
justify-content:center
对于水平居中首先应该考虑哪些元素有自带的居中效果,即考虑行内元素或者行内块级元素,一般都以text-align:center
,其次去考虑可不可以使用margin:0 auto
,还是不行的话可以使用绝对定位或者flex布局,移动端能用flex就用flex。
垂直居中
-
单行文本、行内元素、行内块级元素:line-height(与height等值)。line-height最终表现是通过inline box实现,无论inline box所占的高度是多少其占据的空间都是与文字内容公用水平中垂线。设置父元素中line-height等于height的值。缺点是只能作用于单行行内内容,并且需要知道高度的值。
-
多行文本、行内元素、行内块级元素:通过用span把所有文字包裹起来,设置display:inline-block将其转化为行内块级元素解决。
-
图片:可以在图片上设置vertical-align:middle(默认为基线对齐),然后在父元素中设置line-height与height相等,并设置font-size为0后才可以完全垂直居中。如果是块级元素也可同样设置,但需要对这个块级元素设置宽高,并
display:inline-block
使其具有行内特性。 -
position:父元素非 static,子元素绝对定位,top 为 50%,
margin-top 为 -50%或者transform:translateY(-50%)
-
flex:父元素
display:flex
,align-item:center
。
css 中可以继承的属性
- 字体:font、font-family、font-size、font-weight、font-style
- 文本:text-align、work-spacing、line-height、letter-spacing、color
- 元素可见性:visibility
- 光标属性:cursor
- box-sizing
css 作用域(选择器)权重
- 第一等:代表内联样式,如: style=””,权值为1000。
- 第二等:代表ID选择器,如:#content,权值为0100。
- 第三等:代表类,伪类和属性选择器,如.content,:hover,:not(否定选择器、条件选择器),权值为0010。
- 第四等:代表类型选择器和伪元素选择器,如div p,::before,权值为0001。
- 通配符、子选择器、相邻选择器等的。如*、>、+,权值为0000。
- 继承的样式没有权值。
权重是 256 进制数,1,0,0,0 > 0,99,99,99,也就是说从左往右逐个等级比较,前一等级相等才往后比,每一级都有自己的最大值(最大数目255),超出时就会应用其最大值(最大数目),超过255仍用最大值。
!important
的权重是正无穷(有界,可计算)。权重相同后面覆盖前面。
z-index 有什么属性会影响
设置元素的堆叠顺序。该属性设置一个定位元素沿 Z轴的位置,Z轴定义为垂直延伸到显示区的轴。如果为正数,则离用户更近,为负数则表示离用户更远。
层叠顺序表:(1-7,最底层-最外层)
形成层叠上下文环境的元素的背景与边框
拥有负 z-index 的子堆叠上下文元素 (负的越高越堆叠层级越低)
正常流式布局,非 inline-block,无 position 定位(static除外)的子元素
无 position 定位(static除外)的 float 浮动元素
正常流式布局,inline-block元素,无 position 定位(static除外)的子元素(包括 display:table 和display:inline )
拥有 z-index:0 的子堆叠上下文元素
拥有正 z-index: 的子堆叠上下文元素(正的越低越堆叠层级越低)
元素一旦成为定位元素,其z-index就会自动生效,此时其z-index
就是默认的auto
,也就是0级别,根据上面的层叠顺序表,就会覆盖inline
或block
或float
元素。
层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文,父元素的z-index
低于父元素另一个同级元素,子元素 z-index再高也没用。
面试题:如何防止父元素的z-index小但是子元素的z-index大?
position属性常用的取值和它们的基本行为
-
static
static是position属性的默认值,定位方式为静态文档流。
-
relative:对文档流位置偏移
-
absolute:根据第一个非 static 的父节点进行定位
-
fixed:根据 viewport 定位
-
sticky:static+fixed 的组合。粘性定位,需要配合 top、bottom、left、right 中的任意一种,只有达到指定的阈值才会被固定。
sticky 的兼容性问题处理的解决方案?
% 相对于什么
- font-size:把 font-size 设置为基于父元素的一个百分比值。
- line-height:基于当前字体尺寸的百分比行间距。
- width:正常文档流中和设置浮动的情况下,相对于父元素content-box的宽度;绝对定位时,相对于包含块padding-box的宽度。
- height:和width还是有一个明显的区别是当父元素width属性为auto时,子元素宽度仍然可以使用百分比设置。但是对于height,只要子元素还是在正常文档流当中的,如果父元素的height属性为auto,则子元素height设置为百分比会被忽略。规范中指出:如果包含块的高度没有显式指出(即高度由内容决定),并且该元素不是绝对定位,则计算值为auto。而auto*100/100=NaN。
- margin、padding:无论是垂直或水平方向,均是相对于父元素的宽度,正常文档流中和设置浮动的情况下,相对于父元素content-box的宽度;绝对定位时,相对于包含块padding-box的宽度。
- left、right、top、bottom: top,bottom设置百分比定位是按包含块padding-box的高度来计算的,同样left,right,设置百分比定位是按包含块padding-box的宽度来计算的。
padding-box、content-box、border-box:这三种都表示的是盒模型中盒子宽度的大小,从里向外依次增大,即 content-box < padding-box < border-box。box-sizing 只有 content-box、border-box、innitial、inherit、unset 几种,但本质上还是两种即 标准盒模型和IE盒模型。
sass、less 相较于 css 有哪些优点
1、Less:
是一种动态样式语言. 对CSS赋予了动态语言的特性,如变量、继承、运算、函数。
Less 既可以在客户端上运行 (支持IE 6+, Webkit, Firefox),也可在服务端运行。
2、Sass:
是一种动态样式语言,Sass语法属于缩排语法,
比css比多出好些功能(如变量、嵌套、运算,混入(Mixin)、继承、颜色处理,函数等),更容易阅读。
3、Sass与Scss是什么关系?
Sass的缩排语法,对于写惯css前端的web开发者来说很不直观,也不能将css代码加入到Sass里面,因此sass语法进行了改良,Sass 3就变成了Scss(sassy css)。与原来的语法兼容,只是用{}取代了原来的缩进。
共同点:
1、混入(Mixins)——class中的class;
2、参数混入——可以传递参数的class,就像函数一样;
3、嵌套规则——Class中嵌套class,从而减少重复的代码;
4、运算——CSS中用上数学;
5、颜色功能——可以编辑颜色;
6、名字空间(namespace)——分组样式,从而可以被调用;
7、作用域——局部修改样式;
8、JavaScript 赋值——在CSS中使用JavaScript表达式赋值。
不同:
- 用 Less 可以满足大多数场景的需求,但相比另外两者,基于 Less 开发类库会复杂得多,实现的代码会比较脏,能实现的功能也会受到 DSL 的制约。比 Stylus 语义更清晰、比 Sass 更接近 CSS 语法,使得刚刚转用 CSS 预编译的开发者能够更平滑地进行切换。Less 支持浏览器端编译。
- 当初 Sass 并不支持 SCSS 语法,使得转投 Sass 成本较高,后来引入支持 css 语法的 scss 。从功能上来说 Sass 大而全,语义明晰但是代码很容易显得累赘。主项目基于 Ruby 可能也是一部分人不选择它的理由
flex 布局(flexible box,弹性布局)常用属性
父元素上
- flex-direction:决定主轴方向(项目的排列方向)
- row(默认起点为水平左端)
- row-reverse(起点为水平右端)
- column(起点为垂直上沿)
- column-reverse(起点为垂直下沿)
- flex-wrap:一条轴线排不下如何换行
- nowrap(默认不换行)
- wrap(换行,第一行在上方)
- wrap-reverse(换行,第一行在下方)
- flex-flow:flex-direction 和 flex-wrap 的合并
- justify-content:项目在主轴上的对齐方式(默认情况下即水平方向的对齐方式)
- flex-start(默认左对齐)
- flex-end(右对齐)
- center(居中)
- space-between(两端对齐,项目之间间隔相等)
- space-around(每个项目两侧间隔相等,项目之间的间隔时项目与边框间隔的两倍)
- align-items:项目在交叉轴上如何对齐(默认情况下即垂直方向上的对齐方式)
- flex-start (交叉轴起点对齐)
- flex-end(交叉轴终点对齐)
- center(交叉轴中点对齐)
- baseline(项目第一行文字的基线对齐)
- stretch(默认项目未设置高度或者 auto 时将会占满整个容器的高度)
- align-content:多根轴线的对齐方式
- flex-start(与交叉轴起点对齐)
- flex-end(与交叉轴终点对齐)
- center(与交叉轴中点对齐)
- space-between(与交叉轴两端对齐,轴线之间的间隔平均分布)
- space-around(每根轴线两侧间隔相等)
- stretch(轴线占满整个交叉轴)
子元素
-
order:项目的排列顺序,数值越小排列越靠前
-
flex-grow:项目的放大比例,默认0
-
flex-shrink:项目的缩小比例,默认1
-
flex-basis:项目占据主轴的空间(同 width、height),默认为 auto(项目本来大小),另外还可设置为 content、长度或百分比值。auto 时查看当前项有无设置宽度,如果有则使用该宽度,否则以包含的内容决定宽度;content 一律以内容决定宽度;百分比则是相对于容器而言,如果包含块注尺寸未定义,则计算结果和 auto 一样。
-
flex:flex-grow、flex-shrink、flex-basis 的合并简写
- 可以赋值为三个值
- 可以赋值为 auto,表示 flex-grow、flex-shrink 均为 1,flex-basis 为 auto
- 可以赋值为 none,表示 flex-grow、flex-shrink 均为 0,flex-basis 为 auto
- 可以赋值为非负数,该数字表示 flex-grow,flex-shrink ,flex-basis 取 0%
- 可以赋值为一个长度(px)或百分比,该数字表示 flex-basis,flex-grow 与 flex-shrink 取 1
- 可以赋值为两个非负数,分别表示 flex-grow 与 flex-shrink,flex-basis 取 0%
- 可以赋值为一个非负数和一个长度(px)或百分比,分别设为 flex-grow 与 flex-basis 的值,flex-shrink 取 1。
举一个不同的值之间的区别:
<div class="parent"> <div class="item-1"></div> <div class="item-2"></div> <div class="item-3"></div> </div> <style type="text/css"> .parent { display: flex; width: 600px; } .parent > div { height: 100px; } .item-1 { width: 140px; flex: 2 1 0%; background: blue; } .item-2 { width: 100px; flex: 2 1 auto; background: darkblue; } .item-3 { flex: 1 1 200px; background: lightblue; } </style>
主轴上父容器总尺寸为 600px; 子元素的总基准值是:0% + auto + 200px = 300px,其中
- 0% 即 0 宽度 - auto 对应取主尺寸即 100px
故剩余空间为 600px - 300px = 300px
伸缩放大系数之和为: 2 + 2 + 1 = 5
剩余空间分配如下:- item-1 和 item-2 各分配 2/5,各得 120px - item-3 分配 1/5,得 60px
各项目最终宽度为:
- item-1 = 0% + 120px = 120px - item-2 = auto + 120px = 220px - item-3 = 200px + 60px = 260px
- 当 item-1 基准值取 0% 的时候,是把该项目视为零尺寸的,故即便声明其尺寸为 140px,也并没有什么用,形同虚设
- 而 item-2 基准值取 auto 的时候,根据规则基准值使用值是主尺寸值即 100px,故这 100px 不会纳入剩余空间
-
align-self:允许单个项目有和其他项目不一样的对齐方式,可覆盖 align-items 属性,默认 auto(继承父元素 align-items,没有父元素等同与 stretch)
如何实现下划线
-
border -
text-decoration:underline
或给要加上下划线的部分用<u></u>
包裹,必须要有文本内容,否则不会显示下划线,而且只有文字部分有下划线 -
利用 css 伪类配合 scale 完成???
-
利用伪元素 after before:创建一个块元素,使其位于当前元素底部,并设定高宽和颜色
0.5px 的边框
安卓手机无法识别 0.5px 的 border:对于浮点型数据会进行四舍五入,这个时候采用的方法一般是通过
transform:scale(0.5)
将其缩小一半,可以是普通的boder: 1px solid
,或者通过伪元素,设置width: 200%; height: 1px
计数器实现目录结构
css counter-reset定义一个计数器后面跟一个名字,这个属性在哪个元素上设置则标示遇到这个元素我就重新开始计数。
<div class="list2">
<ul>
<li>gdfg
<ul>
<li>content</li>
<li>content</li>
<li>content</li>
</ul>
</li>
<li>dfs</li>
<li>sdaf
<ul>
<li>content</li>
<li>content</li>
<li>content</li>
</ul>
</li>
<li>dsfa</li>
<li>fsda</li>
</ul>
</div>
.list2{
padding: 10px;
border: 1px solid #ccc;
}
.list2 li{
list-style: none;
}
// 遇到ul就重新计数(添加一个新的计数器,原计数器不受影响)。
.list2 ul{
counter-reset: xuhao;
}
// counters,第一参数接收计数器,第二参数指明新的计数值以什么字符链接在上一级计数值得后面
.list2 li::before{
counter-increment: xuhao;
content: counters(xuhao, ".") " ";
}
常用伪类伪元素
伪类:像类选择器一样给某个已存在的DOM元素添加额外样式,一个冒号隔开。常见伪类有:
-
link(鼠标点击之前)、active(鼠标点击时)、visited(鼠标点击后)、hover
-
:first-child
、:last-child
、nth-child(n/odd/even)
(n表示给第n个元素添加样式、odd 奇、even偶)nth-last-child
,传递参数为 n 时表示匹配属于其元素的第 n 个子元素(从最后一个子元素开始计数),使用公式 an+b,n为计数器(从0开始),也可以传递 odd 或 even 表示奇数个或偶数个
伪元素:给出一个虚拟元素,给这个虚拟元素添加样式,两个冒号隔开。常用伪元素:
::before
,::after
,content 属性必须设置,可以设置为空(伪元素不存在于 DOM 但可以添加内容原因)。
高度、宽度
获取元素的大小和相对于视口的位置:Element.getBoundingClientRect()
设置页面元素显隐
-
display:none
脱离文档流,如果重新显示需要回流。
修改其中子元素 display 属性不会重新显示出来
元素上面添加的 click 事件不会触发
-
opacity:0
占据原来位置,不会进行回流,可能会进行重绘。因为具有 transition 或 animation 的 opacity 元素,渲染层被提升为合成层,translateZ(0) 或 translate3d(0,0,0) 可以认为强制创建合成层。元素提升为合成层后,transform 和 opacity 不会触发重绘,GPU可以改变之前画好页面的透明值
修改其中子元素 opacity 属性不会重新显示出来
元素上面的 click 事件仍可以触发
-
visibility:hidden
占据原来位置,不会进行回流,会进行重绘
修改其中子元素 visibility 的值可以重新显示出来
元素上面的 click 事件不能触发
css 轮播图 实现思路
首先图片全部显示出来,排成一行,图片外包裹 div,绝对定位,white-space: nowrap
不换行,这个 div 外再包裹一层,overflow: hidden
。定时改变图片外包裹 div 的left值。
关于无限循环到最后一个元素时跳到第一个元素的动画方向问题:这里采用的解决方法在开头第一张图前加上最后一张图,在滚动到最后一个元素时,自动将动画效果去除并跳到开头第一张图前面的那张图,然后再开始循环。
写个小图标
- 三角箭头:首先三角形可以使用 css 的 border 来绘制,即设置四个方向的颜色,将三面设置为透明就可以显示出一个三角形。将一个有颜色的三角形和一个白色的三角形以一定间距叠加,就可以显示出一个箭头符号
- 圆形进度条:圆形加载可以先通过 border 构建一个圆形边框,边框上 1/4 部分有不同颜色,然后让这个圆形边框动起来,通过 animation 和 keyframes,keyframes 中 transform 从 rotate 0deg 到 360deg,设置一下动画循环次数 animation-iteration-count 为 infinite 让其无限旋转下去
link 和 @import 的区别
-
link属于XHTML标签,而@import完全是css提供的一种方式。link标签除了可以加载css外,还可以做很多其他的事情,比如定义RSS,定义rel连接属性等,@import只能加载CSS。
-
加载顺序的差别:当一个页面被夹在的时候(就是被浏览者浏览的时候),link引用的CSS会同时被加载,而@import引用的CSS会等到页面全部被下载完再加载。所以有时候浏览@import加载CSS的页面时会没有样式(就是闪烁),网速慢的时候还挺明显。
-
兼容性的差别。由于@import是CSS2.1提出的所以老的浏览器不支持,@import只有在IE5以上的才能识别,而link标签无此问题,完全兼容。
-
使用dom控制样式时的差别。当使用JavaScript控制dom去改变样式的时候,只能使用link标签,因为@import不是dom可以控制的(不支持)。
-
@import可以在css中再次引入其他样式表,比如创建一个主样式表,在主样式表中再引入其他的样式表
css 文本省略
text-overflow: ellipsis
多行文字,特定行截断
-
可以通过 -webkit-line-clamp 使文字不超过指定行,它需要和 display、-webkit-box-orient 和 overflow 结合使用:
display: -webkit-box;
必须结合的属性,将对象作为弹性伸缩盒子模型显示。-webkit-box-orient;
必须结合的属性,设置或检索伸缩盒对象的子元素的排列方式text-overflow: ellipsis;
可选属性,可以用来多行文本的情况下,用省略号“…”隐藏超出范围的文本。
缺点是兼容性(该属性是 webkit 私有属性,只支持 webkit 内核浏览器)、开发点击展开交互不是很方便(不知道是否有超出)
-
float 模拟实现:有个三个盒子 div,粉色盒子左浮动,浅蓝色盒子和黄色盒子右浮动,
- 当浅蓝色盒子的高度低于粉色盒子,黄色盒子仍会处于浅蓝色盒子右下方。
- 如果浅蓝色盒子文本过多,高度超过了粉色盒子,则黄色盒子不会停留在右下方,而是掉到了粉色盒子下。
高度优先级问题
max-height、min-height、height 同时使用
当 height、max-height 同时使用时,小的生效。
- max-height < height,元素高度 max-height
- height < max-height,元素高度 height
当 height、max-height、min-height 同时使用时,
- height > max-height > min-height,元素高度 max-height
- height > min-height > max-height,元素高度 min-height
- min-height > height > max-height,元素高度 min-height
css Module 与 css in js
css in js : 用 js 对象来封装 css 样式使用,作为行内样式插入
css Module: 使用一个独一无二的 class 名字,不会与其他选择器重名。通常对一个类名进行哈希编码,html 中在引入的时候以对象属性的方式引入,构建工具会进行编译处理
border 与 outline 的区别
- border 占用空间,outline 不占用空间,不影响元素的位置和尺寸
- border 适用于所有有形的 html 元素,outline 针对链接、表单控件等设计,如 input 元素自带 outline,在 focus 时显示 outline,在 blur 不显示。可以用 outline 来做悬停的动态效果,且没有 hover 添加 border 影响元素定位和大小。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律