CSS重学
一种属性化 解释性的键值对语言
内部的属性赋值流程被成为声明语句块
参考1.5 万字 CSS 基础拾遗(核心知识、常见需求) - 掘金 (juejin.cn)
CSS的运行原理
浏览器在扫描器工作后生成了存在于内存中DOM树文档流,在扫描css生成CSSOM树,结合二者生成渲染树。
通过css的选择器机制绑定两者便是渲染树的生成。(具体看我浏览器渲染原理章节)
CSS语法规则:
css的声明块加上选择器组成了css的规则集。
1.普通规则:(难以详尽,如有特别再进行补充)
**2.@规则:**在一般规则选择器加语句块下,已经基本能进行css与html的绑定,但是一些额外的操作例如:字符集,导入其它的外部样式表,字体等,这些需要专门的语句表示
@规则根据使用方法的不同又可以分为“常规规则”与“嵌套规则”两种。
所谓“常规规则”指的是语法类似下面的规则:
@[KEYWORD] (RULE);
CSS @规则(详细) (biancheng.net)
简单枚举一下他们的用途:
常规规则里有以下几个:
@charset:设置CSS文件使用的字符编码,他是网络流传播页面的一种字符规则设置之一,且优先级靠后不做特殊解释。 多个charset中只有首个会生效
特殊规则:字符集编码规则
- HTML 文件开头的字符编码声明;
- HTTP 请求头中的字符编码声明;
- CSS 文件中使用 @charset 定义的字符编码声明;
@import:请求加载合并多种的外部样式,头部声明状态,更语言化。
@import会建立请求连接,占用连接池,且会有数量限制
@import <media_query_list>:其中, 为使用绝对或相对路径指定的要导入的外部样式表文件路径,也可以使用 url() 函数来指定文件路径;<media_query_list> 为可选参数,用来指定媒体查询的条件,多个条件之间使用逗号
,
分隔。在媒体查询生效条件下导入。 @namespace:相当于是一种作用域规则,避免重复定义覆盖//规定作用域后 加上前缀可以处理多个命名空间的文档和隔绝SVG
关于xmlns在html标签上标明此属性,可以为该文档配置命名空间,@namespace处理命名空间的别名在css文档中使用,达到选择效果
嵌套规则:
所谓“嵌套规则”指的就是在 @规则后面需要跟随一个花括号
{ }
,其中包含了一些其它的规则声明 @media:媒体查询是用于判断设备信息的一组条件,如设备的宽高值,宽高比,颜色,分辨率等,当条件匹配时,才会执行其内嵌套的样式信息。(用于多端)
@page:前端文档打印时修改一些CSS属性;
@supports:条件判断浏览器是否支持某一种css特性;
@font-face: 请求加载对应需要的字体资源 需要一些特定参数
@keyframes:定义css3中的animation动画关键帧,预设一些动画模板,匹配一些预定义的属性(如animation-name:, animation-duration等)与定义的动作模型相互匹配。
@document:用来根据文档的 URL 限制文档中样式的作用范围,通过该属性可以为指定用户定义专属的样式。
总结:让css能更灵活,能复用,能多端,能预设,能语言,面向特征化。
语言特征
三大特性:
1.层叠性:CSS的核心特性之一,例如来自多个源定义的css规则该如何采用,执行的结果是怎样兼容的。
2.继承性:CSS中的某些样式具有继承性,它允许样式不仅应用于某个特定HTML标签,而且应用于其后代。(一定程度的继承避免了代码冗余)
3.CSS重要性:权重占比。
样式层叠的优先级:
CSS规定基本选择器的优先级从低到高排序为:元素(标记)样式 < 类别(class)样式 < ID样式 < 行内样式 < !important。
优先级的排布采用01规则(采用5个bit位的1所在来标识)
- 10000:!important;
- 01000:内联样式;
- 00100:ID 选择器;
- 00010:类选择器、伪类选择器、属性选择器;
- 00001:元素选择器、伪元素选择器;
- 00000:通配选择器、后代选择器、兄弟选择器;
继承特性带来的好处:
不会影响到页面布局的属性一般都会被继承
那么哪些属性可以默认继承呢?
字体相关:
font-family
、font-style
、font-size
、font-weight
等;文本相关:
text-align
、text-indent
、text-decoration
、text-shadow
、letter-spacing
、word-spacing
、white-space
、line-height
、color
等;列表相关:
list-style
、list-style-image
、list-style-type
、list-style-position
等;其他属性:
visibility
、cursor
等;
对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为:
inherit
:继承父元素对应属性的计算值;直接取父级
initial
:应用该属性的默认值,比如 color 的默认值是#000
;
unset
:如果属性是默认可以继承的,且父级定义,则取inherit
的值,否则重新设置为初始状态;
revert
:效果等同于unset
,兼容性差。
无继承性的属性:(一般都是一些特征属性,且继承无用)
display:规定元素应该生成的框的类型
文本属性:
vertical-align:垂直文本对齐
text-decoration:规定添加到文本的装饰
text-shadow:文本阴影效果
white-space:空白符的处理
unicode-bidi:设置文本的方向
盒子模型的属性:width、height、margin~~20多个包括内外编剧等
背景属性:background、background-color、background-image、background-repeat、background-position、background-attachment
定位属性:float、clear、position、top、right、bottom、left、min-width、min-height、max-width、max-height、overflow、clip、z-index
生成内容属性:content、counter-reset、counter-increment
轮廓样式属性:outline-style、outline-width、outline-color、outline
页面样式属性:size、page-break-before、page-break-after
声音样式属性:pause-before、pause-after、pause、cue-before、cue-after、cue、play-during
选择器
资源:(139条消息) CSS的四种基本选择器和四种高级选择器_是加油呀的博客-CSDN博客_基础选择器
CSS 选择器 - CSS(层叠样式表) | MDN (mozilla.org)
就是指定CSS要作用的标签,那个标签的名称就是选择器。意为:选择哪个容器
一般来说分为两个大类:基本选择器和扩展选择器:
*基本选择器(为通用)
1.标签选择器:指定的已定义的标签都将被选择
2.ID选择器:#定义的特定标签(id值唯一)所以只能使用一次的选择器
3.类选择器: 采用 . 标识,匹配元素的class属性(字符串绑定的灵活性,让类尽量能复用)
4.属性选择器:在html元素的属性上做选择,挑选出含有匹配模板属性的标签元素。
总结:类上样式,id上行为
高级选择器
1.后代选择器:通过对dom树结构的扫描,对祖先结构判断后叠加 采用空格分隔(中间不用空格 用>符号的是直接子代组合器)
语法:A B 例子:div span
2.交集选择器:不用空格做分隔,同时拥有需要的选择器时,随后的样式才会生效
语法:AB 例子:.ss.aa
3.并集选择器:采用,分割(一个样式多写,减少代码书写)
4.伪类选择器:CSS允许对于元素的不同状态,定义不同的样式信息(一般采用:)
1.静态伪类:只能用于超链接。(匹配文档树中的状态信息)
2.动态伪类:针对所有的标签都适用(浏览器补做一些状态行为做为了元素的属性时,可选择)
条件伪类
:lang()
:基于元素语言来匹配页面元素;:dir()
:匹配特定文字书写方向的元素;:has()
:匹配包含指定元素的元素;:is()
:匹配指定选择器列表里的元素;:not()
:用来匹配不符合一组选择器的元素;行为伪类
:active
:鼠标激活的元素;:hover
: 鼠标悬浮的元素;::selection
:鼠标选中的元素;状态伪类
:target
:当前锚点的元素;:link
:未访问的链接元素;:visited
:已访问的链接元素;:focus
:输入聚焦的表单元素;:required
:输入必填的表单元素;:valid
:输入合法的表单元素;:invalid
:输入非法的表单元素;:in-range
:输入范围以内的表单元素;:out-of-range
:输入范围以外的表单元素;:checked
:选项选中的表单元素;:optional
:选项可选的表单元素;:enabled
:事件启用的表单元素;:disabled
:事件禁用的表单元素;:read-only
:只读的表单元素;:read-write
:可读可写的表单元素;:blank
:输入为空的表单元素;:current()
:浏览中的元素;:past()
:已浏览的元素;:future()
:未浏览的元素;结构伪类
:root
:文档的根元素;:empty
:无子元素的元素;:first-letter
:元素的首字母;:first-line
:元素的首行;:nth-child(n)
:元素中指定顺序索引的元素;:nth-last-child(n)
:元素中指定逆序索引的元素;;:first-child
:元素中为首的元素;:last-child
:元素中为尾的元素;:only-child
:父元素仅有该元素的元素;:nth-of-type(n)
:标签中指定顺序索引的标签;:nth-last-of-type(n)
:标签中指定逆序索引的标签;:first-of-type
:标签中为首的标签;:last-of-type
:标签中为尾标签;:only-of-type
:父元素仅有该标签的标签;
5.序选择器:对列表的特殊选择:last-child :first-child多种筛查
6.一般兄弟选择器:~匹配同级父元素的下的所有同元素
语法:A ~ B 例子:p ~ span
7.紧邻的兄弟组合器:+选择相邻元素,共享父节点且紧邻
语法:A + B 例子:h2 + p
8.列组合器:采用||匹配表格内的节点
语法: A || B 例子: col || td
9.伪元素选择器:表示所有无法用HTML语义表达的实体:也是需要浏览器执行时参照的。具体看HTML章节
文档流
什么是文档流?
(引用)在 CSS 的世界中,会把内容按照从左到右、从上到下的顺序进行排列显示。正常情况下会把页面分割成一行一行的显示,而每行又可能由多列组成,所以从视觉上看起来就是从上到下从左到右,而这就是 CSS 中的流式布局,又叫文档流。文档流就像水一样,能够自适应所在的容器。
关于文档流的两种元素:
块级元素 和 内联元素的排版规划在浏览器里不一样:
块级元素默认会占满整行,所以多个块级盒子之间是从上到下排列的;
- 可以设置其宽度、高度,内外边距
- 可以充当容器的作用 嵌套其他块
内联元素默认会在一行里一列一列的排布,当一行放不下的时候,会自动切换到下一行继续按照列排布;
- 不可以设置宽高 ,可设置水平方向的padding和margin,垂直方向上,都无效;(padding-top和padding-bottom会显示出效果,但是高度不会撑开,不会对周围元素有影响)
- 默认宽度是自身宽度
行内块元素可以设置宽高和内边距
块级元素和内联元素的相互转换,给其添加display:属性,当属性值为block时为块级,inline为行级元素。
css中的定位机制:
- 正常的文档流
- float
- postion
如何脱离正常的文档流?
目前存在三种状况将使得元素可以离开文档流而存在,分别是浮动、绝对定位、固定定位。
基于文档流,先了解定位的形式:
相对定位:元素框偏移某个距离。元素仍保持其未定位前的形状,它原本所占的空间仍保留。
绝对定位:即完全离开文档流, 相关于position属性非static值的比来父级元素进行偏移。
固定定位:即完全离开文档流,相关于视区进行偏移。
position脱离文档流:
绝对定位脱离文档流:
绝对定位absolute的特性在于:元素加上该属性后脱离文档流,且它之后的定位会基于第一个有定位属性的(即 position 为 relative 或者 absolute)的祖先元素;(如没有,则定位文档body体)
高级特性:自动伸缩的功能,当我们将 width 设置为 auto 的时候,绝对定位元素会根据其 left 和 right 自动伸缩其大小。(如果我们设置 left 和 right 都为0,则该元素会填充满其相对的元素)–>如果宽度为固定值其margin会按照父元素做比较 此时可以auto居中该属性。
其层叠通过z-index属性定义(合成层和层重叠)
固定定位脱离文档流:
特征:它以浏览器的可视窗口为参考点的移动元素,不会随滚动条移动,且脱离文档流,不占用位置。
相对定位:relative,但将依据left,right,top,bottom等属性在正常文档流中偏移位置。当对象定位在浏览器窗口以外,浏览器因此显示滚动条。不脱离文档流 ,占空间,可使用left等做偏移。
浮动定位float脱离文档流:
特性:CSS浮动float详解 - 简书 (jianshu.com)
1.float后的元素会丢掉原有的行块元素特性,会失去占满一行特征,类似于inline元素一样产生包裹性,宽度也自适应,但可以定义宽高。
2.内层元素float后不参与其外层的高度计算,认为该元素的行内高度为0,但浮动元素高度不为0,内层进行了高度塌陷,但是内层的元素在参与文档流布局时,依然会被浮动元素占据位置。
也就是形成一个文字环绕的效果(浮动元素占文档计算位置)
解决上述虚假浮动的方式就是清除浮动,采用clear隔离浮动元素和其他元素。
高度塌陷解决
闭合浮动 让父元素采用BFC,重新获得计算后该有的高度。
清除浮动:通过计算BFC来去除高度塌陷。或者利用伪元素设置clear强制移动到浮动元素之后,使得浮动元素参与高度计算。
盒模型
简单说明:因为css中的任何元素都可以看作成一个盒子模型由4个部分组成:
内容(content)、内边距(padding)、边框(border)和外边距(margin)
由此:盒子大小是等于盒子的实际尺寸 = 内容(设置的宽/高) + 内边距 + 边框
注意:但这是标准的盒模型与ie的模型不同(已基本废弃)
选择:CSS3 中新增了一个属性 box-sizing
(以其两个属性做为标准)
content-box
:标准盒模型;border-box
:IE 盒模型//计算方式相反 直接明确盒子的宽高
盒子的类型由display决定:决定其对应的显示类型(对外显示|对内显示)关于display的属性值:常用的有:block
, inline-block
, none
, table
, line
视觉格式化模型
视觉格式化模型(Visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。
CSS 中一切皆盒子,而视觉格式化模型简单来理解就是规定这些盒子应该怎么样放置到页面中去,这个模型在计算的时候会依赖到很多的因素,比如:盒子尺寸、盒子类型、定位方案(是浮动还是定位)、兄弟元素或者子元素以及一些别的因素。
给一个元素设置 display 后,将会决定这个盒子的 2 个显示类型(display type):
outer display type(对外显示):决定了该元素本身是如何布局的,即参与何种格式化上下文;
inner display type(对内显示):其实就相当于把该元素当成了容器,规定了其内部子元素是如何布局的,参与何种格式化上下文;
outer display type:
对外的显示方面:一般可以分为块级的盒子block 和行内级的盒子inline。
所有块级盒子都会参与 BFC,呈现垂直排列;而所有行内级盒子都参会 IFC,呈现水平排列。
详细的一些区别参数:
1.block:占满一行,继承父元素宽度,BFC排列 可以设置宽高 和内外边距
2.inline:不占满一行,宽度被内容撑开,内元素自动换行,且不能设置宽高和竖直方向的内外边距(因为它是撑开的模型)
3.inline-block:行内块元素,能设置宽高和内外编剧
inner display type
对内方面,其实就是把元素当成了容器,里面包裹着文本或者其他子元素。container box 的类型依据 display 的值不同,分为 4 种:
1.block container:建立的是BFC或者IFC
2.flex container: 建立FFC;
3.Grid container :建立GFC;
4.ruby container;
格式化上下文:
页面中的一块渲染区域,规定了渲染区域内部的子元素是如何排版以及相互作用的。
不同类型的盒子有不同格式化上下文,大概有这 4 类:
1.BFC (Block Formatting Context) 块级格式化上下文;
2.IFC (Inline Formatting Context) 行内格式化上下文;
3.FFC (Flex Formatting Context) 弹性格式化上下文;
4.GFC (Grid Formatting Context) 格栅格式化上下文;
BFC:(块格式化上下文)
块格式化上下文,它是一个独立的渲染区域,只有块级盒子参与,它规定了内部的块级盒子如何布局,并且与这个区域外部毫不相干(盒子套用 小窗口)
思路:隔离了外部环境,只关心其内部如何。
其渲染规则:
1.内部的盒子会在垂直方向,一个接一个地放置;
2.盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠;
3.每个元素的 margin 的左边,与包含块 border 的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此;
4.BFC 的区域不会与 float 盒子重叠;
5.BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
6.计算 BFC 的高度时,浮动元素也参与计算。(盒子内的浮动元素也参与计算)
触发BFC规则:
- body 根元素
- 浮动元素:float 除 none 以外的值//浮动元素内部生成BFC
- 绝对定位元素:position (absolute、fixed)//内部生成隔离域
- display 为 inline-block、table-cells、flex
- overflow 除了 visible 以外的值 (hidden、auto、scroll)//可以用此解决高度塌陷
特性:
1.同一个BFC下的元素外边距会发生重叠
2.BFC内可以包含浮动的元素 (清除浮动的效果)
3.BFC可以阻止浮动元素覆盖
总结:BFC是具有隔离性的独立盒子模型
IFC:
IFC 的形成条件非常简单,块级元素中仅包含内联级别元素,需要注意的是当IFC中有块级元素插入时,(会产生两个匿名块将父元素分割开来,产生两个 IFC。)
其渲染规则:
1.子元素在水平方向上一个接一个排列,在垂直方向上将以容器顶部开始向下排列;
2.节点无法声明宽高,其中 margin 和 padding 在水平方向有效在垂直方向无效;
3.节点在垂直方向上以不同形式对齐;
4.能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的线盒(line box)。线盒的宽度是由包含块(containing box)和与其中的浮动来决定;
5.IFC 中的 line box 一般左右边贴紧其包含块,但 float 元素会优先排列。
6.IFC 中的 line box 高度由 line-height 计算规则来确定,同个 IFC 下的多个 line box 高度可能会不同;
7.当内联级盒子的总宽度少于包含它们的 line box 时,其水平渲染规则由 text-align 属性值来决定;
8.当一个内联盒子超过父元素的宽度时,它会被分割成多盒子,这些盒子分布在多个 line box 中。如果子元素未设置强制换行的情况下,inline box 将不可被分割,将会溢出父元素。
IFC 应用场景
水平居中:当一个块要在环境中水平居中时,设置其为 inline-block 则会在外层产生 IFC,通过 text-align 则可以使其水平居中。//
垂直居中:创建一个 IFC,用其中一个元素撑开父元素的高度,然后设置其 vertical-align: middle,其他行内元素则可以在此父元素下垂直居中。//
FFC
CSS3引入了一种新的布局模型——flex布局。
flex是flexible box的缩写,一般称之为弹性盒模型。和CSS3其他属性不一样,flexbox并不是一个属性,而是一个模块,包括多个CSS3属性。flex布局提供一种更加有效的方式来进行容器内的项目布局,以适应各种类型的显示设备和各种尺寸的屏幕,使用Flexbox布局实际上就是声明创建了FFC(自适应格式上下文)
GFC
CSS3引入的一种新的布局模型——Grids网格布局,目前暂未推广使用,使用频率较低,简单了解即可。
Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。
Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。
层叠上下文
众 HTML 元素依据自己定义的属性的优先级在 Z 轴上按照一定的顺序排开,而这其实就是层叠上下文所要描述的东西。
(z-index属性)关于z-index属性的一些特性:
z-index 能够在层叠上下文中对元素的堆叠顺序其作用是必须配合定位才可以;
除了 z-index 之外,一个元素在 Z 轴上的显示顺序还受层叠等级和层叠顺序影响;
如何产生一个层叠上下文?
特定的 HTML 元素或者 CSS 属性产生层叠上下文
html 文档根元素
声明 position: absolute/relative 且 z-index 值不为 auto 的元素;//有定位
声明 position: fixed/sticky 的元素;
flex 容器的子元素,且 z-index 值不为 auto;
grid 容器的子元素,且 z-index 值不为 auto;
opacity 属性值小于 1 的元素;
mix-blend-mode 属性值不为 normal 的元素;表示应该应用的混合模式
以下任意属性值不为 none 的元素:
- transform
- filter//CSS属性
filter
将模糊或颜色偏移等图形效果应用于元素。- perspective//CSS 属性 **
perspective
**指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。- clip-path//clip-path CSS 属性使用裁剪方式创建元素的可显示区域。区域内的部分显示,区域外的隐藏。
- mask / mask-image / mask-border//
isolation 属性值为 isolate 的元素;//
isolation
CSS 属性定义该元素是否必须创建一个新的层叠上下文-webkit-overflow-scrolling 属性值为 touch 的元素;
will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素;
contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素//contain** 属性允许开发者声明当前元素和它的内容尽可能的独立于 DOM 树的其他部分。
层叠等级:
在同一个层叠上下文中,它描述定义的是该层叠上下文中的层叠上下文元素在 Z 轴上的上下顺序;
在其他普通元素中,它描述定义的是这些普通元素在 Z 轴上的上下顺序;普通节点的层叠等级优先由其所在的层叠上下文决定,层叠等级的比较只有在当前层叠上下文中才有意义,脱离当前层叠上下文的比较就变得无意义了。
层叠顺序:
层叠上下文的 border 和 background
z-index < 0 的子节点
标准流内块级非定位的子节点
浮动非定位的子节点
标准流内行内非定位的子节点
z-index: auto/0 的子节点
z-index > 0的子节点
比较两个元素的层叠等级
在同一个层叠上下文中,比较两个元素就是按照上图的介绍的层叠顺序进行比较。
如果不在同一个层叠上下文中的时候,那就需要比较两个元素分别所处的层叠上下文的等级。(合成层)
如果两个元素都在同一个层叠上下文,且层叠顺序相同,则在 HTML 中定义越后面的层叠等级越高。
关于css的值与单位
数值:长度值 ,用于指定例如元素 width、border-width、font-size 等属性的值;
百分比:可以用于指定尺寸或长度,例如取决于父容器的 width、height 或默认的 font-size;
颜色:用于指定 background-color、color 等;
坐标位置:以屏幕的左上角为坐标原点定位元素的位置,比如常见的 background-position、top、right、bottom 和 left 等属性;
函数:用于指定资源路径或背景图片的渐变,比如 url()、linear-gradient() 等;
特殊单位:
px:屏幕分辨率是指在屏幕的横纵方向上的像素点数量,px 表示的是 CSS 中的像素,在 CSS 中它是绝对的长度单位,也是最基础的单位,其他长度单位会自动被浏览器换算成 px。但是对于设备而言,它其实又是相对的长度单位,自动换算比例。 浏览器结合参数。
概念知识:设备像素(Device pixels),设备像素比(DPR),像素密度(DPI/PPI),设备独立像素(DIP) 有自己的计算公式
em:em 是 CSS 中的相对长度单位中的一个。em 在计算的时候是会层层计算的。
在 font-size 中使用是相对于父元素的 font-size 大小,比如父元素 font-size: 16px,当给子元素指定 font-size: 2em 的时候,经过计算后它的字体大小会是 32px;
在其他属性中使用是相对于自身的字体大小,如 width/height/padding/margin 等
rem:rem(root em) 和 em 一样,也是一个相对长度单位,不过 rem 相对的是 HTML 的根元素 html。
rem 由于是基于 html 的 font-size 来计算,所以通常用于自适应网站或者 H5 中。在根节点定义字体大小或者动态计算一个根节点字大小。便可以动态的进行尺寸定义。
vw/vh:这是基于视口的长度单位
1vw = 视口宽度均分成 100 份中 1 份的长度;
1vh = 视口高度均分成 100 份中 1 份的长度;vmin:取 vw 和 vh 中值较小的;
vmax:取 vw 和 vh 中值较大的;
颜色体系
关于颜色值类型可以分为:
颜色关键字
transparent 关键字
currentColor 关键字
RGB 颜色
HSL 颜色
颜色关键字:颜色关键字(color keywords)是不区分大小写的标识符,它表示一个具体的颜色,比如 white(白),黑(black)等;
transparent:用 transparent 实现三角形的原理就是设置一个边框相邻透明。transparent 关键字表示一个完全透明的颜色,即该颜色看上去将是背景色。 运用(增大点击区域,利用透明的边框增大按钮的点击区域 加大盒子)
currentColor:会取当前元素继承父级元素的文本颜色值或声明的文本颜色值
RGB[A] 颜色:经典函数
HSL[A] 颜色:HSL[A] 颜色是由色相(hue)-饱和度(saturation)-亮度(lightness)-不透明度组成的颜色体系。
Flex布局
在之前格式化上下文的介绍中,我们有提到关于Flex内部生成的上下文(flex container: 建立FFC;),它的作用就是让布局变得简单,
采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”
双轴布局
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。 主要记住 “容器”、“项目”、“主轴(横轴)”和“交叉轴(纵轴)”的意思和指向就行。
开启flex布局
在css中设置display属性为flex 或者 inline-flex之后该标签即可成为Flex container。
flex:Flex container以块级元素存在
inline-flex: Flex container以行内元素存在
容器的属性:
flex-direction 决定主轴的方向,有四个参数描绘主轴的方向。
flex-wrap:元素在轴上排布是否换行,有nowrap,wrap,wrap-reverse(第一行在上下方决定)
flex-flow:flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
justify-content :项目在主轴上的元素对齐方式:
1.flex-start:向主轴的起始位置对齐,从起始位置开始排列。flex-end:向主轴结束位置对齐,也就是从主轴结束的位置开始排列。
2.center: 居中在主轴居中排列
3.space-between:如果有两个以上的项目,则容器主轴的开始和结束位置各一个,其他的项目均匀排列,项目之间的间隔相等。
4.space-around:每个项目两侧的间隔相等。
align-items属性:align-items属性定义项目在交叉轴(纵轴)上如何对齐
1.flex-start:交叉轴的起点对齐。 flex-end:交叉轴的终点对齐。
2.center:交叉轴的中点对齐。
3.baseline:项目的第一行文字的基线对齐。
4.stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content属性:与上面两个主轴排布不同的是,align-content属性定义了多根轴线(多行)的对齐方式。如果项目只有一根轴线(一行),该属性不起作用。
1.stretch(默认值):多行占满整个交叉轴。
2.flex-start:与交叉轴的起点对齐。 flex-start:与交叉轴的起点对齐。
3.center:与交叉轴的中点对齐。
4.space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
5.space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍
项目的属性
order属性;
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
flex-grow属性:flex-grow属性定义项目的放大比例,默认为0。
如果所有的item 的flex-grow的值都是一样的话那就是以item 的width为最小值平均分配主轴上的宽度。如果item没有设置width则所有的item平分主轴上的剩余宽度(多余空间)。
如果item的flex-grow的值不一样,那就是根据对应的比例来分配主轴上的剩余宽度(多余空间)。同样是以item设置的width为最小值。
如果item设置的max-width则放大的宽度不会超过该值。flex-shrink属性:
flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
如果container容器设置的flex-wrap则不存在空间不足的情况,如果超过会自动换行。所以这时候设置flex-shrink也是不起作用的。flex-basis属性:
flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
flex属性:flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。
auto (1 1 auto) 和 none (0 0 auto) 两个快捷值
如果flex-basis的总和计算加起来大于父级,子级被压缩,最后的选择是flex-shrink来进行压缩计算:
加权值 = son1 + son2 + …. + sonN;
压缩的宽度 w = (子元素flex-basis值 * (flex-shrink)/加权值) * 溢出值 //计算shrink所占权 在溢出宽度上挨个减项目
扩张的宽度 w = (子元素flex-grow值 /所有子元素flex-grow的总和) * 剩余值 //增大可扩张的项目
align-self属性:
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
align-self: auto | flex-start | flex-end | center | baseline | stretch;
Grid布局(写的有点乱)
Grid container :建立GFC;
Grid布局优点:这是一个二维布局系统,最大优点就是可以同时处理列和行,不像其他布局那样,主要是一维布局系统。
由行和列组合包围的网格线叫grid item,由最外围的行和列的边框叫grid container。红色的123构成的是行分界线(row grid lines)、黑色的1234构成的是列分界线(column grid lines)
使用 display: grid 将容器元素定义为一个 grid(网格) 布局,使用 grid-template-columns 和 grid-template-rows 设置 列 和 行 的尺寸大小,然后通过 grid-column 和 grid-row 将其子元素放入这个 grid(网格) 中
术语:网格容器(Grid Container),网格项(Grid Item),网格项(Grid Item),网格轨道(Grid Track),网格单元格(Grid Cell),网格区域(Grid Area)
Grid容器属性:
display:将元素定义为网格容器,并为其内容建立新的 网格格式上下文。
grid :生成一个块级网格
inline-grid :生成一个内联网格grid-template-columns / grid-template-rows:网格的行与列:
– : 可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位(剩余可用空间占比))
– :你可以选择的任意名称//这里定义了网格线以及网格线的名称
.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}
.container {
grid-template-columns: 40px 50px auto 50px 40px;//分配数字名称 自动
grid-template-rows: 25% 100px auto;
}
关于分配网格名称:网格名称可以有多个,可以调用repeat()函数实现简化定义,在调用时如果多行共享相同的名称,可以使用其网格线名称和计数来引用他们。
auto-fill 关键字创建适合网格容器的轨道数,而不会导致网格溢出
auto-fit 关键字的行为与 auto-fill 相同,只是在网格项目放置后,它只会根据需要创建任意数量的轨道,并且任何空的重复轨道都会折叠在一起。
grid-template-areas:通过引用 grid-area 属性指定的 网格区域(Grid Area) 名称来定义网格模板。
:由网格项的 grid-area 指定的网格区域名称
.(点号) :代表一个空的网格单元
none:不定义网格区域注意你 不能 用这个语法来命名网格线,只是命名 网格区域 。当你使用这种语法时,区域两端的网格线实际上会自动命名。如果你的网格区域的名字是 foo,该区域的起始行网格线 和 起始列网格线 的名称将为 foo-start,而最后一条行网格线 和 最后一条列网格线 的名称将为 foo-end。这意味着某些网格线可能有多个名字,如上例中最左边的网格线,它将有三个名称:header-start,main-start 和 footer-start 。
grid-template:
用于定义 grid-template-rows ,grid-template-columns ,grid-template-areas 简写属性。
none:将所有三个属性设置为其初始值
/ :将 grid-template-columns 和 grid-template-rows 设置为相应地特定的值,并且设置grid-template-areas为nonegrid-column-gap / grid-row-gap:指定网格线(grid lines)的大小。你可以把它想象为设置列/行之间间距的宽度
grid-gap://值grid-gap: ;
关于Grid的行列对齐:
justify-items:(align-items与之类似)
start:将网格项对齐到其单元格的左侧起始边缘(左侧对齐)
end:将网格项对齐到其单元格的右侧结束边缘(右侧对齐)
center:将网格项对齐到其单元格的水平中间位置(水平居中对齐)
stretch:填满单元格的宽度(默认值)这些行为也可以通过每个单独网格项(grid items) 的 justify-self 属性设置。
place-items
place-items 是设置 align-items 和 justify-items 的简写形式。
:第一个值设置 align-items 属性,第二个值设置 justify-items 属性。如果省略第二个值,则将第一个值同时分配给这两个属性。
justify-content:(align-content)
有时,你的网格合计大小可能小于其 网格容器(grid container) 大小。 如果你的所有 网格项(grid items) 都使用像 px 这样的非灵活单位设置大小,就可能出现这种情况。在这种情况下,您可以设置网格容器内的网格的对齐方式。 此属性沿着 inline(行)轴线对齐网格(相反的属性是 align-content ,沿着 block(列)轴线对齐网格)
start:将网格对齐到 网格容器(grid container) 的左侧起始边缘(左侧对齐)
end:将网格对齐到 网格容器 的右侧结束边缘(右侧对齐)
center:将网格对齐到 网格容器 的水平中间位置(水平居中对齐)
stretch:调整 网格项(grid items) 的宽度,允许该网格填充满整个 网格容器 的宽度
space-around:在每个网格项之间放置一个均匀的空间,左右两端放置一半的空间
space-between:在每个网格项之间放置一个均匀的空间,左右两端没有空间
space-evenly:在每个网格项目之间放置一个均匀的空间,左右两端放置一个均匀的空间place-content:
place-content 是设置 align-content 和 justify-content 的简写形式。
隐式的Grid网格:
如果网格项的数量多于网格单元格,或者网格项位于显式网格外部,则网格容器会通过向网格添加网格线自动生成网格轨道。 显式网格与这些额外的隐式轨道和网格线线一起形成所谓的隐式网格。
grid-auto-columns / grid-auto-rows;
引用的网格线不存在,所以创建宽度为 0 的隐式网格轨道以填补空缺。我们可以使用 grid-auto-columns 和 grid-auto-rows 来指定这些隐式轨道的大小:
grid-auto-flow;如果你有一些没有明确放置在网格上的网格项(grid items),自动放置算法 会自动放置这些网格项。该属性控制自动布局算法如何工作。
row:告诉自动布局算法依次填充每行,根据需要添加新行 (默认)
column:告诉自动布局算法依次填入每列,根据需要添加新列
dense:告诉自动布局算法在稍后出现较小的网格项时,尝试填充网格中较早的空缺grid:在一个声明中设置所有以下属性的简写: grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, 和 grid-auto-flow 。
子元素 网格项(Grid Items属性)
引用特定的网格线来确认Item在网格内的位置。
grid-area:为网格项提供一个名称,以便可以 被使用网格容器 grid-template-areas 属性创建的模板进行引用。
属性对齐:
justify-self and align-self 设置对齐方式是对齐其单元格
参考:CSS Grid 布局完全指南(图解 Grid 详细教程)-WEB前端开发 (html.cn)
网格动画
根据 CSS Grid 布局模块 Level 1 规范,有 5 个可应用动画的网格属性:
grid-gap, grid-row-gap,grid-column-gap 作为长度,百分比或 calc。
grid-template-columns,grid-template-rows 作为长度,百分比或 calc 的简单列表,只要列表中长度、百分比或calc组件的值不同即可。
常见需求
自定义属性
CSS 里也支持了变量的用法;
特征:自定义属性也和普通属性一样具有级联性,申明在 :root 下的时候,在全文档范围内可用,而如果是在某个元素下申明自定义属性,则只能在它及它的子元素下才可以使用(作用域)
定义声明的形式:它必须通过–x的格式来进行声明,可以在html的style属性中声明,这样的化它的发挥空间较小,但是可以动态化。
1px 边框解决方案
Retina 显示屏比普通的屏幕有着更高的分辨率,所以在移动端的 1px 边框就会看起来比较粗,为了美观通常需要把这个线条细化处理
默认样式清除
reset.css文件
Normalize.css 只是一个很小的CSS文件,但它在默认的 HTML 元素样式上提供了跨浏览器的高度一致性。相比于传统的 CSS reset,Normalize.css 是一种现代的、为 HTML5 准备的优质替代方案,现在已经有很多知名的框架和网站在使用它了。
区别于 reset.css,Normalize.css 有如下特点:
- reset.css 几乎为所有标签都设置了默认样式,而 Normalize.css 则是有选择性的保护了部分有价值的默认值;
- 修复了很多浏览器的 bug,而这是 reset.css 没做到的;
- 不会让你的调试工具变的杂乱,相反 reset.css 由于设置了很多默认值,所以在浏览器调试工具中往往会看到一大堆的继承样式,显得很杂乱;
- Normalize.css 是模块化的,所以可以选择性的去掉永远不会用到的部分,比如表单的一般化;
- Normalize.css 有详细的说明文档;
长文本的处理
字符太长超出了所给的容器(定义了宽度)
使用overflow-wrap实现换行
字符超出位置使用连字符:hypens:auto
单行文本超出省略
多行文本超出省略 利用line-clamp规定行
整块文本省略https://juejin.cn/post/6938583040469762055
水平垂直居中
元素在父元素中呈现出水平垂直居中的形态;参考那几个渲染上下文模型。
单行的文本、inline 或者 inline-block 元素;
固定宽高的块级盒子;
不固定宽高的块级盒子
单行的文本、inline 或 inline-block 元素:
此类元素需要水平居中,则父级元素必须是块级元素(block level)
.parent {
text-align: center;
}
垂直居中:
.single-line {
padding-top: 10px;
padding-bottom: 10px;
}
.single-line {
height: 100px;
line-height: 100px;
}
固定宽高的块级盒子
参考:https://juejin.cn/post/6941206439624966152#heading-2
法一:使用绝对定位+ 负 margin(偏移为50%)
法二:使用绝对定位+margin auto
法三:实现使用计算函数(因为盒子的宽高能取得)
不固定宽高的块级盒子
法一:absolute + transform位移百分比
法二:line-height + vertical-align 线盒的居中
法三:writing-mode:对其文本的垂直两次+居中就可以得到
法四:table-cell
法五:flex布局,直接使用一维轴排布
法六:grid布局,使用二维排布中轴
两栏布局(边栏定宽主栏自适应)
法一:float + overflow(BFC 原理)触发右侧BFC
法二:float + margin;定宽左边,右边直接使用边框隔离
法三:flex补全单行:
法四:grid布局;
三栏布局(两侧定宽主栏自适应)
法一:利用偏移量+margin的负值实现,加上两边的padding,float+百分比盒内宽度实现
法二:利用的是单边的固定+右侧-margin重叠的双边float靠拢
法三:float + overflow(BFC 原理)
还有多列等高和竖直划分三块没有写(原博客中都有)
less/(sass暂时不介绍)
LESS (Leaner Style Sheets 的缩写),是一款向后兼容的CSS 预编译语言,与css 很像,学习成本不高。less对CSS增加了少许方便的扩展。当然,因为less只是预编译语言,浏览器并不识别,因此,需要 less.min.js文件将less样式转化成css样式
既然是预编译的语言:
less实现了自己的变量:
【格式】 @变量名: 值
less可以通过上面的格式来定义自己的变量,变量可以参与less文本的运算和被调用
less的变量可以被属性调用成为属性值,同时也可以控制选择器名,属性名,URLs和 @import声明。区别就是后者需要在引用时添加{} (感觉上就像是只用进行变量替代内容的字符串转换文本形式的预编译,其实不是)
less的变量可以双层控制:控制选择器名,属性名,URLs和 @import声明。
less 的作用域:
懒加载:变量在使用前不会被赋值,父子作用域交叉的变量在父作用域中未被加载。在相同作用域定义的相同变量,都会被加载。
less编译器并不是阅读一句css就编译一句,而是将整个块都构建成渲染树,再编译出最终结果(遍历文档 类似变量提升 作用域交叉 )
可以将属性做为变量使用使用$来获得
.content {
color: #efefef;
backgroung-color: $color;
}
可以构建公用默认样式变量文件:且虽然引入了可能较大的library.less
文件,包含很多别的组件样式代码,但你不必担心,因为懒加载的特性,多余的代码并不会被加载编译。
父选择器的使用:
符号&可以做为父类的别名使用。
& 代表的是所有的父元素,而不是最近的父元素,但对于后面拼接字符串的情况,则只加在最近的一个父元素上。
在代码中使用可以达到一个类似于替换成父元素类名+选择器的字符串替换效果。
&在使用时,如果父类是多选择器,那么在编译时会采用排列组合的形式列出所有字符串替换的结果
样式追加 / 继承:
&:extend; LESS 支持样式追加,即将&:extend()中的样式加载到自身类下。
.c:extend(.d all) { // 继承所有包含.d 类的样式,如 ".x.d" 和 ".d.x" } .c:extend(.d) { // 只继承 .d 类的样式 }
前面关于less的介绍可以看出 它能通过字符串拼接 作用域 父选择器还有继承加载出新的样式类,且需要less的编译器维护一个能实例化变量的环境,来产生css文档。
关于合并Merge与混入Mixin:
1.值的合并与混入: 合并是将两个类相同属性的两个值合并到要合并类的同名属性中;而混入则是将一个类中的属性及样式都加入到要混入的类中。
//逗号合并+
.mixin() {
box-shadow+: inset 0 0 10px #555;
}
.myclass {
.mixin();
box-shadow+: 0 0 20px black;
}
//编译后
.myclass {
box-shadow: inset 0 0 10px #555, 0 0 20px black;
}//属性混入且用逗号连接
//空格合并+_
.mixin() {
transform+_: scale(2);
}
.myclass {
.mixin();
transform+_: rotate(15deg);
}
//编译后
.myclass {
transform: scale(2) rotate(15deg);
}
//自身参与编译的混入类 直接将类名写到混入类中
.a, #b {
color: red;
}
.mixin-class {
.a();
}
.mixin-id {
#b();
}
//编译后
.a, #b {
color: red;
}
.mixin-class {
color: red;
}
.mixin-id {
color: red;
}
//自身不参与编译的混入类: 类带圆括号
.my-mixin {
color: black;
}
.my-other-mixin() {
background: white;
}
.class {
.my-mixin;
.my-other-mixin;
}
//编译后
.my-mixin {
color: black;
}
.class {
color: black;
background: white;
}
选择器的混入:
less不仅可以做值混入,选择器也可以做混入,例如伪类或修饰类的混入。
.my-hover-mixin() {
&:hover {
border: 1px solid red;
}
}
button {
.my-hover-mixin();
}
//编译后
button:hover {
border: 1px solid red;
}
命名空间Namespace:
如果一个命名空间带有条件,则仅当条件结果返回为真时混入样式才会生效。
!important 关键字:在less中,可以对单个属性增加!important,也可以对整个类追加!important关键字。
函数式混入:
mixin可以携带参数,通过参数形式将变量传递给内部属性。往往我们都是先定义好方程式,再在需要调用位置传递参数。
// Defined
.border-radius(@radius) {//此处可以为参数赋默认值//也可以无参直接返回一个套板
//方程的值传递,参考具名传递和不具名传递
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
// Usage
#header {
.border-radius(4px);
}
.button {
.border-radius(6px);
}//函数式混入
混入函数在调用时会全部执行,可以通过选择来实现函数式混入的 “if / else”
.mixin (@a) when (lightness(@a) >= 50%) {
background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
background-color: white;
}
.mixin (@a) {
color: @a;
}
// Usage
.class1 { .mixin(#ddd) }
.class2 { .mixin(#555) }
//编译后
.class1 {
background-color: black;
color: #ddd;
}
.class2 {
background-color: white;
color: #555;
}
@arguments参数可以在函数式混入中参与使用。
递归混入:
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i =< @n) {
.column-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}
类型检查函数:
LESS 提供了一些基础的类型检查函数,又称为
is
函数,有:
- iscolor()
- isnumber()
- isstring()
- iskeyword()
- isurl()
也可以检查值的单位类型。有:
- ispixel()
- ispercentage()
- isem()
- isunit()
条件判断:
& when (@my-option = true) {
button {
color: white;
}
a {
color: blue;
}
}
@import:
@import在预编译的less中可以任意地方使用,且可以携带修饰符关键字
reference 使用文件,但不会输出其内容(即,文件作为样式库使用)
inline 对文件的内容不作任何处理,直接输出
less 无论文件的扩展名是什么,都将作为LESS文件被输出
css 无论文件的扩展名是什么,都将作为CSS文件被输出
once 文件仅被导入一次 (这也是默认行为)
multiple 文件可以被导入多次
optional 当文件不存在时,继续编译(即,该文件是可选的)
@plugin导入JS
registerPlugin({
install: function(less, pluginManager, functions) {
functions.add('pi', function() {
return Math.PI;
});
}
})
//js文件,但可以被调用
// Usage
@plugin "my-plugin";
.show-me-pi {
value: pi();
}
面试总结
min-width/max-width 和 min-height/max-height 属性间的覆盖规则?
max-width 会覆盖 width,即使 width 是行内样式或者设置了 !important。
min-width 会覆盖 max-width,此规则发生在 min-width 和 max-width 冲突的时候;
浏览器是怎样解析CSS选择器的?
CSS选择器的解析是从右向左解析的,一层层的过滤元素不把查询浪费在失败查询之上。