CSS全称为层叠样式表,描述了如何在屏幕、纸张或其他媒体上显示HTML元素。
优点:(1)可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化 ;
(2)能够对网页中元素位置的排版进行像素级精确控制,支持几乎所有的字体字号样式,拥有对网页对象和模型样式编辑的能力;
(3)节省了大量工作,可以同时控制多张网页的布局。
一、CSS全局关键字属性值
全局关键字属性值包括inherit、initial、unset以及revert,也就是说所有css属性都可以使用这几个关键字作为属性值。
(1)inherit(继承)
当我们想给输入框的内置字体进行重置为父元素的字体,只需要设置字体为inherit就行;如果想要子元素的高度可以继承父元素的高度,那么给高度也设置为inherit即可。
例如:我们给p标签的高度以及input输入框的字体都设置成inherit;
结构:
样式:
效果:
可以看出p标签占满父盒子高度,input输入框的字体也继承了父盒子的字体。
兼容性:https://caniuse.com/?search=inherit
(2)initial(初始)
initia可以把当前css属性的计算值还原成css语法中规定的初始值。
例如:我们给ul最后一个li的font-size设置成initial
结构:
样式:
效果:
发现“测试initial”几个字体会更大一些,也就是css规范中定义的初始值,为16px。
这个属性常用于我们需要重置某些css的样式,但是又不知道初始值的场景。比如:我们给p元素设置display:initial,可以发现这个元素垂直方向的margin属性失效了,也就意味着display的初始值为内联元素inline。
结构样式:
效果:
兼容性:https://caniuse.com/?search=initial
(3)unset(未设置)
unset意思是不固定的关键字,它如果用在具有继承特性的属性中就等同于inherit,反之就相当于initial,一般配合all属性去使用。
例如:我们在chrome浏览器中使用dialog标签去实现弹窗:
结构:
效果:
但是我们又不想去使用它的样式,这时候一个个去修改覆盖之前的样式过于繁琐,就可以使用all:unset进行批量重置再写自己所需要的样式。
样式:dialog { all: unset; }
效果
兼容性:https://caniuse.com/?search=unset
(4)revert(还原)
revert可以将当前元素的样式还原成浏览器内置的样式。
例如:我们想要ul列表默认显示3项,点击”更多“按钮显示选项4时,我们一般会将最后一个li标签的display值设置成block;
结构样式:
效果:
我们看效果发现选项4已经添加,但是丢失了它的项目符号。这其实是因为li元素默认的display计算值不是‘block’,而是‘list-item’。但是实际开发的时候,也许我们想不到或者根本不知道他的计算值是什么,此时可以使用revert关键字代替,这样就可以实现了。
修改后样式:
btn.onclick = function () {
showList.style.display = 'revert';
}
效果:
兼容性:https://caniuse.com/?search=revert
二、all属性
批量设置,可以设置置除unicode-bidi、direction以及所有css自定义属性以外的所有css属性。比如上面提到的all:unset;主要取值为initial / inherit / unset / revert,上面已经详细介绍过,不再赘述。
那么为什么unicode-bidi、direction不受all属性的影响?这是因为direction属性(规定文本的方向 / 书写方向)的初始值为ltr(从左到右展示),但是阿拉伯文的展示方式为从右到左,如果我们使用all: inherit 属性去重置direction,阿拉伯文的展示就会变成从左变右,不符合他们的阅读习惯;unicode-bidi 属性需要与direction属性一起使用(设置或返回文本是否被重写),所以也就同direction属性一样被设计成不受all属性的影响。
兼容性:https://caniuse.com/?search=all
三、white-space属性
场景:当我们输入一行串内容的时候,里面包含了各种换行符、空白行等,想在页面完整展示怎么办?一般会选择使用正则匹配,但其实可以使用white-space属性的值来控制。
white-space属性我们常用来控制元素是否换行展示,但是可能没有关注它对于文本中的空白、制表符、换行符的作用。主要取值有:
normal | 默认,忽略文本中所有的空白、换行符;只有在文本达到框的约束时才会换行 |
---|---|
nowrap | 忽略文本中所有的空白、换行符;遇到框的宽度约束时不会自动换行,只有在遇到br标签时文本才会换行 |
pre | 保留文本中的空白、换行符;遇到框的宽度约束时不会自动换行,只有在文本遇到换行符时才会换行 |
pre-wrap | 保留文本中的空白、换行符;只有在文本遇到换行符或者遇到框的宽度约束时才会换行 |
pre-line | 忽略文本中的空白符,保留换行符;只有在文本遇到换行符或者遇到框的宽度约束时才会换行 |
(1)normal:默认,忽略文本中所有的空白、换行符;只有在文本达到框的约束时才会换行
结构样式:效果:
即:忽略了attribute前面的空格展示,this后面换行符没有起到作用,但受到以及父盒子宽度的限制;
(2)nowrap:忽略文本中所有的空白、换行符;遇到框的宽度约束时不会自动换行,只有在遇到 br标签时文本才会换行
样式:.whiteSpace { white-space: nowrap; }
效果:
即:与normal类似,但是不同的是nowrap会超过父盒子宽度展示而不换行;
(3)pre:保留文本中的空白、换行符;遇到框的宽度约束时不会自动换行,只有在文本遇到换行符时才会换行
样式:.whiteSpace { white-space: pre; }
效果:
即:所有的空格,换行符都保留(This前),会超出父盒子的宽度展示而不换行,并且the后面的br也没有导致换行;
(4)pre-wrap:保留文本中的空白、换行符;只有在文本遇到换行符或者遇到框的宽度约束时才会换行
样式: .whiteSpace { white-space: pre-wrap; }
效果:
即:与pre类似。但不同的是pre-wrap会在受到父盒子宽度限制的时候进行换行;
(5)pre-line:忽略文本中的空白符,保留换行符;只有在文本遇到换行符或者遇到框的宽度约束时才会换行
样式: .whiteSpace { white-space: pre-line; }
效果:
即:与pre-wrap类似,但不同的是pre-line忽略了文本中的空白符(attribute前的);
(6)兼容性: https://caniuse.com/?search=whit-space
四、 word-break / word-wrap 字符单元的中断与换行
场景:当一个长单词超过容器宽度时,如果不换行则会溢出容器,这是因为浏览器的默认换行规则:
a、spce普通空格、Enter (回车)空格和Tab (制表符)空格这3种空格无论怎样组合都会合并为单个普通空格。
b、文字可以在CJK文本(指中文、日文、韩文这几种文字)、普通空格和短横线连字符处换行,连续英文单词和数字不换行。
例如:
(一)word-break属性
指定非CJK文本的断行规则,主要取值有:
normal | 默认,使用浏览器默认的换行规则 |
---|---|
break-all | 所有的都可以换行 |
keep-all | 只能在半角空格或连字符处换行 |
例如:我们给table的宽度设置为400px,“会议内容” 这一列的宽度固定为250px;
结构:
样式:.tableForm { width: 400px; table-layout: fixed; }
如果我们不修改word-break的值,就达到示例的效果,连续 英文单词不换行导致溢出。
(1)break-all 所有的都可以换行
样式:.tableForm { width: 400px; text-align: center; word-break: break-all; }
效果:
(2) keep-all 只能在半角空格或连字符处换行
样式:.tableForm { width: 400px; text-align: center; word-break: keep-all; }
效果:
即:长文本以及长单词都没有换行,导致文本溢出,但是在连字符处进行了换行
(二)word-wrap 属性
word-wrap属性允许长的内容可以自动换行。主要取值有:
normal | 只在允许的断字点换行(浏览器保持默认处理) |
---|---|
break-word | 在长单词或 URL 地址内部进行换行 |
(1)break-word 在长单词或 URL 地址内部进行换行
样式:.tableForm { width: 400px; word-wrap: break-word; table-layout: fixed; }
效果:
即:不管是长文本还是长单词都被拆分展示
(三)区别
从上面可以看出,word-break:break-all 以及word-wrap:break-word 都可以在长文本及长单词内换行,而他们有个细微的区别: word-break: break-all 是所有的都可以换行,不会留什么空隙;而word-warp: break-word 的换行会受其余可以换行的点的影响,比如空格等,也就是说如果这个长单词前面有个空格,那么会将这个单词另起一行去展示。
(四)兼容性
- word-break :https://caniuse.com/?search=word-break%20
- word-wrap :https://caniuse.com/?search=word-wrap%20
五、vertical-align属性
场景:如果实现这样上标下标的样式,我们会怎么布局?写个标签,使用定位?其实使用vertical-align里的属性值即可实现。
vertical-align属性设置一个元素的垂直对齐方式,主要取值有:
baseline | 默认。元素放置在父元素的基线上 |
---|---|
sub | 提高盒子的基线到父级合适的上标基线位置(没有具体的位置,可能字体不一样,上标基线的位置也不确定) |
super | 降低盒子的基线到父级合适的下标基线位置(没有具体的位置,可能字体不一样,上标基线的位置也不确定) |
top | 把元素的顶端与行中最高元素的顶端对齐 |
text-top | 把元素的顶端与父元素字体的顶端对齐 |
middle | 把此元素放置在父元素的中部 |
bottom | 把元素的顶端与行中最低的元素的顶端对齐 |
text-bottom | 把元素的底端与父元素字体的底端对齐 |
length | 将元素的基线对齐到其父级基线上方的给定长度。允许为负值 |
% | 将元素的基线与对应于其父级基线之上的给定百分比对齐,该值是line-height属性的百分比 |
(1) baseline / top / middle / bottom 常用对齐方式
(2) text-top / text-bottom :把元素的顶端与父元素的顶端 / 底端对齐。
当我们给top下的span标签添加text-top的属性值,bottom的span标签添加text-bottom的属性值,即可实现场景中的功能
结构:
样式:
(3) length:将元素的基线对齐到其父级基线上方的给定长度。允许为负值。
样式:.top span { vertical-align : 50px; }
效果:
(4) %:将元素的基线与对应于其父级基线之上的给定百分比对齐,该值是父级line-height属性的百分比。
当我们给父盒子的line-height设置40px,那么40px的250%就是100px;即上标距离父元素的基线100px
.top { line-height: 40px; } .top span { vertical-align: 250%; }
效果:
(5)兼容性: https://caniuse.com/?search=vertical-align
六、:is() 和:where() 伪类选择器
伪类选择器的结构与伪元素类似,很容易混淆。 伪类选择器是用来描述一个元素的特殊状态。比如第一个元素、某个元素的子元素、鼠标点击的元素等,结构为:xx表示,我们常用的有:visited(),:hover(),:focus(),:first-child(),:not()等等,而伪元素是用于设置元素指定部分的样式,它可用于设置元素的首字母,首行的样式,或者在元素的内容之前或之后插入内容,结构规范为::xx表示。
场景:在日常写代码中,经常遇见重复的同一个元素在不同的标签中的情况,这时我们采用列举的方式写这个元素的样式时就会比较麻烦,稍加不注意就会出现错误,这时候可以使用伪类选择器。
(1):is() 伪类选择器
例如: 当我们想给下面结构中所有的h1-h6标签里的字体设置颜色,采用全部列举的方式时:
结构:
样式:
效果:
这样写不仅代码冗余,但是一旦出现一个失效的选择器,就会导致整个列表的选择器都设置不成功,比如我们给列表添加一个:unsupported选择器;
样式:
效果:
如果我们使用:is()伪选择器,同时添加:unsupported选择器;
样式:
效果:
可以很明显的看出,不仅代码量减少了,也不会因为:unsuppoerted这个失效的选择器导致整个列表颜色设置不成功。
(2):where() 伪类选择器
与:is()伪类选择器用法完全一致,只是优先级不同
(3)两者的优先级
:is()伪类选择器的优先级取决于其参数列表中优先级最高的选择器。因此,使用时可能会提升选择器的优先级,而:where()伪类选择器的优先级始终是0 。
例如:我们分别使用:is()伪类选择器和:where()伪类选择器以及列表列举(放后面)的方式给li字体添加颜色,按照就近原则,我们会认为ol里的li字体为绿色:
结构:
- 使用:is() 伪类选择器
样式::is(ol, .list) li { color: red; } ol li { color: green; }
效果:
即:因为:is()伪类选择器的参数中有class选择器(.list),它的优先级权重大于标签选择器。因此,最终ol里的li的字体颜色是红色。 - 使用:where()伪类选择器
样式::where(ol, .list) li { color: red; } ol li { color: green; }
效果:
即:我们知道标签选择器li的优先级权重是1,效果呈现出绿色,代表没有受到:where()的影响,从而得出它的优先级为0。
(4)兼容性
- :is() :https://caniuse.com/?search=%3Ais
- :where(): https://caniuse.com/?search=%3Awhere
七、table-layout属性
场景:实际开发中,我们经常会用到表格结构,然而当我们写了一个table表格,想按照自己需要的宽度去修改表格列的宽度时,发现无论怎么设置都改变不了,原因是因为table-layout的属性值默认为auto
table-layout 属性用来显示表格单元格、行、列的算法规则,主要取值为:
auto | 自动表格布局 |
---|---|
fixed | 固定表格布局 |
例如:这样一个表格结构, 我们给长文本设置宽度为450px;
结构:
样式:
效果:
(1)auto 自动表格布局
自动表格布局列的宽度是由列单元格中没有折行的最宽的内容设定的,自动表格布局时,设置单元格的宽度是没有效的。由上述例子看出,虽然我们给长文本那列设置了450px的宽度,但是从审查元素看出并没有设置成功,这就是因为table-layout的默认值为auto导致。
(2)fixed 固定表格布局
固定表格布局仅取决于表格宽度、列宽度、表格边框宽度、单元格间距,而与单元格的内容无关。如果指定了单元格的宽度,则会按指定的宽度限定每个单元格宽度(如果指定的是比例,会永远保持这个比例),这样就可能出现内容飘到单元格之外的情况。如果没有指定单元格的宽度,则会根据table的总宽度平分到每个单元格。
当我们修改table-layout的属性值为fixed时,可以看到此时宽度为450px,设置成功。
(3)兼容性:https://caniuse.com/?search=table-layout
八、user-select属性
场景:实际开发中,当我们手写一个按钮样式时,会发现里面的文本可以选中,但这并不符合我们想要的功能,这时候可以使用user-select禁用文本选中的功能。
user-select属性规定是否能选中元素的文本,主要取值有:
auto | 默认,文本将根据浏览器的默认属性进行选择 |
---|---|
none | 防止文字和图片被选中 |
text | 文字和图片可被选中 |
all | 当所有内容作为一个整体时可以被选中,如果双击或者在上下文上点击子元素,那么被选择的部分将是以该子元素向上回溯的最高祖先元素 |
例如:现在的这个按钮,是可以选中文本的。
(1)none 防止文本被选中
添加样式:.btnsty { user-select: none }
效果:
(2)text 文本可以被选中
我们在原先的结构上加一个子元素span标签,写点样式:
结构:
修改样式:
效果:
即:当我们双击时,会对应的选中文字
(3)all:auto与text选中效果均为双击选中,但all为单击时选中,当所有内容作为一个整体时可以被选中
当我们修改为user-select:all 时,效果:
即:当我们单击时,包含子元素,父元素被整体选中
注:
1、无论将user-select的值设置成什么,::before和::after 伪元素生成的内容都无法被选中;
例如:我们将span标签改为使用::before伪元素,再给按钮的user-select设置为all或text,可以看出无论怎么选择只有“测试选中”几个字被选中,::after同理。
样式:
效果:
为all时:
为text时:
2、user-select的初始值为auto,如果将父元素的user-select属性值设置成all/none,则当前元素的user-select属性值也表现为all/none;
例如上面示例中增加的span标签,仅仅是对父元素的user-select进行了设置,span标签内的元素也展示了同样的效果,但是这并不是代表user-select属性具有继承性,只是初始值auto的渲染效果而已。
(4)兼容性:https://caniuse.com/?search=user-select
九、min(), max() 和 clamp() 比较函数
比较函数的作用:可以提供动态布局和更灵活设计组件方法,主要用来设置元素尺寸,如容器大小,字体大小,内距,外距等等,一般用于弹性布局中(宽度自适应布局中)。
场景:当我们希望网页在PC端浏览器中宽度为1200px,在移动端中的宽度为100%,会选择使用
.box {
width: 1200px;
max-width: 100%;
}
如果使用min()函数只需一句CSS声明即可实现; .box {width:min(1200px,100%)};
(1)min() 函数:支持一个或多个表达式,每个表达式直接使用逗号分隔,然后将最小的表达式的值作为返回值
例如:
结构:
<div id="boxWidth">
测试宽度
</div>
样式:
#boxWidth {
border; 1px solid #000;
width: min(50%, 500px);
box-sizing: border-box;
}
这里的width计算值最大就是500px;对于真实的宽度取决于浏览器视口的宽度,如果小于1000px(其50%小于500px);那宽度就会取50%的计算值,如果大于1000px;宽度取500px;也就是说min() 函数实际上是用来限制最大值的。
此时body的宽度为284px,取其50%为142px,小于500px,因此div的宽度为142px;
而当body的宽度大于1000px时,div的宽度则取500px;
(2)max() 函数:支持一个或多个表达式,每个表达式直接使用逗号分隔,然后将最大的表达式的值作为返回值
与min() 类似 ,上述例子如果浏览器宽度小于1000px;那宽度就会取500px,如果大于1000px;宽度取50%的计算值; 也就是说max() 函数实际上是用来限制最大值的。
(3)clamp() 函数:返回一个区间范围的值
语法:clamp(MIN, VAL, MAX),MIN代表最小值,VAL代表首选值,MAX代表最大值,如果VAL的值在MIN-MAX之间,则使用VAL作为函数的返回值,如果VAL大于MAX,则使用MAX作为返回值,如果VAL小于MIN,则使用MIN作为返回值。
例如:我们设置VAL为500px,MIN为50%,MAX为60%;
此时body的宽度为1200px,500< 120050%,因此取MIN的600px;
此时body的宽度为800px,500> 80060%,因此取MAX的480px;
此时body的宽度为900px,90050% < 500 < 90060%,因此取VAL的500px;