febobo/web-interview

面试官:css选择器有哪些?优先级?哪些属性可以继承?

huihuiha opened this issue · 3 comments

一、选择器

CSS选择器是CSS规则的第一部分

它是元素和其他部分组合起来告诉浏览器哪个HTML元素应当是被选为应用规则中的CSS属性值的方式

选择器所选择的元素,叫做“选择器的对象”

我们从一个Html结构开始

<div id="box">
    <div class="one">
        <p class="one_1">
        </p >
        <p class="one_1">
        </p >
    </div>
    <div class="two"></div>
    <div class="two"></div>
    <div class="two"></div>
</div>

关于css属性选择器常用的有:

  • id选择器(#box),选择id为box的元素

  • 类选择器(.one),选择类名为one的所有元素

  • 标签选择器(div),选择标签为div的所有元素

  • 后代选择器(#box div),选择id为box元素内部所有的div元素

  • 子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素

  • 相邻同胞选择器(.one+.two),选择紧接在.one之后的所有.two元素

  • 群组选择器(div,p),选择div、p的所有元素

还有一些使用频率相对没那么多的选择器:

  • 伪类选择器
:link :选择未被访问的链接
:visited:选取已被访问的链接
:active:选择活动链接
:hover :鼠标指针浮动在上面的元素
:focus :选择具有焦点的
:first-child:父元素的首个子元素
  • 伪元素选择器
:first-letter :用于选取指定选择器的首字母
:first-line :选取指定选择器的首行
:before : 选择器在被选元素的内容前面插入内容
:after : 选择器在被选元素的内容后面插入内容
  • 属性选择器
[attribute] 选择带有attribute属性的元素
[attribute=value] 选择所有使用attribute=value的元素
[attribute~=value] 选择attribute属性包含value的元素
[attribute|=value]:选择attribute属性以value开头的元素

CSS3中新增的选择器有如下:

  • 层次选择器(p~ul),选择前面有p元素的每个ul元素
  • 伪类选择器
:first-of-type 父元素的首个元素
:last-of-type 父元素的最后一个元素
:only-of-type 父元素的特定类型的唯一子元素
:only-child 父元素中唯一子元素
:nth-child(n) 选择父元素中第N个子元素
:nth-last-of-type(n) 选择父元素中第N个子元素,从后往前
:last-child 父元素的最后一个元素
:root 设置HTML文档
:empty 指定空的元素
:enabled 选择被禁用元素
:disabled 选择被禁用元素
:checked 选择选中的元素
:not(selector) 选择非 <selector> 元素的所有元素
  • 属性选择器
[attribute*=value]:选择attribute属性值包含value的所有元素
[attribute^=value]:选择attribute属性开头为value的所有元素
[attribute$=value]:选择attribute属性结尾为value的所有元素

二、优先级

相信大家对CSS选择器的优先级都不陌生:

内联 > ID选择器 > 类选择器 > 标签选择器

到具体的计算层⾯,优先级是由 A 、B、C、D 的值来决定的,其中它们的值计算规则如下:

  • 如果存在内联样式,那么 A = 1, 否则 A = 0

  • B的值等于 ID选择器出现的次数

  • C的值等于 类选择器 和 属性选择器 和 伪类 出现的总次数

  • D 的值等于 标签选择器 和 伪元素 出现的总次数

这里举个例子:

#nav-global > ul > li > a.nav-link

套用上面的算法,依次求出 A B C D 的值:

  • 因为没有内联样式 ,所以 A = 0

  • ID选择器总共出现了1次, B = 1

  • 类选择器出现了1次, 属性选择器出现了0次,伪类选择器出现0次,所以 C = (1 + 0 + 0) = 1

  • 标签选择器出现了3次, 伪元素出现了0次,所以 D = (3 + 0) = 3

上面算出的ABCD 可以简记作:(0, 1, 1, 3)

知道了优先级是如何计算之后,就来看看比较规则:

  • 从左往右依次进行比较 ,较大者优先级更高
  • 如果相等,则继续往右移动一位进行比较
  • 如果4位全部相等,则后面的会覆盖前面的

经过上面的优先级计算规则,我们知道内联样式的优先级最高,如果外部样式需要覆盖内联样式,就需要使用!important

三、继承属性

css中,继承是指的是给父元素设置一些属性,后代元素会自动拥有这些属性

关于继承属性,可以分成:

  • 字体系列属性
font:组合字体
font-family:规定元素的字体系列
font-weight:设置字体的粗细
font-size:设置字体的尺寸
font-style:定义字体的风格
font-variant:偏大或偏小的字体
  • 文本系列属性
text-indent:文本缩进
text-align:文本水平对刘
line-height:行高
word-spacing:增加或减少单词间的空白
letter-spacing:增加或减少字符间的空白
text-transform:控制文本大小写
direction:规定文本的书写方向
color:文本颜色
  • 元素可见性
visibility
  • 表格布局属性
caption-side:定位表格标题位置
border-collapse:合并表格边框
border-spacing:设置相邻单元格的边框间的距离
empty-cells:单元格的边框的出现与消失
table-layout:表格的宽度由什么决定
  • 列表属性
list-style-type:文字前面的小点点样式
list-style-position:小点点位置
list-style:以上的属性可通过这属性集合
  • 引用
quotes:设置嵌套引用的引号类型
  • 光标属性
cursor:箭头可以变成需要的形状

继承中比较特殊的几点:

  • a 标签的字体颜色不能被继承

  • h1-h6标签字体的大下也是不能被继承的

无继承的属性

  • display

  • 文本属性:vertical-align、text-decoration

  • 盒子模型的属性:宽度、高度、内外边距、边框等

  • 背景属性:背景图片、颜色、位置等

  • 定位属性:浮动、清除浮动、定位position等

  • 生成内容属性:content、counter-reset、counter-increment

  • 轮廓样式属性:outline-style、outline-width、outline-color、outline

  • 页面样式属性:size、page-break-before、page-break-after

参考文献

伪元素前面应该是两个冒号,你写成一个冒号了;:enabled 选择被启用的元素,你写成被禁用的元素了;

简单总结

依据上文思路,从选择器、优先级、属性可继承三方面简单记录一下。

选择器与优先级

根据优先级排序

内联样式 > id 选择器 > 类、伪类选择器、属性选择器 > 元素、伪元素选择器 > 后代、子代、兄弟选择器

当多种样式要同时作用于同一元素时,最终的显示效果就要由优先级来决定,用 A、B、C、D 四个默认值都是0的值来依次代表 内联样式、id选择器、类选择器伪类选择器属性选择器、元素选择器伪元素选择器。

  • 如果存在内联样式, 则 A ++,
  • 如果存在id选择器,则 B++
  • 每出现一个类选择器、伪类选择器或者属性选择器,C++执行一次
  • 每出现一个元素选择器或者伪元素选择器,D++执行一次

由上面的方法,每组样式都会算出一组结果为 (A,B,C,D) 的值,将各组结果依次对比:

  • 先比较A,如果双方A值不相等,就取较大者的样式;如果双方A值相等,就比较B,若2B不等则取较大者的样式,若等则比较C ...
  • 如果ABCD四个值都比较完了,且四个值都对应相等,则会发生样式覆盖,表现效果为后者样式会覆盖前者,最终浏览器显示的效果为最后定义的一个样式。

属性是否可继承

好难记,记一部分
可继承:

  • visibility 元素可见性
  • 字体系列:font-weight 粗细、font-size 大小、font-style 风格
  • 文本系列:text-indent 缩进、text-align 水平对齐、color 颜色、line-height 行高

不可继承:
display、盒子模型、定位浮动、背景属性

注意点

多种样式作用于同一元素才有必要用优先级来判断要显示的是哪种样式

测试

<body>
  <div id="test" class="six testClass">
    <div id="test2" class="six2">
      <div id="test3" class="six3 six33">
        <p>666</p>
      </div>
    </div>
  </div>
</body>
    #test {
      background-color: red;
    }

    #test>#test2 {
      background-color: yellow;
    }

    #test>.six2>#test3 {
      background-color: black;
    }
   
     #test>.six2>.six3 {
      background-color: blue;
    }
/* 最终显示颜色为black,理由是#test>.six2>#test3的优先级在这里最高者 */
    #test {
      background-color: red;
    }

    #test>#test2 {
      background-color: yellow;
    }

    #test>.six2>.six3 {
      background-color: blue;
    }

    #test>.six2>.six33 {
      background-color: yellowgreen;
    }
最终显示为yellowgreen,理由是发生了样式覆盖
    #test {
      background-color: red;
    }

    #test>#test2 {
      background-color: yellow;
    }

    #test>.six2>.six3 {
      background-color: blue;
    }

    #test>.six2>.six33 {
      background-color: yellowgreen;
    }

    p {
      background-color: aqua;
    }
最终显示为aqua,理由是作用于p元素上的只有一个标签选择器,没有其它选择器与之冲突。
题外话:优先级的使用场景是多种选择器作用于同一个元素上,才需要去计算优先级,用之判断显示的是哪组选择器控制的样式

h1-h6标签字体的大小也是不能被继承的