1~13关于选择符,选择器。
14~18关于层叠和特殊性。
19 加载CSS。
20 关于性能优化的tips。
看完重新回答一道面试题:了解JavaScript文件的异步加载吗?
以前的回答:大概知道async和defer。
现在的回答:
首先说一下,为什么要异步加载?
因为JavaScript脚本会阻塞HTML和CSS对页面渲染,影响上屏时间,所以要异步加载JavaScript脚本。
然后说一下,两种异步加载属性的特点和区别
两个属性,async和defer,会告诉浏览器,立刻异步下载JavaScript文件。区别在于async是下载完后立刻执行,而defer是界面渲染完后执行。多个defer会按出现顺序执行,而async是只要下载完就执行。
1.类型选择符:
p{
color:black;
}
2.后代选择符:
blockquote p{
padding-left:2em;
}
3.id和类选择符:
#intro{
...
}
.date-post{
...
}
4.子选择符:
#nav > li{
只选择 *一个* 直接后代
}
5.相邻同辈选择符:
h2 + p{
选择一个后方相邻同辈
}
6.一般同辈选择符:
h2 ~ p{
选择h2后面所有同辈的p
}
以上三个也叫组合子。
为什么这些选择符都不会选择前面的元素而是选择后面的元素呢?
因为网页的渲染是向前进的,一个元素假如排在html的前面,那它就应该先渲染,所以选择器不选择之前的元素,因为假如选择之前的元素,必须要多轮渲染才能渲染完成,大大影响性能。
7.通用选择符:
*{
选择所有标签
}
往往不这么做,因为会导致一些问题,比如影响button和select等,一般明确指出,比如:
h1,h2,h3,h4,h5,h6
,ul,ol,li,dl,p{
padding:0;
margin:0;
}
当然可以结合其他选择器一起用。
8.属性选择器:
基于元素是否有某个属性或者某个属性是否为某个值:
abbr[title]{
当abbr有title属性时应用
}
input[type="submit"]{
当input的type为submit时应用
}
a[href^="https:"]{
匹配href以https:开头的a
}
img[src$=".jpg"]{
匹配src以.jpg结尾的img
}
a[src*="/about/"]{
匹配src包含‘/about/’的a
}
a[rel~=next]{
匹配以空格分隔rel属性中包含next的a
}
a[lang|=en]{
匹配lang属性是en或者en-xxxx这种形式的a
}
9.不是通过页面选择元素,但又给元素添加特殊标记,用到伪元素。
::first-letter选择第一段第一个字符
::first-line选择第一段第一行
::before 在前方插入
::after 在后方插入
以上俩个适合插入一些静态图标,符号等等,插入元素对交互有影响的话,最好不要用这个方法,以免css加载出问题。
比如:
.chapter::before{
content:' " ';
font-size:15em;
}
就在chapter之前插入一个大型的“ " ”符号,达到增加文档样式的作用。
10.伪类:
用文档以外的结构来给页面添加样式。
比如:
a:link 没有被访问时
a:visited 被访问过
a:hover 鼠标放置
a:focus 获得焦点
a:active 活动时
11.目标与反选:
.comment:target
这个target会匹配url后面的#内容,选择id为这个的标签。
:not(.xxxx){
选择不是.xxxx类的元素
}
综合上面两个写一个demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<a href="#test1">111</a>
<a href="#test2">111</a>
<div class="demo" id="test1">
test1
</div>
<div id="test2">
test2
</div>
</body>
<style type="text/css">
:target:not(.demo){
color: #FF0000;
}
</style>
</html>
点击跳到锚点后,会把符合target但不是.demo的div变红
12.结构化伪类:
选择元素基于序号。
如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ol id="ul-parent">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>
<ol id="ul-parent2">
<li class="l1">1</li>
<a>2</a>
<div>3</div>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ol>
</body>
<style>
#ul-parent :nth-child(3n){
color: red;
}
#ul-parent2 :nth-of-type(1){
color:red;
}
</style>
</html>
这个demo第一个会选择3n,n=1,2,3…的元素,而第二个会分类,然后选每类标签的第一个元素。
:nth-child()
:nth-of-type()
:nth-last-child()
:nth-last-of-type()
比如:
.column:nth-last-of-type(4):first-child,
.column:nth-last-of-type(4):first-child ~ .column{
这个会选择四个同类型的.column元素,并且只有在有至少有四个的时候才会选
}
再比如:
:nth-child(-n+3){
就只选前三个
}
13.表单伪类
<label for="field-name">Name: </label>
<input type="text" name="field-name" id="field-name" required>
选择带required的input,设置外边框:
input:required{
outline: 2px solid #000;
}
选择不带require的input
input:optional{
border-color:#ccc;
}
选择无效的email输入框:
input[type="email"]:valid{
border-color:green;
}
除了这些还有,type为number的
:in-range
:out-of-range
针对readonly的:read-only
针对没有readonly的:read-write等等
查看全部伪类:参考MDN
14.层叠
层叠就是当不同角色的CSS冲突时的按照重要性级别渲染CSS。
下面优先级降序:
- 标注为!important的用户样式
- 标注为!important的作者样式
- 作者样式
- 用户样式
- 浏览器的默认样式
15.特殊性
按照上面的规则就可以推算出特殊性的值,特殊性最强的选择器的样式会被应用。
特殊性相等则最后加载的一个被应用。
注意选择符*的特殊性为0,但是它是强于浏览器默认样式的。
16.伪类的顺序:
“Lord Vader Hates Furry Animals”
:link,:visited,:hover,:focus,:active
按照这个顺序,这几种伪类才不会异常覆盖。
17.减少特殊性(这条文字很少,但很重要):
写选择器的时候,尽量少使用特殊性强的标签:
1)会特殊性太高,覆盖掉某些组件的属性。
2)复用性差
18.继承
子类会继承父类的属性,但会被如何选择器覆盖,包括特殊性为0的通用选择器 * 。
浏览器默认样式也会覆盖继承。
这就是为什么给body设置一个font-size,而h标签不会被影响,因为h标签有浏览器默认样式。
再如:
*{
color:black;
}
h2{
color:red;
}
<h2>The emphasized text will be <em>black</em></h2>
这里由于*选择器覆盖了em的属性,所以不继承red。
19.style元素,link,可以引入CSS。
<style>
body{
xxxx
}
</style>
<style>
@import url("/css/moudules.css");
}
</style>
这说明,一个css文件里可能会下载其他css文件。
<link href="/css/base.css " rel="stylesheet" />
更推荐link,而不是@import
20.性能:
Web加载性能通常用“渲染时间”或者“上屏时间”来描述,在短时间内加载完全部CSS文件和Html文件很重要。
三方面优化:
1.减少http请求,通过如webpack这样的打包工具对Css压缩,尽量不用@import。
采用http2.0也是可以减少http请求次数的。
2.压缩和缓存
压缩就不解释了,缓存就是说我们要配置服务器和前端,对静态文件的缓存时间,通过强缓存或者协商缓存来让文件复用。
3.不要让JavaScript阻塞渲染
在运行到js脚本的时候,页面会阻塞,所以要把<script>
标签放最后,或者用异步加载。
<head>
<script src="/scripts/core.js" async></script>
<script src="/scripts/core.js" defer></script>
</head>
async 表示立即异步下载,立即执行,下载完后依然会阻塞加载。
defer表示立即异步下载,等待html解析完成后再执行。