CSS(层叠样式表,Cascading Style Sheets)不是编程语言,而是用来描述 HTML 或 XML(包括如 SVG、MathML 或 XHTML 之类的 XML 分支语言)文档的表现与展示效果的样式表语言。CSS3是CSS的最新标准,是向后兼容(指的是老版本的功能和数据在新版本能完美运行,与向前兼容相反)的,CSS1/2 的特性在 CSS3 里也可以使用。
1 值与单位
所有的 CSS 声明都包括一个 属性 / 值 对。由于属性不同,对应的值可能是一个单个整数或关键字,也可能是一串包含或不包含计数单位的数字和关键字的集合。
通常,支持四个方位的简写属性可以采用单值、两值、三值、四值语法,其中单值设置上下左右,两值设置上下、左右,三值设置上、左右、下,四值设置上、右、下、左。
初始值(initial value)、指定值 (specified value) 、计算值(computed value)、应用值(used value)、解析值(resolved value)、实际值(actual value):
初始值:CSS 属性的初始值是其默认值,即规范中其定义表中所列,注意,初始值不应与浏览器样式表指定的值混淆。初始值的使用取决于属性是否被继承:对于继承的属性,只要未提供指定值,初始值仅用于根元素。对于非继承属性,只要未提供指定值,所有元素都会使用初始值。可以使用 initial 关键字显式指定初始值。
浏览器执行四个步骤来计算一个属性的实际(最终)值。
- 首先,根据级联和层叠、继承或使用初始值的结果来确定指定值。
- 接下来,根据规范计算计算值。
- 然后,计算布局,产生应用值。
- 最后,根据本地环境的限制对应用的值进行转换,产生实际值。
CSS属性的指定值获取途径:
- 首先文档的样式表(用户代理样式表或页面作者样式表或用户自定义样式表)中给这个属性赋的值,通过样式层叠(选取样式表里权重最高的规则)后会被优先使用;
- 如果文档的样式表中没有给这个属性赋值,那么它会尝试从父元素那继承一个值;
- 如果上面的两种途径都不可行,则把 CSS 规范中针对这个元素的这个属性的初始值作为指定值。
CSS属性的计算值是在继承期间从父级传输到子级的值。通过以下方式从指定值计算得出的:
- 处理特殊值 inherit, initial, revert, revert-layer 和 unset;
- 执行所需的计算以达到属性定义表中"计算值"一行中所描述的值,而所需的计算通常涉及将相对值转换为绝对值(如 em 单位或百分比)。对于依赖布局的 CSS 属性百分比值或 auto 就是计算值:
- background-position
- bottom,left, right, top
- height, width
- margin-bottom, margin-left, margin-right, margin-top
- min-height, min-width
- padding-bottom, padding-left, padding-right, padding-top
- text-indent
此外,line-height 如果是没有单位的数字,该值就是它的计算值。
CSS 属性的应用值是对计算值执行所有计算后的值。
CSS 属性的解析值是 getComputedStyle 返回的值。对于于大多数属性,它是计算值;但对于一些旧属性(包括宽度和高度),它是应用值。
CSS 属性的实际值是在应用了任何必要的近似值之后该属性的应用值。例如,一个只能呈现整数像素宽度的边框的用户代理可以将边框的厚度四舍五入到最接近的整数。
2 定位
position属性用于指定一个元素在文档中的定位方式。top,right,bottom 和 left 属性则决定了该元素的最终位置。按定位类型将元素分为:
1. 非定位元素(non-positioned element)是其计算后 position 属性为 static(默认值):位于正常文档流位置,设置 top, right, bottom, left 和 z-index 属性无效;
2. 定位元素(positioned element)是计算后 position 属性为 relative、absolute、fixed、sticky 。
3. 相对定位元素(relatively positioned element)是计算后 position 属性为 relative:在不改变页面布局的前提下,top/right/bottom/left 属性指定了元素的上/右/下/左边界离开其正常位置的偏移(因此会在此元素未添加定位时所在位置留下空白),而且不影响其他元素的位置与自身的尺寸,该值对设置 table-*-group, table-row, table-column, table-cell, table-caption 的元素无效。同时,z-index 不为 auto 时会创建新的层叠上下文。
4. 绝对定位元素(absolutely positioned element)是计算后 position 属性为 absolute 或 fixed:元素会被移出正常文档流,并不为元素预留空间,top/right/bottom/left 属性指定了定位元素上/右/下/左外边距边界与其包含块上/右/下/左边界之间的偏移。fixed 或 absolute 会将 display 的计算值隐式的变为 block,为其内容建立一个新的块格式上下文,并且 fixed 会创建一个新的层叠上下文。absolute 元素 的 z-index 不为 auto 时会创建新的层叠上下文。
5. 粘性定位元素(stickily positioned element)是计算后位置属性为 sticky :它被视为相对定位,直到它的包含块在块格式上下文(或最近的滚动祖先即 overflow 为 hidden, scroll, auto, 或 overlay)中跨越指定的阈值时固定住,top/right/bottom/left 属性则用于计算粘性约束矩形,直到遇到包含块的相反边缘。其次,如果想相对视口固定生效,任何祖先的 overflow 要为默认值 visible。注意:同一个父容器中的 sticky 元素,如果定位值相等,则会重叠;如果属于不同父元素,且这些父元素正好紧密相连,则会挤开原来的元素,形成依次占位的效果。父级元素设置和粘性定位元素等高的固定 height 高度值,或者高度计算值和粘性定位元素高度一样,也没有粘滞效果。当最近的滚动祖先是视口时,粘性定位可以被认为是相对定位和固定定位的混合。sticky 会创建一个新的层叠上下文。
根据重绘内容的复杂性、浏览器性能和设备的处理速度,滚动包含 fixed 或 sticky 内容的元素时,浏览器可能无法管理 60 fps 的重绘,从而导致敏感人群的可访问性问题和所有人的卡顿。一个解决方案是添加 will-change: transform 到定位元素,以在其自己的层中渲染元素,提高重绘速度,从而提高性能和可访问性。
z-index 属性设定了一个定位元素及其后代元素或 flex 项目的 z 轴顺序。当元素之间重叠的时候,z-index 较大的元素会覆盖较小的元素在上层进行显示。z-index 为 auto 时,盒子不会建立新的局部层叠上下文。当前层叠上下文中默认生成的盒子的层叠级别是 0。z-index 为 <integer> 表示当前层叠上下文中生成的盒子的层叠级别,而且会建立新的本地层叠上下文,意味着后代的 z-index 不会与该元素之外的元素的 z-index 进行比较。
形成新的层叠上下文的方式:
修改:will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素。
inset 简写属性,对应于 top、right、bottom 和 left 属性。此属性虽然为 CSS 逻辑属性规范的一部分,但是无论元素的书写模式、行内方向和文本朝向如何,其所定义的都不是逻辑偏移而是实体偏移。inset 属性的取值与 left 属性相同。
3 盒模型
CSS 的盒模型存在外部显示类型和内部显示类型,由 display 属性设置。
其中外部显示类型(block,inline,inline-block)决定一个盒子是块级盒子(display: block)还是行内盒子(display: inline 和 inline-block)。
内部显示类型(比如flex,grid)则决定盒子内部是如何布局的,比如内部设置为弹性布局(display:flex)或网格布局(display:grid),而默认是按正常文档流布局即内部按块级和内联的默认行为布局。如果一个元素是浮动(float 不为 none)的、绝对定位(fixed 或 absolute)的或者是根元素(html),那么它就被称为流外(out of flow)即布局方式分别为浮动或绝对定位。如果一个元素不在流外,则称为流内(in-flow)即布局方式为正常流(normal flow),包括相对定位(relative)和粘性定位(sticky)。
CSS 视觉格式化模型(visual formatting model)根据 CSS 基础框盒模型(CSS basic box model)将文档树中的元素转换为零个或多个盒子(box),盒子会创建一个包含其后代元素的包含块,但是盒子内布局并不由包含块所限制,当盒子的内布局跑到包含块的外面时称为溢出(overflow)。每个盒子的布局由以下因素决定:
(1)盒子尺寸和类型(盒子类型由 display 属性决定);
(2)定位方案(正常流动、浮动和绝对定位);
(3)文档树中元素之间的关系;
(4)外部信息(例如,视口大小、图像的内在尺寸等)。
每个盒子都有一个内容 content 和可选的内边距 padding(隔离元素与内容)、边框 border 、外边距 margin(隔离元素),所能看到的元素显示区域是 content + padding + border。外边距总是在计算可见部分后额外添加,设置负值会导致和其他元素重叠。
基础盒模型分为标准盒模型(默认值,box-sizing: content,width/height 设置的是 content)和替代(IE)盒模型(box-sizing: border-box,width/height 设置的是 content + padding + border)。
给所有元素默认设置为替代盒模型:
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
获取盒模型或 DOM 宽高的方式:
(1)element.style.width/height:获取的是行内样式 style 属性上设置的盒模型宽高,行内样式没设置则为 ""。
(2)element.currentStyle.width/height:IE浏览器获取盒模型的宽高计算值。
(3)window.getComputedStyle(element).width/height:主流浏览器获取盒模型的宽高计算值。
(4)element.getBoundClientRect().width/height:主流浏览器获取 DOM 的显示宽高(border + padding + content)。
(5)element.clientWidth/clientHeight:主流浏览器获取 DOM 元素的视口宽高(padding + content - 滚动条)
正常文档流中,块的下外边距 (margin-bottom)和另一个块的上外边距 (margin-top)有时合并 (折叠) 为单个边距,其大小为单个边距的最大值 (或如果它们相等,则仅为其中一个),这种行为称为外边距折叠。因此设置 float 和 absolute 的元素不处于正常流中,因此不会产生外边距重叠行为。
多个设置 display: inline-block 或者 display: inline 的元素,它们之间会出现一个微小的空隙。原因默认情况下浏览器会将内联元素标签之间的空白符(空格、回车换行等)合并为一个空格字符处理。解决办法有:
/* 1.去掉内联元素之间的空格/换行:<a>元素1</a><a>元素2</a><a>元素3</a> */
/* 2.设置负 margin */
a {
margin-right: -4px;
}
/* 3.父元素使用弹性布局 */
.parent {
display: flex;
flex-direction: row;
}
/* 4.父元素设置 font-size: 0px; 子元素重新设置 font-size 为正常 */
.parent {
font-size: 0px;
}
.child {
font-size: 16px;
}
一个或多个 display: inline-block 或者 display: inline 的图片在垂直方向上也会出现空隙,原因是针对内联元素,默认是和父元素的 baseline 对齐,即 vertical-align: baseline; 而基线与父元素的下边缘是存在一定的距离的。解决办法是:
img {
/* 或 text-top 或 bottom 或 text-bottom 或 middle */
vertical-align: top;
}
min-width/min-height 和 max-width/max-height 属性分别为给定元素设置最小和最大宽度/高度。当达到这两者的临界值时(比如内容增加或减少,浏览器窗口尺寸改变),宽度或者高度都不再增加或者减少。当 min-height/min-width 大于 max-height/max-width 或 height/width 时,元素的高度会设置为 min-height/min-width 的值。当 max-height/max-width 的值 小于 height/width 时,元素的高度会设置为 max-height/max-width 的值。[min/max]-[width/height] 均不能为负值。min-width/min-height 和 max-width/max-height 初始值是 none,width/height 的初始值是 auto。常规流中,块级元素 width/height 为 auto 时,分别相当于 fill-available/fit-content。auto 高度计算时会忽略脱离正常文档流的元素。
margin 属性为给定元素设置所有四个(上下左右)方向的外边距,是 margin-top,margin-right,margin-bottom,和 margin-left 四个外边距属性设置的简写。取值可以是 <length> 或 <percentage> 或 auto。正常流中,auto 的 margin 总是会占据全部的多余的空间,但如果是 width 为 auto 的块级元素,以width占据剩余空间优先,即 auto 的 margin 计算值为 0。而在浮动元素上设置 margin 为 auto 时,margin 计算值为 0。在一个固定宽度的块上设置auto的左右margin可以使它在父元素内水平居中。
padding 属性为给定元素设置所有四个(上下左右)方向的内边距,是 padding-top,padding-right,padding-bottom,和 padding-left 四个外边距属性设置的简写。和 margin 不同,内边距不能为负值,且没有 auto。
outline属性是outline-style, outline-width 和 outline-color的简写属性。将 outline 设置为 0 或 none 会移除浏览器的默认聚焦样式,比如 input 元素。outline 和 border 语法相似,区别在于轮廓(outline)不占据空间,不会影响元素的尺寸,绘制于元素可见区域周围,因此可能与其他元素重叠,通常是矩形,但也可能是非矩形,而且不允许设置单边(border-top,border-right)。
元素的尺寸和位置的百分比的计算值是根据它的包含块计算得的:
- height,top,bottom 中的百分值,默认是通过包含块的 height 进行计算。但如果包含块的height 会根据它的内容变化(即为初始值 auto,没有指定值),而且包含块的 position 属性的值被赋予 relative 或 static,那么,这些百分比值失效,计算值变为 auto。
- width, left, right, padding, margin 这些属性由包含块的宽度来计算它的百分值。
包含块的确定完全依赖于position属性:
- 根元素 (<html>) 所在的包含块是一个被称为初始包含块的矩形。尺寸是视口 viewport (for continuous media) 或分页媒体 page media (for paged media)。
- 如果 position 属性是 static、relative 或 sticky,则包含块由最近的块容器(如 inline-block、block 或 list-item 元素)或具有块格式化上下文的祖先元素的内容区的边缘形成。
- 如果 position 属性为 absolute,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relative 或 sticky)的祖先元素的内边距区的边缘形成。
- 如果 position 属性是 fixed,在连续媒体的情况下 (continuous media) 包含块是 viewport,在分页媒体 (paged media) 下的情况下包含块是分页区域 (page area)。
- 如果 position 属性是 absolute 或 fixed,包含块也可能是满足条件之一的最近祖先元素的内边距区的边缘形成:
(1) transform 或 perspective 的值不是 none;
(2) will-change 的值是 transform 或 perspective;
(3) filter 的值不是 none 或 will-change 的值是 filter(只在 Firefox 下生效)。
(4) contain 的值是 paint;
(5) backdrop-filter 的值不是 none。
4 格式化上下文
页面上的所有内容都是格式上下文的一部分,或者是一个被定义为以特定方式(grid,multi-column,flex,table)布局内容的区域。格式化上下文可以分为块格式化上下文、行内格式化上下文和其他(比如弹性、网格等)格式化上下文。块格式化上下文(block formatting context,BFC)将根据块布局规则布置子元素,比如文档最外层元素是使用块布局规则的,称为初始块格式上下文;flex 格式化上下文将其子元素布置为 flex items 等。
块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素(计算 BFC 高度时内部的浮动元素才参与)与其他元素交互的区域。新 BFC 的行为与最外层文档(html)非常相似,因为它成为主布局内的子布局。BFC 包含其中的所有内容(因此,auto 的 height 会计算 BFC 内部的浮动),float 和 clear 仅适用于同一格式化上下文中的项目,并且外边距仅在同一格式化上下文中的元素之间折叠。块格式化上下文的创建方式(IE浏览器创建方式:zoom:1)与表现及应用:
如果采用浮动创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行,这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们对最后一列采用非浮动方式创建一个新 BFC,那么它将总是占据其他列先占位完毕后剩下的空间。
块级盒子参与块格式上下文,块级盒子会从包含块的顶部开始,按序垂直排列,每个盒子的左外边缘会与包含块左边缘重合(如果是从右到左的排版顺序,则盒子的右外边缘与包含块右边缘重合),相邻两个块级盒子之间的垂直间距会遵循外边距折叠原则被折叠。行内格式上下文(inline formatting context,IFC)存在于其他格式上下文中,行内盒子参与行内格式上下文,从包含块的顶部开始,按序水平排列。若是垂直书写模式,块级盒子按序水平排列,行内盒子按序垂直排列。块轴(block-axis)即是块级盒子排列的方向,行内轴(inline-axis)即是行内盒子排列的方向。
5 浮动
float 属性指定一个元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性(与绝对定位相反,即允许其他元素的文本(即匿名行盒)和行内级元素环绕它),然后向上向左(float:left)或者向上向右(float:right)平移,直到碰到了所处的包含块的边框,或者碰到同一行另外一个相同方向浮动的元素,或者碰到元素位置在前的正常流块盒(相反,位置靠后的正常流块盒会无视位置在前的浮动元素进行排列),行盒(包括匿名行盒)或其他 BFC 在排列时会避开浮动元素。浮动元素是 float 的计算值非 none 的元素。由于浮动意味着使用块格式上下文,某些情况下会修改 display 属性的计算值:
clear 属性指定一个元素是否必须移动到在它之前的浮动元素下面,适用于浮动和非浮动元素。当应用于非浮动块时,它将非浮动块的边框边界移动到所有相关浮动元素(即在相同块格式化上下文中的前置浮动)外边距的下方,这个非浮动块的顶部外边距会折叠,而两个浮动元素的垂直外边距将不会折叠。当应用于浮动元素时,它将元素的外边距边缘移动到所有相关的浮动元素(即在相同块格式化上下文中的前置浮动)外边距边缘的下方。这会影响后面浮动元素的布局,因为后面的浮动元素的位置无法高于它之前的元素。
如果一个元素只包含浮动子元素,它的高度就会崩溃为0。如果希望该元素的高度自适应包含所有浮动元素(非自适应的话,也可以给父元素显式指定高度),则需要给该元素添加 clearfix 类清除浮动:
/* 添加伪元素来清楚浮动 */
.clearfix::after {
content: '';
display: block;
height: 0px;
clear: both;
visibility: hidden;
}
/* 或者创建 BFC 清楚浮动 */
.clearfix {
/* chrome58+, Edge79+, Safari13+, Firefox53+, Opera45+, IE不支持 */
display: flow-root;
}
6 边框属性
border 属性是 border-width、border-style、border-color 简写属性。但 border 属性只接受三个参数,分别是宽度、风格和颜色,所以这样会使得四条边的边框相同。如果 border-style 未定义,它将不可见,这是因为样式默认为 none。border-color 的默认值是 color 属性的值。
border-image(CSS3)用于在元素的边框上绘制图像,它会替换掉 border-style 属性所设置的边框样式。border-image-slice 属性可以用四个指定的 <number-percentage> 值来表示每一个图像切片的位置。负数是无效的,而大于其相应的最大尺寸的值则会被限制为 100%。
特别注意,若 border-image-source 的值为 none 或者图片不能显示,则会降级为 border-style。
border-radius(CSS3)设置边框的圆角, 当使用一个半径时确定一个圆形圆角,当使用两个半径时(半长轴和半短轴)确定一个椭圆圆角。是 border-top-left-radius、border-top-right-radius、border-bottom-right-radius,和 border-bottom-left-radius 的简写属性。 当 border-collapse 的值为 collapse 时,border-radius 属性不会被应用到表格元素上。当使用百分比值的时候,水平半轴相对于盒模型的宽度;垂直半轴相对于盒模型的高度。border-radius: 50% 和 100% 的区别?W3C 规定如果两个相邻的角的半径和超过了对应的盒子的边的长度,那么浏览器要重新计算保证它们不会重合即同时缩放两个圆角的半径,直至两个相邻角的半径和为盒子的长度。
box-shadow(CSS3) 用于定义元素的阴影,可设置的值包括阴影扩散方向,阴影的 X 轴偏移量、Y 轴偏移量、模糊半径、扩散半径和颜色。偏移量 x 的正(负)对应于阴影出现在右(左)侧。偏移量 y 的正(负)对应于阴影出现在底(顶)侧,若使用 insert 关键字则刚好相反。
box-shadow 可以用来尝试处理移动端 1px 的问题(画 0.5px 的线):
.one-pixel {
-webkit-box-shadow: 0 1px 1px -1px rgb(0, 0, 0);
}
7 渐变(CSS3)
CSS 渐变由两种或多种颜色之间的渐进过渡组成,数据类型是 <gradient>,是类型 <image> 的子类型。渐变可以在任何使用 <image> 的地方使用,例如在背景中。
线性渐变 linear-gradient,线性渐变的着色线垂直于渐变线。渐变线由包含渐变图形的容器的中心点和一个角度来定义的。渐变线上的颜色值是由不同的点来定义,包括起始点,终点,以及两者之间的可选的中间点(中间点可以有多个)。着色线上的颜色和渐变线上的色点一致。起始点由渐变线和从最近的顶点发出的垂直线之间的交叉点定义的,终点是起点关于容器的中心点的反射点。利用在颜色后面添加 <length> 或者 <percentage> 数据类型来定义颜色中间点的位置。0deg
等价于 to top
,增加值相当于顺时针旋转。
径向渐变 radial-gradient,从原点(容器中心)辐射的两种或多种颜色之间的渐进过渡组成。它的形状可以是圆形或椭圆形。径向渐变由其中心点、边缘形状轮廓、两个或多个色值结束点定义而成。径向渐变函数绘制了一系列从中心点放射到边缘轮廓(甚至可能超出范围)的同心着色轮廓。边缘形状可以是圆形(circle)或椭圆形(ellipse)色值点位于虚拟渐变射线(Virtual gradient ray)上,该渐变射线从中心点水平向右延伸。基于百分比的色值中间点是相对于边缘轮廓和此渐变射线之间的交点(代表 100%)。每个轮廓都是一种单色,并由其相交的渐变射线上的颜色确定。
圆锥渐变 conic-gradient,是通过指定渐变中心、旋转角度以及颜色断点列表来实现的。颜色断点放置在渐变圆弧(圆的周长)上,两个颜色断点之间颜色平滑过渡。
重复线性渐变 repeating-linear-gradient,参数和 linear-gradient 一致。重复径向渐变 repeating-radial-gradient,参数同 radial-gradient 一致。重复圆锥渐变 repeating-conic-gradient,参数同 conic-gradient 一致。重复渐变线或弧的大小,是第一个色标和最后一个色标之间的长度。如果第一个色标只有颜色没有色标长度,那么值默认为 0。如果最后一个色标只有颜色没有色标长度,那么值默认为 100%。如果都没有指定,那么渐变线是 100%,意味着线性和圆锥的渐变都不会重复,径向渐变只会在渐变的半径小于中心点和最远角之间的距离时重复。如果第一个色标声明了,其值大于 0,渐变也会重复,因为线或弧的大小就是第一个色标和最后一个色标之间的距离,小于 100% 或 360 度。
8 背景属性
background 用于一次性集中定义各种背景属性,包括 color, image, origin 与 size, repeat 方式等等。可以应用多个背景到元素,但只有最下方也就是最后一个背景可以包含颜色。
background-color 用于指定背景颜色,值为颜色值或关键字 "transparent",默认值是 transparent 透明。是非继承属性。
background-image(CSS3)用于为一个元素设置一个或者多个背景图像(以逗号隔开),值为url(相对或绝对地址)或渐变函数。在绘制时,图像以 z 方向堆叠的方式进行。先指定的图像会在后指定的图像上面绘制。因此指定的第一个图像“最接近用户”。层级上,元素的 border 会在 background-image 之上,background-image 在 background-color 之上。若图像加载失败则等同于设置成 none,建议指定 background-color
属性预防图像无法被加载的情况。
背景图像(background-image)和HTML图像(<img>)的区别有:前者不存在语义上的意义,它们不能有任何备选文本,也不能被屏幕阅读器识别。当图片属于网页的内容时推荐使用 <img>,当图片仅用于美化页面时,推荐使用 background-image。
.mult-background {
width: 100%;
height: 400px;
background-image: url(bg1.png),
url(bg2.png),
linear-gradient(to right top, #051937, #004d7a, #008793, #00bf72, #8aeb12);
background-repeat: no-repeat, no-repeat, no-repeat;
background-position: bottom right, top left, right;
}
background-origin(CSS3)设置 background-image 显示的区域,当使用 background-attachment 为 fixed 时,该属性将被忽略不起作用。默认值是 padding-box。
background-position 用于设置 background-image 应该位于 background-origin 所规定区域内的位置,初始值是 0% 0%。
background-repeat 定义背景图像的重复方式。可以沿着水平轴(repeat-x),垂直轴(repeat-y),两个轴重复(repeat),或者根本不重复(no-repeat)。单值语法是双值语法的简写。
background-size(CSS3)设置背景图片大小。图片可以保有其原有的尺寸,或者拉伸到新的尺寸,或者在保持其原有比例的同时缩放到元素的可用空间的尺寸。
background-attachment 决定背景图像的位置是在视口内固定,或者随着包含它的区块或内容滚动。
background-clip(CSS3) 设置元素的背景(背景图片或颜色)是否延伸到文本、内容盒子、内边距盒子、边框下面。默认值是 border-box(是在边框下层)。如果没有设置背景图片(background-image)或背景颜色(background-color),那么这个属性只有在边框( border)被设置为非固实(即非soild)、透明或半透明时才能看到视觉效果(与 border-style 或 border-image 有关),否则,本属性产生的样式变化会被边框覆盖。
background-blend-mode 属性定义该元素的背景图片,以及背景色如何混合。 混合模式应该按 background-image 属性同样的顺序定义。如果混合模式数量与背景图像的数量不相等,它会被截取至相等的数量。
mix-blend-mode 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。
mask 属性允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。
backdrop-filter 属性可以为元素后面区域添加图形效果(如模糊或颜色偏移),与 fillter 的区别在于不会影响元素本身。因为它适用于元素背后的所有元素,为了看到效果,必须使元素或其背景至少部分透明。可以用来实现磨砂玻璃效果。取值如下:
- none:没有应用于背景的滤镜。
- <filter-function-list>:一个以空格分隔的滤镜函数(<filter-function>)或是要应用到背景上的 SVG 滤镜。
9 文本属性
text-align 属性设置块元素或表格单元格中行内级内容的水平对齐方式。这意味着它的工作方式类似于 vertical-align,但在水平方向上。,该属性是设置在非 display: inline 元素上才有效。
单行文本两端对齐问题?因为 text-align: justify 不会处理块级元素内文本的最后一行,导致不能对单行文本两端对齐,text-align-last(CSS3)定义最后一行的对齐方式,取值与 text-align 相同,因此可以通过定义 text-align-last: justify 来实现单行文本两端对齐。或者使用伪元素派生一行新的占位内容把单行文本变成多行文本,即可直接使用 text-align: justify 实现两端对齐。
单行文本居中显示,多行文本自动居左显示?父元素设置 text-align:center,子元素设置为display: inline-block; text-align : left; 即可。如此子元素内文本单行时,子元素在父元素内居中;子元素内文本多行时,文本在子元素内居左。
vertical-align 指定行内级元素(inline 或 inline-block 或 inline-table)或表格单元格(table-cell)元素的垂直对齐方式,即以不同的方式在块的方向上进行对齐。Flex 容器内会忽略该属性。
text-decoration 用于设置文本的修饰线外观的(下划线、上划线、贯穿线/删除线或闪烁)。
text-transform 定义元素的文本如何转换大小写。
text-justify(CSS3)用于定义使用什么方式实现文本内容两端对齐。由于该属性影响文本布局,所以 text-align 属性必须设置为 justify。
text-indent 定义一个块级元素首行文本内容之前的缩进量。行内级元素要使用该属性必须先定义该元素为块级(block)或行内块级(line-block),hanging 和 each-line 关键词紧随在缩进数值之后。
text-overflow (CSS3)用于确定如何提示用户存在隐藏的溢出内容。其形式可以是裁剪、显示一个省略号(“…”)或显示一个自定义字符串。该属性并不会强制“溢出”事件的发生,需要设置宽度,overflow,且只对块级元素溢出的内容以及元素内联方向上有效。单值,指的行末溢出行为。双值,第一个值指行左端,第二个值指行右端溢出。
letter-spacing 用于设置文本字符的间距表现,最后一个字符后也会被添加。取值为 <length> 或 normal。
word-spacing 用于指定单词之间的额外间隙,最后一个单词不添加。取值为 <length> 或 normal 或 <percentage>。
overflow-wrap(CSS3)用于设置当一个不能被分开的字符串太长而不能填充其包含块时,为防止其溢出,浏览器是否允许这样的单词中断换行。word-wrap 属性原本属于微软的一个私有属性,在 CSS3 现在的文本规范草案中已经被重名为 overflow-wrap。word-wrap 只是被当作 overflow-wrap 的“别名”。
word-break(CSS3)指定怎样在单词内断行。其中值 break-word 已弃用,word-break:break-all 和 overflow-wrap: break-word 的区别在于后者会先将整个单词换到下一行进行显示。
white-space 用来设置如何处理元素中的空白。
text-shadow(CSS3)可以为文字与 decoration (文本上的装饰性线条) 添加多个阴影,阴影值之间用逗号隔开。每个阴影值由元素在 X 和 Y 方向的偏移量<offset-x> 和<offset-y>、模糊半径 <blur-radius> 和颜色值 <color> 组成。
line-height 用于设置多行元素的空间量,如多行文本的间距。对于块级元素,它指定元素行盒(line boxes)的最小高度。对于非替代的行内级元素,它用于计算行盒(line box)的高度。主段落内容的 line-height 至少应为 1.5,这将有助于改善低可视条件下的体验,也对认知阻碍者有帮助,如阅读困难者。如果文字的大小要随页面的缩放而变化,请使用无单位的值,以确保行高也会等比例缩放。
color 属性设置颜色值的前景色以及文本装饰,并设置 currentcolor 值。currentcolor 可以用作其他属性的间接值,并且是其他颜色属性的默认值,例如 border-color。CSS 并不是唯一支持颜色的 web 技术。同时还有其他支持颜色的图形技术(svg,canvas,webgl)。
transparent 关键字表示一个完全透明的颜色,即该颜色看上去将是背景色。从技术上说,它是带有阿尔法通道为最小值的黑色,是 rgba(0,0,0,0) 的简写。
HSL(Hue、Saturation、Lightness),HSL 颜色的色调/色相 (H) 分量的值是从红色到黄色、绿色、青色、蓝色和品红色(在 360° 处再次回到红色)的角度,它标识了基色是什么。该值可以用CSS 支持的<angle>任何单位指定,包括度 ( deg)、弧度 ( rad)、弧度 ( grad) 或转数 ( turn),当省略色调的单位时,它假定为度数 ( deg)。但这并不能控制颜色的鲜艳程度或暗淡程度,或颜色的亮暗程度。颜色的饱和度 (S) 分量指定最终颜色中包含指定色调的百分比,100% 饱和度是完全饱和,而 0% 是完全不饱和(灰色)。其余部分由亮度 (L) 分量提供的灰度级定义,100% 的亮度是白色,0% 的亮度是黑色,50% 的亮度是“正常”。
-webkit-text-stroke 属性指定了文本字符的笔触宽度<length>(初始值为0)和笔触颜色 <color>(初始值为当前 color 的颜色),取值为<length> <color>。可用于文字描边。此属性为全称属性 -webkit-text-stroke-width 和 -webkit-text-stroke-color 的简写属性。
text-combine-upright 属性将字符组合设置到单个字符的空间中。如果组合文本的宽度超过 1em,则用户代理必须将内容调整到 1em 以内。生成的组合被视为用于布局和装饰的单个直立字形。初始值是 none 即不做特殊处理,值 all 表示尝试水平排版盒子中的所有连续字符,以便它们占据盒子垂直线内单个字符的空间。该属性仅在垂直书写模式下有效,是用来产生横向文字的效果,即使得所有文字都是直立的。
-webkit-line-clamp 属性可以把块容器中的内容限制为指定的行数。它只有在 display 属性设置成 -webkit-box 或者 -webkit-inline-box 并且 box-orient 属性设置成 vertical时才有效果。在大部分情况下,也需要设置 overflow 属性为 hidden,否则,里面的内容不会被裁减,并且在内容显示为指定行数后还会显示省略号。
-webkit-box-orient 属性用来设置一个元素是水平还是垂直布局其子元素。
9.1 单行文本内容溢出省略
.text-ellipsis {
white-space: nowrap; /* 文本换行无效 */
overflow: hidden; /* 溢出部分隐藏 */
text-overflow: ellipsis; /* 超出部分在内容区域内显示为省略号 */
}
9.2 多行内容溢出省略
@lines-to-show: 2;
.text-ellipsis {
display: -webkit-box; /* 作为弹性伸缩盒子模型显示 */
-webkit-box-orient: vertical; /* 设置伸缩盒子的子元素排列方式--从上到下垂直排列 */
-webkit-line-clamp: @line-to-show; /* 显示的行数 */
overflow: hidden; /* 溢出部分隐藏 */
text-overflow: ellipsis; /* 超出部分在内容区域内显示为省略号 */
}
优点:响应式截断,根据不同宽度做出调整;文本超出范围才显示省略号,否则不显示省略号;浏览器原生实现,所以省略号位置显示刚好
缺点: -webkit-line-clamp 是不规范的属性,没有出现在 CSS 规范草案中,也就是说只有 webkit 内核的浏览器才支持这个属性。
开源方案:clamp.js / jQuery.dotdotdot。
10 字体属性
font 属性是 font-style, font-variant, font-weight, font-size, line-height 和 font-family 属性的简写,还可以用于设置元素的字体为系统字体。
font-family 属性指定一个有先后顺序的、逗号隔开,由字体名或者字体族名组成的列表来为选定的元素设置字体。浏览器会选择列表中第一个该计算机上有安装的字体,或者是通过 @font-face 指定的可以直接下载的字体。应当至少在使用的 font-family 列表中添加一个通用的字体族名 <generic-name> 作为降级处理,因为既不能保证用户计算机内已经安装了指定的字体,也不能保证使用 @font-face 提供的字体能够正确地下载。对字体的选择是逐字进行的。也就是说即使某个字符周围都在某个字体中可以显示,但该字符在当前的字体文件中没有适合的图形,那么会继续尝试列表中靠后的字体。
font-size 属性指定字体大小,以两种方式之一指定:
- 作为一个从绝对大小 absolute-size 关键字列表(xx-small, x-small, small, medium, large, x-large, xx-large)或相对大小 relative-size 关键字列表(larger, smaller,分别指的是比父元素的字体大或小)中选择的单个关键字。
- 作为一个 <length>[px, rem, em] 或 <percentage> 值。
px 像素(Pixel),是相对于显示器屏幕分辨率而言的相对长度单位。对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用 px 即可;
em 是相对长度单位。在 font-size 中使用是相对于父元素的 font-size,在其他属性中使用是相对于自身的 font-size,如 width。如在网页中任何地方都没有设置文字大小的话,那它将等于浏览器默认文字大小,通常是 16px。em 的值并不是固定的,会继承父级元素的字体大小;font-size 属性的 em 和 ex 单位值是相对于父元素的字体大小(不像其他属性,它们指的是相对当前元素的字体大小),这意味对于 font-size 属性来说,em 单位和百分比单位的作用是一样的。em 值是复合的。设置 body 元素的字体大小为 62.5% (即默认大小 16px 的 62.5%),等于 10px。现在你可以通过计算基准大小 10px 的倍数,在任何元素上方便的使用 em 单位。这样有 6px 即 0.6em = 6px / 10px, 12px 即 1.2em = 12px / 10px(em = 希望得到的像素大小 / 父元素字体像素大小)。
rem(root em)为元素设定字体大小时,是只相对于 HTML 根元素,因此设置好根元素的 font-size,那么其他元素上的 1rem = 根元素的 font-size。rem 值的发明是为了避免复合问题。对于不支持的浏览器可以多写一个绝对单位 px 的声明做降级处理。rem 适合适配各种移动设备。
font-weight 属性指定了字体的粗细程度。一些字体只提供 normal 和 bold 两种值,因此,若指定粗细值为 100-500 时,实际渲染时将使用 normal,指定粗细值为 600-900 时,实际渲染时将使用 bold 。
font-variant 属性用于定义元素的文本是否为小型的大写字母。normal ——正常的字体;
small-caps —— 小型的大写字母。
font-style 属性允许选择 font-family 字体下元素的文本是否为斜体。normal 样式指定文本字体样式为正常的字体,italic 样式一般是指书写体,相比无样式的字体,通常会占用较少的高度,而 oblique 字形一般只是常规字形的倾斜版本。如果当前字体没有 italic(或 oblique,会选用倾斜体oblique(italic )替代。
font-stretch 属性用于定义元素的文字是否横向拉伸变形。
@font-face(CSS3)用于指定在线字体,消除对用户电脑字体的依赖。
如果提供了 local() 函数,从用户本地查找指定的字体名称,并且找到了一个匹配项,本地字体就会被使用。否则,字体就会使用 url() 函数(顺序依次进行加载,若失败再加载后面的)下载的资源(存在跨域限制)。@font-face 不仅可以放在在 CSS 的最顶层,也可以放在@规则的条件规则组(包括 @media、@support、@ducument)中,但不能放在 CSS 选择器内。
关于字体是否下载,IE8 只要定义了 font-face,就会去下载字体,不论实际有没有应用该字体。Firefox, IE 9+ 只有定义了 font-face 并且页面有元素应用了该字体,就会去下载,不论该元素是否有文本内容。Chrome, Safari 只有定义了 font-face 并且页面有元素应用了该字体,并且该元素有文本内容,才会去下载字体。
<!-- 字体预加载,以便更快的加载字体 -->
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin />
<script type="text/javascript">
// 动态插入 DOM 时,字体下载时机
const el = document.createElemnt('div');
el.style.fontFamily = 'open_sansregular';
// 到这里 IE8 就会来开始下载字体
document.body.appendChild(el);
// 到这里 Firefox,IE9+ 就会开始下载字体
el.innerHTML = 'Content.';
// 到这里 Chrome, Safari 就会开始下载字体
</script>
11 transform变换属性(CSS3)
transform 属性允许对元素进行 2D 和 3D 空间的线性仿射变形(affine linear transformations):旋转,缩放,倾斜或平移。这是通过修改 CSS 视觉格式化模型的坐标空间来实现的,因此只能转换由盒模型定位的元素(display 不是 inline)。
transform-origin(CSS3) 属性指定原点的位置。默认值为元素的中心(center)。
backface-visibility(CSS3) 指定当元素背面朝向观察者时是否可见。visible 指定元素背面(指元素内表面)可见,允许显示正面的镜像,hidden 指定元素背面不可见。
transform 可以用来尝试处理移动端 1px 的问题(画 0.5px 的线):
/* 绝对定位伪元素 + transform */
.after-scale {
position: relative; /* 父元素相对定位 */
}
.after-scale::after {
content: '';
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
border-bottom: 1px solid #c8c7cc;
transform: scaleY(0.5);
transform-origin: 0 0;
}
12 @media媒体查询(CSS3)
媒体查询允许基于设备的不同特性来应用不同的样式申明。媒体查询可以有以下的表现和使用形式:
1. 通过 @media 和 @import 有条件的使用 CSS 样式,如:
/* @import 规则用于指定导入的外部样式表以及目标媒体 */
@import "style.css" screen, projection;
/*
其中:
1. @import 行尾分号是必须的
2. 除 @charset 之外,@import 规则必须先于其他任何 CSS 规则
3. IE 中使用 @import 无法引入超过 35 条的样式表
*/
2. 用 media 属性为 <style>, <link>, <source> 和其他 HTML 元素指定特定的媒体类型。如:
<link rel="stylesheet" src="styles.css" media="screen" />
<link rel="stylesheet" src="styles.css" media="print" />
3. 在JavaScript 中使用 Window.matchMedia() 和 MediaQueryList.addListener() 方法来测试和监控媒体状态。
使用 @media 规则指定一个媒体查询和一个 CSS 块,当且仅当该媒体查询与正在使用其内容的设备匹配时,该 CSS 块才能应用于该文档。@media 可以放在在 CSS 的最顶层,也可以放在@规则的条件规则组中。
每条媒体查询语句都由一个可选的媒体类型和任意数量的媒体特性表达式构成。可以使用多种逻辑操作符(not、and、only和逗号 “,”,其中逗号相当于 or;not 只能用于一整条媒体查询语句而不能用于媒体特性表达式即 not 关键字只能放在单条最前面:not(hover)、@media not all and (monochrome))合并多条媒体查询语句。当不使用 only 时,旧版本的浏览器会将 screen and (max-width: 500px) 简单地解释为screen,这对于防止较早的浏览器应用所选样式很有用。媒体查询语句不区分大小写。CSS2中只包括媒体类型,而且CSS3废弃了一些媒体类型(tty, tv, projection, handheld, braille, embossed, 以及 aural)。
媒体类型与媒体特性嵌套:
/* 媒体类型嵌套媒体特征 */
@media screen {
@media (min-width: 20em) {
img {
display: block;
width: 100%%;
height: auto;
}
}
@media (min-width: 40em) {
img {
display: inline-block;
max-width: 300px;
}
}
}
当媒体类型(可选且默认为 all,使用 not 或 only 逻辑操作符则必须指定)与在其上显示文档的设备匹配并且所有媒体功能表达式都计算为 true 时,媒体查询将计算为 true,CSS 内容才适用。涉及未知媒体类型的查询始终为 false。即使媒体查询返回 false,带有媒体查询附加到其 <link >标记的样式表仍将下载。媒体类型有:
(1)all:用于所有设备;
(2)print:用于在打印预览模式下在屏幕上查看分页材料和文档;
(3)screen:用于屏幕;
(4)speech:用于语音合成器。
媒体特性(Media features)描述了 user agent、输出设备,或是浏览环境的具体特征是否存在、值为多少。媒体特性表达式是完全可选的,但都必须置于括号中。在测试接受范围的任何特性时允许更简洁的媒体查询(比如 400px <= width <= 700px、height > 600px),或者利用支持添加 max- 和 min- 前缀的媒体特性来进行范围检测。
/* 0 ~ 30rem */
@media (max-width: 30rem) {
nav li {
display: block;
}
}
/* 30rem ~ 100rem */
@media (max-width: 100rem) {
nav li {
display: inline-block;
}
}
为了最好地调整网站文本大小,当使用长度值 <length>[em,rem,px] 进行媒体查询时,单位建议使用 rem。
由于媒体查询可以洞察用户正在使用的设备的功能(以及扩展的功能和设计),因此有可能滥用它们来构造“指纹”来识别设备,或者至少 将其分类为某些细节,这可能是用户不希望看到的。因此,浏览器可能会选择以某种方式捏造返回的值,以防止它们被用来精确地标识计算机。浏览器可能还会在此区域提供其他措施。例如,如果启用了 Firefox 的“抵抗指纹”设置,则许多媒体查询会报告默认值,而不是代表实际设备状态的值。
利用媒体查询实现自适应:
background-image 用 image-set() 设置响应式的背景图片:
<img> 标签用 srcset 和 sizes 实现更好的图片自适应:
- 带 x 的由浏览器计算出正在显示的显示器的分辨率,然后提供 srcset 引用的最适合的图像
- 带 w 的由浏览器根据 sizes 属性中媒体查询为真的 size,然后提供 srcset 引用中最相近的图像。
Bootstrap 中使用媒体查询:
媒体查询可以用来尝试处理移动端 1px 的问题(画 0.5px 的线):
any-hover 媒体特性可以用来测试是否有任意可用的输入机制可以在元素上 hover。取值有:
- none:可用的输入机制里没有机制可以方便地 hover,或者不存在定点输入机制;
- hover:一个或多个可用的输入机制可以方便地在元素上 hover。
13 多列属性(CSS3)
多列布局(通常称为 multicol)用于将内容布置到一组列框中,就像报纸中的列一样。通过给元素添加且必须添加 column-count 或 column-width 之一变成多列容器或简称为 multicol 容器,容器内的列都是匿名的盒子,称为列盒子。多列容器会创建新的块格式上下文(BFC),因此子元素的margin 不会与多列容器的 margin 互相重叠。
如何处理溢出的列取决于是片段化的媒体上下文(比如打印)还是在连续的媒体上下文(比如 web 页面)中。前者中一旦碎片(例如页面)中充满了列,多出的列将移至新页面。后者中列将沿横向溢出,意味着水平滚动条的出现。
columns 属性(columns: <'column-width'> <'column-count'>)用来设置元素的列宽和列数,是 column-count 和 column-width 的简写属性。
column-count 属性设置元素的列数。auto——表示列的数量由其他 CSS 属性指定,比如 column-width。<number> —— 严格正 <integer>,元素内容被划分的理想列数,若 column-width 也被设置为非零值,此参数仅表示所允许的最大列数。
column-width 属性设置多列布局中的理想列宽,容器将具有尽可能多的列,而其中任何列的宽度都不会小于该值,除非容器宽小于该值。auto ——列的宽度由其他 CSS 属性决定,比如 column-count;<length> ——列宽值,不能是百分比和负数。如果想要一个图像尺寸缩小到适合列盒子而不是溢出当前列盒子,标准的响应式的解决方案是设置最大宽度:100%。
column-gap 属性设置元素列之间的间隔大小。目前该属性已不是多列容器中的特有属性,已经可以在 Flexible Box(弹性盒子)以及 Grid layouts(网格布局)中也可使用。normal —— 默认值,多列容器中为 1em,其他类型布局盒子中为 0;<length> 或 <percentage> —— 必须是非负数。
column-rule 属性设置列与列之间的分割线(也称为规则)的宽度、样式和颜色,是column-rule-width(宽度,值为 thin,medium, 或 thick 三个关键字或 <length>,类似 border-width)、column-rule-style(样式,类似 border-style)、column-rule-color(颜色,<color>)的简写属性。
column-fill 属性控制元素的内容在分成列时如何平衡。balance ——默认值,内容在列之间平均分配。auto ——按顺序填充列。内容只占用它需要的空间,可能导致某些列保持空白。balance-all ——内容在列之间平均分配。balance 和 balance-all 区别在于在分段上下文中(分页媒体),前者只有最后一页才会平衡,后者所有片段都是平衡的。
column-span 属性设置为 all(默认为 none 即不跨越多个列)时,可以让一个子元素跨越多列容器的所有的列,该元素(称为 spanning element)建立了一个新的块格式上下文,因此,在该元素对多列容器进行中断,该元素之后再重新启动多列。
break-inside 属性描述了在多列布局页面下的内容盒子如何中断,如果多列布局没有内容盒子,这个属性会被忽略,设置 break-*属性的同时增加一个旧属性 page-break-*能够获得更好的浏览器支持。默认值是 auto —— 既不强制也不禁止。每一个断点由前一个元素的 break-after 值、后一个元素的 break-before 值以及当前元素自身的 break-inside 值定义:
- 若有一个设置的是强制中断值(always, left, right, page, column, region),则该属性值具有优先权。如果存在多个属性是强制中断值,则使用流中最新出现的元素的值, 即 break-before 优先于 break-after,而本身 break-after 优先于 break-inside。
- 若任何一个设置的是禁止中断值(avoid,avoid-page,avoid-region,avoid-column),则禁止该类型的中断。
widows 属性设置在一个片段打断后,新的片段顶部需要结合在一起的最小行数。该值必须为正值。
orphans 属性设置在片段中断之前,可以单独停留在片段底部的最小行数。该值必须为正。
14 flex 弹性盒子布局(CSS3)
弹性盒子(Flexbox)(即 CSS 弹性盒子布局模型)是一种用于在单个维度(行或列)中显示项目的布局模型,关键特性是 flex 布局中的项目可以增大以填满未使用的空间和缩小以避免从父元素溢出,也可以将空间分配到项目本身、项目之间或项目周围,还支持在主轴或交叉轴上对齐项目,从而对一组项目的大小和对齐方式提供高级别的控制,通过嵌套这些盒子(水平盒子在垂直盒子内,或垂直盒子在水平盒子内)就可以实现在两个维度上构建布局。弹性盒子的真正价值可以体现在它的灵活性/响应性,无论是调整浏览器窗口的大小或增加元素。
Flex 项(Flex Item)是 Flex 容器(块级元素设置 display: flex 或行内级元素设置 display: inline-flex)的一级子元素。弹性容器内的连续文本,也将成为 Flex 项。
当元素表现为 Flex 项时,它们沿着两个轴来布局:
- 主轴(main axis)是沿着 flex 项放置的方向延伸的轴。该轴的开始和结束被称为 main start 和 main end。
- 交叉轴(cross axis)是垂直于 flex 项放置方向的轴。该轴的开始和结束被称为 cross start 和 cross end。
flex 容器属性:
flex-direction 属性指定主轴的方向。显然,flex-direction 不会更改绘制顺序。
flex-wrap 属性指定 flex 项在主轴方向上单行或多行显示,允许在换行条件下控制行的堆叠方向。
flex-flow 属性是 flex-direction 和 flex-wrap 的简写(不区分两个属性的顺序)。
justify-content 属性指定浏览器如何沿着 flex 容器的主轴(网格容器的行内轴)在 flex 项(grid项)之间和周围分配空间。在弹性盒子和网格容器中 normal 表现和 stretch 一样,但弹性盒子(flexbox)不支持设置为 stretch。Flex 容器中,初始值是 flex-start。flex 容器中所有的对齐方法,属性值 flex-start 和 flex-end 都会受到文本书写方向影响。
align-items 属性将所有 flex 项的 align-self 设置为相同值。在 Flex 容器,它控制 Cross Axis 上 flex 项的对齐方式。在 grid 容器中,它控制块轴上 grid 项在其网格区域内的对齐方式。如果 flex 容器不设置高度,则最高的元素定义了容器的高度(多行则定义的是行高度)。初始值是 stretch。
align-content 属性设置浏览器如何沿着 flex 容器的交叉轴(或 grid 容器的主轴)在内容项之间和周围分配空间,对单行弹性盒子模型无效(即 flex-wrap:nowrap)。取值上以及表现上和 justify-content 相同。
flex项属性:
flex 属性是 flex-grow、flex-shrink、flex-basis 的简写属性,用于设置 flex 项如何增大或缩小以适应其 flex 容器中可用的空间。而如果空间不要加到 flex 项上,则应该使用 margin 或 justify-content 来处理多余空间。初始值是 flex-grow: 0;flex-shrink: 1;flex-basis: auto。建议使用简写属性,以确保都被设置,除非真的需要单独修改覆盖之前设置的。
flex-grow 属性设置 flex 项主尺寸(main size)的增长系数,即分配剩余空间的相对比例。取值为<number>,初始值为 0,负值无效。剩余空间是 flex 容器的大小减去 flex-basis 为 0 以外的所有 flex 项加起来的大小。如果所有的兄弟项目都有相同的 flex-grow 系数,那么所有的项目将剩余空间按相同比例分配,否则将根据不同的 flex-grow 定义的比例进行分配。
flex-shrink 属性指定 flex 项在初始主尺寸(main size)之和(不包括 flex-basis为 0 的 flex 项)大于容器时的收缩大小。取值为 <number>,初始值为 1,不允许负值,在 flex 属性中省略则默认为 1。min- 主轴方向尺寸优先级大于 flex-shrink 收缩后的尺寸,如果没设置,元素默认不会缩短至小于最小内容尺寸(width/height: min-content)尺寸。
flex-basis 属性指定 flex项的初始主尺寸(main size),标准盒模型是内容盒(content-box)的尺寸,替代盒模型是边框盒(border-box)的尺寸。初始值为 auto,非 auto 的 flex-basis 值相比 width/height 优先,否则即 auto 的 flex-basis 值参考 width/height 的值且如果没有设定 width/height(即 auto),则采用元素内容(width/height:max-content)的尺寸。flex-basis 值为0,则该 flex 项的尺寸所用空间也可以被用来分配。均分布局需要给所有的 flex 项的 flex-basis 属性设置为 0。
align-self 属性覆盖 flex 容器或 grid 容器设置的 align-items 值。在 grid 容器中在网格区域内对齐 gird 项,在 Flex 容器中设置该 flex 项在交叉轴如何对齐,不适用非 gird 项或 flex 项(比如 table-cell和块级盒子)。如果flex项的交叉轴方向的 margin 值设置为 auto,则会忽略 align-self。
order 属性规定了 flex 容器中的 flex 项在布局时的顺序。元素按照 order 属性的值的增序进行布局绘制,默认值为 0。拥有相同 order 属性值的元素按照它们在源代码中出现的顺序进行布局。order 仅仅对元素的视觉顺序产生作用,并不会影响元素的逻辑或标签顺序。 order 适用于 flex 项、grid 项,不可以用于非视觉媒体(比如 speech)。
Flex 容器创建 Flex 格式上下文,内部浮动失效,排除外部浮动,不存在外边距折叠。浏览器兼容方面,IE 10 需要使用 -ms- 前缀,webkit 内核比如 UC 浏览器需要使用 -webkit- 前缀。
Flexbox 应用梳理:
/* 1. 表单控件:input 撑满 */
.wrapper {
display: flex;
}
.wrapper input {
flex: 1;
}
/* 2. 绝对底部:内容区域高度不够时,footer 也需要固定在底部 */
.container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.container .header,
.container .footer {
height: 30px;
}
.container .main {
flex: 1;
}
/* 3. 水平垂直居中 */
.container {
display: flex;
justify-content: center;
align-items: center;
}
.container .content {
width: 100px;
height: 100px;
}
/* 4. 一部分元素左对齐而另一部分右对齐 */
.container {
display: flex;
gap: 20px;
}
/* push-right 类名元素即分割位置所在 */
.container .push-right {
margin-left: auto;
}
/* 5. 九宫格 */
.nine-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background-color: @bg-container;
width: 360px;
height: 360px;
.item {
width: 32%;
height: 32%;
text-align: center;
/* n=0,1,2,3...,因此 -n + 6 即 6,5,4,3,2,1*/
&:nth-child(-n+6) {
margin-bottom: 2%;
}
&:nth-child(3n+1),
&:nth-child(3n+2) {
margin-right: 2%;
}
}
}
/* 6. 自适应布局: 会随着 container 的容器宽度自适应 */
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
width: 100%;
height: auto;
min-height: 400px;
gap: 20px;
}
.item {
display: flex;
justify-content: center;
align-items: center;
flex: 1 1 150px; /* 生长 */
/* flex: 0 1 150px; */ /* 不生长 */
}
15 grid 网格布局(CSS3)
CSS 网格是由一系列水平及垂直的线(行与列)构成的二维的布局模式,可以将网格元素(grid 项)放置在这些行和列定位的位置上,CSS 网格可用于布局页面主要的区域或小型组件。
grid 容器(块级元素设置 display: grid 或行内级元素设置 display: inline-grid)会创建一个 grid 格式上下文,它的直接子元素是 gird 项(grid item)。网格列(grid column)/网格行(grid row)是 grid 容器中的垂直/水平轨道(水平书写模式下)即两个垂直/水平网格线之间的空间。一个网格通常具有许多的列与行,以及行与行、列与列之间的间隙,这个间隙一般被称为沟槽(gutter)。单独声明 display: grid 默认只是创建了一个单列网格。
.grid {
display: grid;
grid-template-rows: [row-start row-1-start] 1fr [row-1-end row-2-start] 1fr [row-2-end row-end];
grid-template-columns: [col-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-end];
}
grid-template-columns/grid-template-rows 属性是基于网格列/行的维度定义网格线的名称和网格轨道的尺寸大小。通过 grid-template-columns/grid-template-rows 属性定义出来的是显式网格。
- 在中括号内用空格将多个名称分开的方式可以给同一网格线定义多个名称。每一个网格线名都可以被引用,以用来定位 grid 项。
- 如果一个区域周围的线都用 -start 和 -end 作为后缀,那么就会创建一个前缀作为名字的区域, grid 项就可以使用名字在 grid-area 中直接指定位置。
- 单位 fr 和其它长度单位混合使用时,fr 的计算基于其它单位分配后的剩余空间。
- repeat(12, [col-start] 1fr)可以得到有相同名字的多条线,由于网格线名字相同,指定 grid 项时应该为 col-start n / col-start m,n 为 1 时 n 可以省略。repeat 函数的第一个参数还可以是 auto-fill 和 auto-fit
- auto-fill 表示如果网格容器在相关的轴上有一个确定的或最大的尺寸,那么轨道列表的重复次数就是最大可能的正整数,且不会导致轨道列表溢出其网格容器,
- auto-fit 表现一样,不同在于任何空的重复轨道(包括两侧的沟槽)都会被折叠起来,推荐使用 auto-fit。
grid-auto-rows / grid-auto-columns 属性用于指定没有使用 grid-template-rows / grid-template-columns 明确规定大小的隐式创建的行/列轨道 (显式定位到超出范围的行/列或由自动放置算法额外创建的行/列)的尺寸大小,默认值是 auto,即这些轨道将自动定义尺寸,所以会根据它里面的内容改变尺寸。grid-auto-rows 和 grid-auto-columns 的简写属性是 grid-auto-flow。
无论是 grid-auto-rows / grid-auto-columns 或 grid-template-columns / grid-template-rows,只有在取值为 auto 时可配合 align-content 和 justify-content 属性使用。
grid-template-areas 属性指定命名的网格区域(网格中由一个或者多个网格单元格(网格中的最小单元。它是四条网格线之间的空间,概念上非常像表格单元格)组成的一个矩形区域)。被命名的网格区域也会隐式的创建”名字-start ”和”名字-end”的网格线。
grid-area 属性是 grid-row-start、grid-column-start、grid-row-end 和 grid-column-end 的简写,通过网格线序号,span 跨度或 auto 或对应 grid-template-areas 中的网格区域来指定 grid 项在网格中的位置和大小,开始与结束的网格线序号之间或网格线与跨度之间要使用 / 符号分开,可以用负数来倒数定位网格线。设置顺序是 grid-row-start / grid-column-start / grid-row-end / grid-column-end,相当于逆时针设置。grid-row 属性则是 grid-row-start、grid-row-end 属性的简写。grid-column 属性则是 grid-column-start、grid-column-end 的简写,这些属性的语法类似。如果只指定开始而没有指定结束或 span 跨度,默认延伸一个轨道。在从左到右的文本水平书写方向中,序号为 1 的第一条列/行网格线在网格的最左/上面。网格线也会在隐式网格中被创建,但无法通过网格线序号定位到。网格线可以在轨道大小信息之前或之后的方括号中进行命名。
IE11 不支持网格单元的自动布置。除非显式地注释 -ms-grid-column 和 -ms-grid-row,否则所有单元都会在网格的第一行/列结束,可以使用提供自动注释的工具:css_grid_annotator。
gap 属性是用来设置网格行与列之间的间隙(gutters),该属性是 row-gap 和 column-gap 的简写形式。<'column-gap'> 是可选的,假如 <'column-gap'> 缺失的话,则会被设置成跟 <'row-gap'> 一样的的值。Flexible Box(弹性盒子)和多列布局也可以使用。多列布局中 column-gap 默认值 normal 的默认间隔为 1em,其他布局中 row-gap 和 column-gap 初始值 normal 的间隔为 0。间隙距离可以用任何长度单位包括百分比来表示,但不能使用 fr 单位。间距所使用的空间会在使用弹性长度 fr 的轨道的空间计算前就被留出来。gap 属性曾经有一个 grid- 前缀,可加可不加。
多个网格项目可以占用同一个网格单位,其覆盖顺序默认遵循文档流的原始顺序(后来居上),也可以发生重叠时使用 z-index 属性控制重叠的顺序。
grid-auto-flow 属性控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。当有一些字符串或文本被包含在网格容器中,但却没有被其他元素包装,它们就会被创建为匿名 grid 项,由于不能被选定则只能由自动布局算法处理。
网格布局方式下共有两条轴线用于对齐——块轴和行轴。块轴是采用块布局时块的排列方向。行轴与块轴垂直,它的方向和常规行内流中的文本方向一致。属性 align-self 和 align-items 用于控制在块轴上对齐元素,justify-items 和 justify-self 用于控制在行轴上对齐元素。由于默认对齐方式是 stretch,会拉伸覆盖网格区域,除非元素具有固定宽高比,对齐行为表现为 start(块轴起点),其他取值则会按照内容自动大小。
而针对网格轨道整体占据的空间小于网格容器情况下,分别使用 align-content 在块轴上对齐网格轨道,使用 justify-content 在行轴上对齐网格轨道,网格布局中默认的行为是对齐到块/行轴起点(start),行轴起点(start)和终点(end)会受到书写方向 direction 的影响,块轴和行轴受到书写模式属性 writing-mode 的影响。place-content 属性则是对 align-content 和 justify-content 的简写。而对于与分配空间有关的值会使网格元素变大。
在网格区域内若 grid 项未设置宽高或者宽高小于网格区域,则可以使用 auto 的 margin 在网格区域内对齐元素。
上述对齐属性的具体值说明参考 flex 弹性盒子布局,大体上类似。
浏览器支持情况:
只需要按行或者列控制布局就用弹性盒子(Flexbox),需要同时按行和列控制布局就用网格(Grid)。弹性盒子从内容出发。网格则从布局入手,先创建网格,然后再把元素放入网格中,或者根据自动放置规则把元素按照网格排列。
grid 布局应用:
/* 1. 媒体查询 + grid 实现响应式布局*/
.wrapper {
display: grid;
grid-gap: 20px;
grid-template-areas:
"header"
"nav"
"content'
"sidebar"
"ad"
"footer";
}
@media (min-width: 560px) {
wrapper {
grid-template-columns: 1fr 3fr;
grid-template-areas:
"header header"
"nav nav"
"sidebar content"
"ad footer";
}
nav ul {
display: flex;
justify-content: space-between;
}
}
@media (min-width: 700px){
.wrapper{
grid-template-columns: 1fr 4fr 1fr;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav content ad"
"footer footer footer";
}
nav ul {
flex-direction: column;
}
}
/* 2. 12 列网格系统 */
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(12, [col-start] 1fr);
}
/* 三列布局使用 */
.header,
.footer {
grid-column: col-start / span 12;
}
.side-left{
grid-column: col-start / span 3;
grid-row: 2 / span 10;
}
.content {
grid-column: col-start 4 / span 6;
grid-row: 2 / span 10;
}
.side-right{
grid-column: col-start 10 / span 3;
grid-row: 2 / span 10;
}
/* 3. 绝对底部: 粘性页脚模式是指当页面内容不足以填满视口高度时,页脚会“粘附”在视口底部的一种模式。 */
.wrapper {
min-height: 100%;
display: grid;
grid-template-rows: auto 1fr auto;
}
/*
<div class="wrapper">
<header class="page-header"></header>
<article class="page-body">
</article>
<footer class="page-footer">footer</footer>
</div>
*/
17 隐藏元素、内容
屏幕阅读器:一种可以将电脑、手机屏幕上的内容通过文本转语音(TTS)朗读出的软件,该类软件的受众主要是视力障碍人群。
判断指标:
- 是否支持动画;
- 可访问性(屏幕阅读器);
- 是否触发事件;
- 是否影响布局;
- 是否会渲染。
1. display:none
完全隐藏元素,元素会从渲染树、无障碍树中移除,仅存在于 DOM 树上,导致该元素和其所有后代元素无法被屏幕阅读器访问,隐藏过程不支持动画,会触发页面的重排和重绘,性能较差。隐藏后不会渲染也不影响布局,无法触发绑定的事件(比如点击)。如果作用的是 img 标签,由于解析到标签的时候,样式还没应用,所以图像会下载,相反使用 background 设置的图像不会下载,同样是因为样式没应用。
2. position:absolute; left: -9999px;
absolute 绝对定位,使用 top、bottom、left、right 将元素移出屏幕来隐藏。隐藏过程会触发重排和重绘,支持动画。隐藏后脱离文档正常流渲染不影响布局,无法被点击,屏幕阅读器可访问。
3. visibility: hidden;
视觉上隐藏元素而不更改文档的布局,隐藏过程支持动画,会触发重绘。隐藏后无法触发事件,无法被屏幕阅读器访问。
4. opacity: 0 和 filter: opacity(0) 和 rgba(255,255,255,0)
设置透明度为 0 来隐藏元素,不更改文档的布局,隐藏过程支持动画,会触发重绘。隐藏后可以触发事件和被屏幕阅读器访问。
5. z-index: -9999px;
对已经定位的元素(position 不是 static)设置负层级来隐藏,隐藏过程支持动画,会触发重排和重绘,隐藏后无法触发事件,可以被屏幕阅读器访问。
6. transform: scale(0, 0);
对元素进行缩放到 0 进行隐藏,不更改文档的布局,隐藏过程支持动画,会触发重排和重绘,隐藏后无法触发事件,可以被屏幕阅读器访问。
7. clip-path:circle(0)
裁剪出元素可见区域,不更改文档的布局,隐藏过程支持动画,触发重绘,隐藏后占据空间,无法触发事件,可以被屏幕阅读器访问。
18 继承与层叠
18.1 继承
继承决定了当没有为元素的属性指定值时该如何计算值。当元素的一个继承属性没有指定值时,则取父元素的同属性的计算值(根元素没有父元素,取初始值 initial);当元素的一个非继承属性没有指定值时,则取属性的初始值 initial。通常情况下,可以通过常识来判断哪些属性属于默认支持继承的,比如可继承属性有 font-size, font-family, color,不可继承属性有 border, padding, margin, width, height。
控制继承的相关属性值:
18.2 层叠
层叠是 CSS 的基本特征,定义了如何合并来自多个源的属性值的算法。只有 CSS 声明(属性名值对)会参与层叠计算。包含在大多数@规则的 CSS 声明是参与层叠计算的,比如包含于@media、@documents或者@supports的 CSS 声明,但是包含于@keyframes / @font-face / @import / @charset 的声明不参与计算。
关键帧不参与层叠,意味着在任何时候 CSS 都是取单一的 @keyframes 的值而不会是某几个 @keyframes 的混合;用 @keyframes 规则定义的值会覆盖全部普通值,但会被 !important 的值覆盖。
CSS声明的来源包括:
- 用户代理样式即浏览器给任何网页设置的默认样式。
- 页面作者样式即网页开发人员设置的样式。
- 用户自定义样式即网页浏览者自定义的样式。
对将要应用在相同元素上的 CSS 声明,首先根据重要性进行排序:用户代理中的 !important 值 > 用户自定义的 !important 值 > 页面作者的 !important 值 > 页面作者样式普通值 > 用户自定义样式普通值 > 用户代理样式普通值。
!important相关:
然后重要性相同时根据优先级排序。优先级计算比较规则:
级联层(@layer)规则:在所有层之外声明的CSS会被认为处于一个最后声明的未命名的层中,后面的层中的普通值比先前定义的层的优先级高,相反,先前定义的层中的 !important 值比后面的层的优先级要高;重要性相同时,内联样式比页面作者定义的非样式的优先级都要高,不受级联层规则的影响。
最后优先级相同时后面声明属性值覆盖前面的。
选择器列表:
类型(标签名或元素)选择器 h1 {}
通配选择器 * {}
类选择器 .box {}
ID选择器 #unique {}
标签属性选择器 a[title] {}
伪类选择器 p:first-child {}
伪元素选择器 p::first-line {}
后代选择器 article p
子代选择器 article > p
相邻兄弟选择器 h1 + p
通用兄弟选择器 h1 ~ p
1. 选择器表达式从右至左解析,最右为关键选择器,持续左移直到和规则匹配或当不匹配而放弃该规则:
因为,从右向左匹配一开始就在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面。的确 .mod-nav h3 span,如果叶子节点存在过多的不符合的 span 标签时,就需要考虑 CSS 选择器的优化了。
2. 避免使用通配符选择器、避免使用子选择器、避免使用多层元素选择器、避免使用元素选择器限制 class 选择器、避免使用元素或 class 选择器限制 id 选择器;可继承属性使用继承。
19 伪类与伪元素
伪类(:pseudo-class)是添加到选择器的开头为冒号关键字,用于指定所选元素的特殊状态(比如鼠标悬停、链接状态、表单状态、第几个元素等)。
为了可以正确地渲染链接元素的样式,:link,:visited,:hover,:active 这四个伪类选择器需要遵循 LVHA 的先后顺序。而 :focus 伪类选择器常伴随在 :hover 伪类选择器左右,需要根据想要实现的效果确定它们的顺序。
伪元素(::pseudo-element)是附加至选择器末的开头为双冒号的关键字,允许对被选择元素的特定部分应用样式。一条选择器语句之后只能使用一个伪元素,伪元素选择器不能匹配任何真实存在的 html 元素。早期的伪元素曾使用单冒号的语法,现代的浏览器为了保持向后兼容,也支持早期的带有单冒号语法的伪元素。::before、::after、::marker 伪元素与 content 属性的共同使用,在 CSS 中被叫做“生成内容”。
滚动条
可以使用以下伪元素选择器去修改基于 webkit 的浏览器的滚动条样式(即 firefox 不支持):
20 逻辑属性与逻辑值
传统的 CSS 根据屏幕的实体尺度设置物体尺寸。而逻辑属性与逻辑值规范定义了从这些实体值到与之等价的逻辑值(即相对于流的值)的对应关系——如 left 和 right,或者 top 和 bottom 对应于 start 和 end。
在使用逻辑属性与逻辑值即相对于流的属性和值时,一个关键的概念是块向与行向这两个方向。块向是指另一方向,即块——例如段落——依次显示的方向。在英文和阿拉伯文中,块沿竖直方向依次排列,而块在任意竖排书写模式中沿水平方向依次排列。行向是指在所用的书写模式中,一行文本延伸的方向。因此在从左到右横排的英文文档,或者从右到左横排的阿拉伯文文档中,行向为水平方向。若切换至竖排书写模式(如日文文档)则行向变为竖直方向,这是因为文本在这种书写模式中竖直延伸。
逻辑属性 margin-block-start / margin-block-end定义了元素的逻辑块首/块末外边距,并根据元素的书写模式、行内方向和文本朝向对应至实体外边距,其取值与 margin-left 属性相同。
21 自定义属性
带有前缀 -- 的属性名,表示的是带有值的自定义属性(有时也被称为“CSS 变量”),其可以通过 var() 函数在全文档范围内复用的。 自定义属性名区分大小写,自定义属性是可继承的;自定义属性是可以级联的:每一个自定义属性可以多次出现,并且变量的值将会借助级联算法和自定义属性值运算出来。自定义属性在某个地方存储一个值,然后在其他许多地方引用它。自定义属性具有语义化的标识的优点。
通常的最佳实践是定义在根伪类 :root 下,这样就可以在 HTML 文档的任何地方访问到它,但如果需要,则应该限制在特定的选择器及及其子孙下。
自定义属性的前缀 var- 是早期标准规定的,后期改为了 --。Firefox 31 和以后的版本遵循新的标准。
在 JavaScript 中获取(getPropertyValue方法)或者修改 (setProperty方法)CSS 变量和操作普通 CSS 属性是一样的。
var(<custom-property-name>, <declaration-value>?) 函数可以插入一个自定义属性的值,用来代替非自定义属性中值的任何部分。var() 函数不能作为属性名、选择器或者其他除了属性值之外的值:
- 第一个参数 <custom-property-name> 是要替换的自定义属性的名称。
- 函数的第二个参数<declaration-value>是可选的,用作回退值。如果第一个参数引用的自定义属性无效(概念:计算时有效性),则该函数将使用第二个值。自定义属性的回退值允许使用逗号,即是说任何在第一个逗号之后到函数结尾前的值都会被考虑为回退值,但是部分有特殊含义的字符除外,例如换行符、不匹配的右括号(如 )、] 或 })、感叹号以及顶层分号(不被任何非 var() 的括号包裹的分号。 回退值并不是用于实现浏览器兼容性的。如果浏览器不支持 CSS 自定义属性,回退值也没什么用。它仅对支持 CSS 自定义属性的浏览器提供了一个回退机制,该机制仅当给定值未定义或是无效值的时候生效。
传统的 CSS 概念里,有效性和属性是绑定的,这对自定义属性来说并不适用。当自定义属性值被解析,浏览器不知道它们什么时候会被使用,所以必须认为这些值都是有效的。但当通过 var() 函数调用时,它在特定上下文环境下也可能不会奏效。因此,当浏览器遇到无效的 var() 时,会使用继承值或初始值代替,即非 var 计算的 CSS 属性 - 值对中存在语法错误,该行则会被忽略,然而如果自定义属性的值无效,它并不会被忽略,从而会导致该值被覆盖为默认初始值。
22 交互
touch-action 属性用于设置触摸屏用户如何操纵元素的区域(例如,浏览器内置的缩放功能)。
23 CSS Houdini
Houdini 是一组底层 API,它们公开了 CSS 引擎的各个部分,从而使开发人员能够通过参加浏览器渲染引擎的样式和布局过程来扩展 CSS。Houdini 是一组 API,它们使开发人员可以直接访问CSS 对象模型 (CSSOM),编写浏览器可以解析为 CSS 的代码,从而创建新的 CSS 功能,而无需等待它们在浏览器中本地实现。
CSS 属性和值 API
CSS 属性和值 API 允许开发者显式地定义它们的 CSS 自定义属性(值使用 var() 函数访问),允许设置属性类型检查、默认值以及是否可继承其值。
@property <custom-property-name> {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
@property
规则中 syntax 和 inherits 描述符是必需的; 如果其中任何一项缺失,整条规则都将失效并且会被忽略。initial-value 描述符仅在 syntax 描述符为通用 syntax 定义时是可选的,否则initial-value 也是必需的且此时如果该描述符缺失,整条规则都将失效且被忽略。未知的描述符自身都是无效的,且会被忽略,但是不会造成整条 @property
规则的失效。
24 其他 CSS 属性
-webkit-box-reflect 属性可使得元素内容在特定方向上进行轴对称反射。语法:-webkit-box-reflect: [above|below|right|left] <length> <image>;其中,[above、below、right、left] 关键字指示反射发生的方向,<length> 指示反射的大小,<image> 描述要应用于反射的遮罩。firefox 不支持此属性。
mask(mask-image,mask-mode、mask-repeat、mask-position、mask-clip、mask-origin、mask-size、mask-composite)简写属性通过在特定点遮罩或剪切图像来隐藏部分或全部元素。mask 会将 mask-border 重置为其初始值。使用 mask 优于使用其他简写或者各自属性的设置来覆盖,这能保证 mask-border 也会重新设置为新的效果样式。
mask-image 属性设置了用作元素遮罩层的图像。默认情况下,这意味着遮罩图像的 alpha 通道将与元素的 alpha 通道相乘。可以使用 mask-mode 属性对此进行控制。取值:
- none 初始值,即透明的黑色图像层,也就是没有遮罩层,
- <mask-source> 对 <mask> 或 CSS 图像的 url() 引用
- <image> 用作 mask 图像层的图像值
mask-mode 属性指示由 mask-image 指向的遮罩被视为亮度或阿尔法遮罩。目前仅 firefox 和sarfari 支持。取值:
- alpha 指示应使用遮罩层图像的透明度(阿尔法通道)值作为遮罩值。
- luminance 指示遮罩层图像的亮度值应用作遮罩值。
- match-source 如果 mask-image 属性是<mask-source>类型,遮罩层图像的亮度值会被作为遮罩值。如果它是类型<image>,遮罩层图像的 alpha 值应用作遮罩值。
mask-composite 属性表示对当前遮罩层与其下方的遮罩层使用的合成操作。目前仅 firefox 和 sarfari 支持。对于合成,当前遮罩层称为源,而其下方的所有层称为目标。取值:
- add 默认值,源放置在目标上方。
- subtract 源被放置在目标之外的位置。
- intersect 源中与目标重叠的部分将替换目标。
- exclude 源和目的地的不重叠区域被组合。
aspect-ratio 属性为盒子规定了首选纵横比,该纵横比可以用于计算 auto 尺寸以及其他布局函数。该属性指定为关键字 auto 或 <ratio> 之一或两者。若两者都给定且该元素是替换元素,例如 <img>,则使用给定的 <ratio>,直到内容加载完毕后应用 auto 值即使用所加载内容的固有宽高比;如果该元素不是替换元素,则使用给定的比率 <ratio>。其中:
- auto 初始值,具有固有纵横比的可替换元素将使用固有纵横比,涉及固有纵横比的尺寸计算始终使用内容盒的尺寸。
- <ratio> 盒子的首选纵横比为指定的 width / height 比率。如果省略 height 和前面的斜杠字符,则 height 默认为 1。涉及首选纵横比的尺寸计算使用由 box-sizing 所指定的盒子的尺寸。width 和 height 至少一个是 auto,<ratio> 才会生效。
scroll-behavior 属性当用户手动导航或者 CSSOM scrolling API 触发滚动操作时为一个滚动框指定滚动行为,其他任何的滚动(例如用户执行的滚动),不受这个属性的影响。当在根元素上指定此属性时,它会应用于视口。在 body 元素上指定的此属性不会传播到视口。取值:
- auto 初始值,滚动盒子瞬间完成滚动。
- smooth 滚动盒子通过一个用户代理预定义的时长、使用预定义的时间函数,来实现平稳的滚动。
writing-mode 属性定义了文本水平或垂直排布以及在块级元素中文本的行进方向。为整个文档设置该属性时,应在根元素上设置它(对于 HTML 文档,应该在 html 元素上设置)。此属性指定块流动方向,即块级容器堆叠的方向,以及行内内容在块级容器中的流动方向。因此,它也确定块级内容的顺序。水平流动方向也受文本的方向影响,从左到右(ltr,例如英语和大多数其他语言)或从右到左(rtl,例如希伯来语或阿拉伯语)。取值:
- horizontal-tb:初始值,对于左对齐(ltr)文本,内容从左到右水平流动。对于右对齐(rtl)文本,内容从右到左水平流动。下一水平行位于上一行下方。
- vertical-lr:对于左对齐(ltr)文本,内容从上到下垂直流动,下一垂直行位于上一行右侧。对于右对齐(rtl)文本,内容从下到上垂直流动,下一垂直行位于上一行左侧。
- vertical-rl:对于左对齐(ltr)文本,内容从上到下垂直流动,下一垂直行位于上一行左侧。对于右对齐(rtl)文本,内容从下到上垂直流动,下一垂直行位于上一行右侧。
cursor 属性设置光标的类型(如果有),在鼠标指针悬停在元素上时显示相应样式。cursor 属性为可以有零个或多个 <url> 值,指向图片文件,它们之间用逗号分隔,最后必填一个关键字值作为备用。每个<url>指向一个图像文件。浏览器将尝试加载指定的第一个图像,如果无法加载则返回下一个图像,如果无法加载图像或未指定图像,则使用关键字值代表的指针类型。每个 <url> 后面都可选跟一对空格分隔的小于 32 的无单位非负数字<x> <y>表示偏移。它们用来设置指针的热点 (即自定义图标的实际点击位置),位置相对于图标的左上角。
clip-path 属性使用裁剪方式创建元素的可显示区域。区域内的部分显示,区域外的隐藏。该属性指定为下面列出的值的一个或多个值的组合:
- none:默认初始值,不创建剪切路径。当计算值不为 none 时,会创建新的层叠上下文,就像 opacity 的值不为 1 时那样。
- <clip-source>:用 url() 引用 SVG 的 <clipPath> 元素。
- <basic-shape>:一种形状,其大小和位置由 <geometry-box> 的值定义。如果没有指定 <geometry-box>,则将使用 border-box 用为参考盒。取值可为以下值中的任意一个:
- inset(<length-percentage>{1,4}, <border-radius> ?) :定义一个 inset 矩形。当四个参数<length-percentage>都被提供时,它们代表了从参考盒向内的上、右、下和左的偏移量,定义了嵌入矩形的边缘位置。这些参数遵循 margin 速记的语法。可选的 <border-radius> 参数使用 border-radius 简写语法定义插入矩形的圆角。
- circle(<shape-radius> [at <position>]?) :使用半径<shape-radius>(可以是<length> 或 <percentage> 或closest-side(从中心出发的最短距离,对于圆来说就是半径)和 farthest-side(从中心出发的最长距离,对于圆来说就是半径))和圆心位置<position>定义一个圆形。
- ellipse(<shape-radius> [at <position>]?) :使用两个半径<shape-radius>(可以是<length> 或 <percentage> 或 closest-side(从中心出发的最短距离,对于椭圆来说就是短半轴)和 farthest-side(从中心出发的最长距离,对于椭圆来说就是长半轴))和圆心位置<position>定义一个椭圆。
- polygon([<'fill-rule'>,]?[<length-percentage><length-percentage>]#) :使用一个可选的 SVG 填充规则 <'fill-rule'> 和一组顶点 [<length-percentage><length-percentage>](三对或更多对值(多边形必须至少绘制一个三角形)。这些值是参考参考框绘制的坐标。)定义一个多边形。
- path([<'fill-rule'>,]?<string>):使用一个可选的 SVG 填充规则<'fill-rule'>(路径内部的填充规则。可能的值是 nonzero 或 evenodd。默认值为 nonzero)和一个 SVG 路径<string>定义定义一个任意形状。
- <geometry-box>:如果同 <basic-shape> 一起声明,它将为 <basic-shape> 提供相应的参考盒。通过自定义,它将利用确定的盒子边缘包括任何形状边角。
- margin-box:使用 margin box 作为参考盒。
- border-box:使用 border box 作为参考盒。
- padding-box:使用 padding box 作为参考盒。
- content-box:使用 content box 作为参考盒。
- fill-box:利用对象边界框(object bounding box)作为参考盒。
- stroke-box:使用笔触边界框(stroke bounding box)作为参考盒。
- view-box:使用最近的 SVG 视口(viewport)作为参考盒。如果 viewBox 属性被指定来为元素创建 SVG 视口,参考盒将会被定位在坐标系的原点,参考盒位于由 viewBox 属性建立的坐标系的原点,参考盒的尺寸用来设置 viewBox 属性的宽高值。
box-decoration-break 属性用来定义当元素跨多行、多列或多页时,元素的片段应如何呈现。指定的值将影响元素 background、border、border-image、box-shadow、clip-path、margin、padding 属性的表现。除 firefox 之外,需要添加前缀 -webkit-。取值有:
- slice:默认值,元素被按照盒子被切割前的原始样式渲染,之后,针对每个行/列/页面将此盒子渲染成片段。请注意,盒子对于每个片段可以是不同的,因为如果中断发生在行内方向,则它使用自己的高度,如果中断发生在块方向,则它使用自己的宽度。
- clone:每个盒片段与指定的 border、padding 和 margin 独立呈现。border-radius、border-image、box-shadow 独立地应用于每个片段,每个片段的 background 也是独立绘制的,这意味着使用 background-repeat: no-repeat 的背景图片仍然可能重复多次。
25 CSS 动画:基础知识与性能优化
26 属性书写顺序
推荐属性顺序:all > 定位 > 盒模型 > 排版 > 可访问性与交互 > 视觉 > 动画;
除了 all以外,定位是第一位的,因为它可以从正常的文档流中移除一个元素并覆盖与盒子模型相关的样式。盒模型——无论是 flex、float、grid 还是 table——都遵循规定了盒的尺寸、放置和对齐方式。其他一切都发生在盒内部或不影响前两个部分,因此它们排在最后。
all:
定位:
盒模型:
排版:
可访问性与交互:
视觉:
动画:
27 兼容性与 hack
hack 是为了处理不同浏览器之间差异的兼容性写法,带前缀的属性写在前,标准属性写在后面。缺点是难理解、难维护、易失效,替代方案有:
- 特性检测
- 针对性加 class;
常见兼容性问题:
28 图片
CSS Sprites(雪碧图):将多个小图片合并成一张图,通过 CSS 的 background-position 来定位展示需要显示的图片部分。优缺点如下:
base64 编码图片(Data URI Scheme):对于编码后数据量不大的图采用,成为 HTML 内的静态资源,不会发起 http 请求,不存在图片更新需要重新上传的问题和清理缓存的问题。缺点:base64 会增加图片大小,使整体下载量增加;由于是内联在页面中,不会被缓存。不适合用于懒加载中。移动端性能优先并不适宜用,解码会耗费 CPU。
压缩或拉伸图片:用 CSS 调整一张图片的尺寸时,如果纵横比与图片的原始宽高不一致,则图片会被压缩或拉伸。解决办法是使用 object-fit 属性。
object-fit 属性指定可替换元素(例如:<img> 或 <video>)的内容应该如何适应到其使用高度和宽度确定的框( 有些类似于 background-size) 。
object-position 属性 指定可替换元素的内容对象内容框中的位置,(类似于 background-position ),允许被替换元素的对象被定位到内容框外部,可替换元素的内容框中未被对象所覆盖的部分,则会显示该元素的背景。
图片加载异常处理方案
原理:img 和 srcipt 标签的 error 并不会冒泡,但是会经历捕获阶段和处于目标阶段。给 img元素添加 onerror 监听的方案就是利用处于目标阶段触发事件函数,但 onerror 已经废弃,因此可以在捕获阶段截获并触发函数,从而减少性能损耗。
具体实现:为每个 img 标签额外添加一个 data-retry-times 计数属性,捕获到错误,当重试超过限制次数后就用表示网络异常的 base64 图片作为兜底。
// 在捕获阶段进行图片兜底处理
document.addEventListener('error', (event) => {
let { target } = event;
const targetName = targetName || '';
if (tagName.toLowerCase() !== 'img') return;
const curTimes = Number(target.dataset.retryTimes) || 0;
if (curTime >= 3) {
// 网络异常:重试次数超过 3 次,就使用代表网络异常的 base64 图片兜底
target.src = 'data:image/png;base64,xxxxx';
} else {
// 原始图片异常:直接重试
target.dataset.retryTimes = curTimes + 1;
target.src = target.src; // 重复赋值,会再请求一次
}
target = null;
}, true);
如果图片使用 CDN,也就可能是 CDN 存在节点覆盖不全的问题,使得 DNS 查询超时导致图片加载失败,可以通过切换 domain 来尝试:文章来源:https://www.toymoban.com/news/detail-665715.html
/* 方式 1. 主动去嗅探可用的 cdn 域名 */
const cdnDomains = [
'https://sf2-xxx.xxx.com',
'https://sf4-xxx.xxx.com',
'https://sf5-xxx.xxx.com',
'https://sf6-xxx.xxx.com',
]
/* 方式 2. 不用主动嗅探,改为直接从服务器获取可用的 cdn */
getUsefulDomains().then(res => {
window.cdnDomains = res.data.imgDomains || '';
}
// 防止嗅探图片出现缓存,添加时间戳保持新鲜度
export const imgUri = `/img/xxx?timestamp=${Date.now()}${Math.random()}`;
export const validateImageUrl = (url: string) => {
return new Promise<string>((resovle, reject) => {
const img = new Image();
// 由于 Image 图片加载没有超时机制以及 Promise 状态的不可变性,借助 setTimeout 来模拟超时
const timer = setTimeout(() => {
clearTimeout(timer);
reject(new Error('image load timeout'));
}, 5000);
img.onload = () => {
clearTimeout(timer);
resolve(url);
}
img.onerror = (err: string | Event) => {
clearTimeout(timer);
reject(err);
}
});
}
export const setCDNDomain = () => {
const cdnLoop = () => {
return Promise.race(
cdnDomains.slice(1).map((domain: string) => validateImageUrl(domain + imgUri))
).then((url) => {
window.shouldReplaceDomain = true;
const urlHost = url.split('/')[2];
window.replaceDomain = urlHost;
});
}
return validateImageUrl(`${originDomain}${imgUri}`).then(() => {
window.shouldReplaceDomain = false;
window.replaceDomain = '';
}).catch(() => {
return cdnLoop();
});
}
// 图片出现异常时调用,替换掉 URL
export const replaceImgDomain = (scr: string) => {
if (src && window.showRelpaceDomain && window.replaceDomain) {
return src.replace(originDomain.split('/')[2], window.replaceDomain);
}
return src;
}
而对于背景图像 background-image,背景图元素没有 error 事件,本身也就无法捕获 error 事件。可以使用合适的 background-color,在背景图像加载失败时兜底。或者创建自定义事件,嗅探图片资源情况并抛出错误事件即可:文章来源地址https://www.toymoban.com/news/detail-665715.html
// 自定义 background-image error 事件
const event = new Event('bgImgError');
// 适合较少的背景图像
validateImageUrl('xxx.png').catch((err) => {
let ele = document.getElementById('bg-img');
if (ele) {
ele.dispatchEvent(event);
}
ele = null;
})
document.addEventListener('bgImgErro', (event) => {
e.target.style.backgroundImage = "url(data:image/png;base64,xxxxx";
}, true);
29 CSS 实现:常见几何图形绘制
30 CSS 实现:常见布局
30 CSS 中的前端工程化:预编译器与后处理器
31 CSS 换肤方案
到了这里,关于前端需要理解的CSS知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!