(第八天)CSS:优先级、选择器、层叠与继承、内联元素&块元素、替换元素&非替换元素

CSS <small>(Cascading Style Sheets)</small>


CSS有何作用?
  • 解决HTML页面内容与表现分离的问题
  • 在"如何显示"HTML元素方面,极大的提高了工作效率
CSS开发者的3种表现形式与优先级
  1. 外部样式表 <link rel="stylesheet" href="style.css">
  2. 内部样式表(位于 <head> 标签内部)<head><style>...</style></head>
  3. 内联样式(在 HTML 元素内部)<div style="..."></div>

上述四种css表现形式中,3的优先级最高,依次往前优先级越来越低。

CSS选择器、优先级、分组


CSS选择器之间的优先级

如果多于一个规则指定了相同的属性值都应用到一个元素上,CSS规定拥有更高确定度的选择器优先级更高。如:ID选择器比类选择器更具确定度, 而类选择器比标签选择器(tag selector)更具确定度,故ID选择器优先级比类选择器高,类选择器优先级比标签选择器高;再如:p.demo{}.demo{},前者确定度比后者高,故前者的优先级比后者高。

一般情况下,如果你提高了某个选择器的的确定度,你便提高它的优先级。
使用这个技巧,可以避免为大量标签指定 class 或 id 属性。CSS(引擎)会帮你做的。
在复杂设计中速度非常重要,避免使用复杂的依赖元素关系的规则可以使你的样式更有效率。

CSS选择器的确定度如何计算?
  • 计算方式
    1. 统计元素中是否存在style属性,如果存在则标记为a=1
    2. 统计选择器中id属性的个数,标记为b=id个数
    3. 统计选择器中其他属性(如.class [attr]等)及伪类的个数,标记为c=其他属性与伪类的总个数
    4. 统计选择器中元素名称及伪元素的个数,标记为d=元素名称与伪类元素的总数
  • 举例说明
  •         {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
    

li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 /
li:hover {} /
a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 :hover是伪类/
li:first-line {} /
a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 :first-line是伪元素/
ul li {} /
a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 /
ul ol+li {} /
a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
h1 + [rel=up]{} / a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 /
ul ol li.red {} /
a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 /
li.red.level {} /
a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */

x34y {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */

style="" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */
<head>
<style type="text/css">

x97z { color: red }

</style>
</head>
<body>
<p id=x97z style="color: green">
</body>


#####CSS选择器类型
* **ID选择器**(*#selector{}*):
`<p id="demo"></p> <style>#demo{}</style>`
* **类选择器**(*.selector{}*):
`<p class="demo"></p> <style>.demo{}</style>`
* **元素(标签)选择器**(*element{}*):
`<p></p> <style>p{}</style>`
* **基于关系的选择器**
  * **后代(派生)选择器** *A E{}*:
元素A的任一后代元素E (后代节点指A的子节点,子节点的子节点,以此类推) `<div class="demo"><p><span></span></p></div> <style>.demo p{} div span{}</style>` p和span元素都是类为.demo的div元素后代
  * **子元素选择器** *A > E{}*:
元素A的任一子元素E(也就是直系后代) `<div class="demo"><p><span></span></p></div> <style>.demo>p{} .demo>p>span{}</style>` p是类为.demo的div元素子元素,span是p的子元素
  * **伪元素(::)与伪类(:)选择器**:
    * 伪类连同伪元素一起, 他们允许你不仅仅是根据文档DOM树中的内容对元素应用样式,而且还允许你根据诸如像导航历史这样的外部因素来应用样式(:visited, 为例), 同样的,可以根据内容的状态 (例如 在一些表单元素上的 :checked ), 或者鼠标的位置 (例如 :hover 让你知道是否鼠标在一个元素上悬浮)来应用样式.
    * 伪元素就像伪类一样, 将伪元素添加到选择器中允许在不添加额外声明的情况下为文档的某些部分添加样式。
    * 伪元素两个冒号 (::) 与伪类一个冒号 (:)是 CSS3 规范中的一部分要求,目的是为了区分伪类和伪元素 . 大多数浏览器都支持这两种表示方式
    * 伪元素与伪类的区别: 
      * 伪元素的样式改变元素中某部分内容的样式
      * 伪类的样式改变元素不同状态时的样式或元素中子元素的样式
    * **伪元素列表**:
      * ***E::first-letter***:E元素的第一个字符的样式
      * ***E::first-line***:E元素的第一行的样式
      * ***E::before***:E元素内容区域内<small>(盒子模型的内容区)</small>内容前的内容与样式
      * ***E::after***:E元素内容区域内<small>(盒子模型的内容区)</small>内容后的内容与样式
      * ***E::selection***:文档中被用户高亮的部分(比如使用鼠标选中时应用的样式)
      * ***E::backdrop***:待了解,目前浏览器支持不太好
    * **伪类列表**:

      * ***E:link***:元素E为超链接状态的样式
      * ***E:visited***:元素E为被访问后的状态的样式
      * ***E:active***:元素E为鼠标按下未弹起的状态的样式
      * ***E:hover***:元素E为鼠标经过的状态的样式
      * ***E:focus***:元素E为获得焦点的状态的样式
      * ***A:not(E)***:A元素下,除了E元素外的所有元素的样式
      * ***:root***:
该属性绑定文档根元素,即html元素;存在该属性的情况下,body元素样式只针对内容区域渲染
      * ***E:first-child***:父元素下的第一个子元素,若第一个子元素不是E元素,则无效
      * ***E:nth-child***:
父元素下的第n个子元素,n根据所有子元素(包含不是E的元素)计算;从上往下,n>=1
      * ***E:nth-last-child***:
父元素下的第n个子元素,n根据所有子元素(包含不是E的元素)计算;从下往上,n>=1
      * ***E:nth-of-type***:
父元素下的第n个"元素为E"的子元素,n根据子元素且"元素为E"计算;从上往下,n>=1
      * ***E:last-of-type***:
父元素下的第n个"元素为E"的子元素,n根据子元素且"元素为E"计算;从下往上,n>=1
      * ***E:first-of-type***:父元素下的第一个子元素E
      * ***E:empty***:元素E无内容状态,如`<td></td>`, 无内容的td元素
      * ***E:target***:由跳转到达的区域状态
      * ***E:checked***:被选中的状态
      * ***E:enabled***:元素可用状态
      * ***E:disabled***:元素不可用状态

    >关于伪类与伪元素选择器,可以查看以下代码示例
[伪类伪元素选择器](https://coding.net/u/iolg/p/web-notes/git/blob/master/css3/pseudo-selector-1.html)
[伪类选择器](https://coding.net/u/iolg/p/web-notes/git/blob/master/css3/pseudo-selector-2.html)
[基于状态的伪类选择器](https://coding.net/u/iolg/p/web-notes/git/blob/master/css3/pseudo-selector-uistatus.html)

  * **相邻兄弟选择器** *B + E{}*:元素B的下一个兄弟元素E(B、E元素的父元素相同)
  * **兄弟选择器** *B ~ E{}*:B元素后面的拥有共同父元素的兄弟元素E
* **属性选择器**
  * *[attribute]{}*:元素存在attribute属性,不管属性值如何
  * *[attribute = value]{}*:元素存在attribute属性,且属性值`等于`value
  * *[attribute ~= value]*:元素存在attribute属性,且`多个属性值`中`存在`value;
  * *[attribute *= value]*:元素存在attribute属性,且属性值`包含`value;
  * *[attribute ^= value]*:元素存在attribute属性,且属性值以value`开头`;
  * *[attribute $= value]*:元素存在attribute属性,且属性值以value`结尾`;

>更多选择器知识可阅读[W3C选择器介绍](https://www.w3.org/TR/selectors/#selectors)

#####CSS选择器分组
当多个选择器使用相同样式时,可通过选择器分组实现。只需在选择器之间用`,`隔开即可。如:
  ```html
h1:before,h1:hover,h2:hover,div:hover { 
   content: ""; 
   padding-left: 10px;
   background-color: #f00;
}
h1,h2,div {background-color: #ff0;}

CSS的层叠与继承


CSS的层叠与优先级

一个HTML页面中,可以添加多种表现形式及同种表现形式同时存在的CSS,当多个CSS作用于一个HTML元素时,会出现层叠现象,浏览器会根据优先级来决定应用哪个CSS;当层叠属性权重相同时,后者优先级高于前者。

  • 以升序排序的优先级(5的优先级最高)如下:
    1. 用户代理声明,即浏览器默认样式
    2. 用户样式声明,即浏览器设置中的用户样式表
    3. 开发者样式声明 <small>(声明的选择器优先级请看选择器部分)</small>
    4. 开发者样式声明,并使用了!important关键字
    5. 用户样式声明,并使用了!important关键字
什么是CSS继承?

子元素会应用父元素的CSS可继承属性;对继承的元素来说,子元素自身的样式优先级高于从父级继承来的样式。如body元素样式的color属性,若其子元素p的css没有color属性时,元素p会应用body样式样式的color属性

!important关键字

在样式属性值中添加!important关键字,可以将该属性的优先级提升到最高;在层叠样式中,该属性将覆盖应用在该元素的相同CSS属性;若遇到相同属性都添加了!important关键字,则根据CSS选择器及层叠的优先级进行处理。

代码示例
<head>
  <meta charset="UTF-8">
  <title>CSS样式的继承与!important关键字</title>
  <style>

      body {
          /*改变浏览器默认字号*/
          font-size: 10px;
          color: #0000FF !important;
          color: red;
      }
      #important{
          /*都存在!important关键字,id选择器比元素选择器确定度更高,
          故id选择器优先级更好,即应用该color属性到该元素上*/
          color: #f00 !important;
      }

      h1 {
          color: #7FFF00 !important;
      }

      #default {
          /*h1标签的默认字号是浏览器默认字号(一般为16px)样式的200%,即32px*/
          font-size: 32px;
          /*h1元素选择器的color属性存在!important关键字,故该color属性无效*/
          color: red;
      }

      #bigger {
          font-size: 200%;
          width: 300px;
      }
  </style>
</head>
<body>
<p>p element</p>
<h1 id="important">h1 element 因继承body的font-size属性导致与default字号不同</h1>
<h1 id="default">h1 element(default)</h1>
<p id="bigger">
  h1默认的字号是浏览器默认字号(一般为16px)的200%,即32px;
  因body样式中将字号修改为10,且font-size是继承属性,故h1元素
  继承了body的font-size属性之后,200%就变成了10x200%=20px
</p>
</body>

内联元素(inline)& 块元素(block)


内联元素(inline)

内联元素,又称行内元素,只占据它对应标签的边框所包含的空间的元素。默认情况下,行内元素不会以新行开始,而块级元素会新起一行。
inline元素举例:<a>, <span>, <b>, <em>, <i>, <cite>, <mark>, <code>

块元素(block)

块级元素占据其父元素(容器)的整个空间,因此创建了一个“块”;通常浏览器会在块级元素前后另起一个新行。
block元素举例:<p>, <div>, <form>, <header>, <nav>, <ul>, <li>, <h1>

重点知识:内联元素(inline)与块元素(block)的区别
  • 内联元素(inline)
    • inline元素中只能包含内容或其他inline元素
    • 默认情况下,多个inline元素之间不会换行
    • 忽略margin-top与margin-bottom两个属性,margin-left与margin-right及padding所有属性有效
    • 忽略height与width属性
    • 设置为inline-block时,inline元素将拥有block部分属性,如margin的所有属性均有效(同时还能避免margin的折叠),height与width也有效。
    • inline元素若设置float为left或right,则拥有所有block元素的特征
    • inline元素可以设置vertical-align属性,如inline-block元素根据vertical-align属性处理元素之间的对齐方式
    • 在超出容器范围时,可以使用white-space设置其换行规则
    • inline与inline-block代码示例
<head>
    <meta charset="UTF-8">
    <title>inline元素与inline-block元素</title>
    <style>
        .inline p {
            border: 1px solid #cccccc;
        }

        /*给所有inline元素加上背景和边框,更好的观察效果*/
        .inline p *:nth-child(n) {
            background-color: #00ccff;
            border: 1px dashed #f00;
        }

        /*inline元素设置宽高无效*/
        .inline span {
            width: 100px;
            height: 100px;
        }

        /*inline元素设置margin;
        margin-left与margin-right有效,
        margin-top与margin-bottom无效*/
        .inline b {
            margin: 1em;
        }
        /*inline元素设置padding各属性均有效,但不会改变父元素高度*/
        .inline cite {
            padding: 1em;
        }

        /*inline元素设置float属性值为left或者right时,
        inline元素将获得所有block元素特性*/
        .inline mark {
            /*因为是浮动,所以不会改变父元素尺寸*/
            float: left;
            /*以下三个值都有效*/
            width: 128px;
            height: 100px;
            margin: 1em;
            padding: 1em;
        }

        .inline-block {
            background-color: red;
            /*height: 200px;*/
            width: 50%;
        }

        .inline-block p span {
            font-weight: bold;
            color: #ff0;
            /*inline-block类型元素,拥有block部分特征的inline元素*/
            display: inline-block;
            /*设置width有效*/
            width: 100px;
            /*该属性决定了inline-block类型元素之间的对齐方式*/
            vertical-align: middle;
            background-color: #0000FF;
            font-size: 16px;
        }
        .inline-block p.no_interval{
            /*父元素将字号设置为0,可解决inline-block类型子元素之间的默认间隔*/
            /*font-size:0px;*/
            /*父元素设置单词间距为-nPX(n需要测试得到具体值),
            也可解决inline-block类型子元素之间的默认间隔*/
            /*word-spacing: -8px;*/
            /*与子元素中的margin-left:-8px配合使用去掉间隔*/
            margin-left:8px;
        }
        .inline-block p.no_interval span{
            margin-left: -8px;
            width:150px;
            border:1px solid #00ff00;
        }
    </style>
</head>
<body>
<div class="inline">
    <h2>多个inline元素默认状态下的排版(默认不会换行,且不会影响父元素的高度)</h2>
    <p>
        <span>设置width、height无效</span>
        <b>margin只有margin-left与margin-right有效,上下无效</b>
        <cite>所有padding属性均有效,但不影响父元素高度</cite>
        <mark>float:left或right,inline元素获得block元素所有特性;浮动元素不影响父元素尺寸</mark>
    </p>
</div>
<!--clear:left 清除左边浮动-->
<h2 style="clear: left;">inline-block类型,拥有block类型部分特征的inline类型元素</h2>
<div class="inline-block">
    <p>
        <span>这是一个inline类型的block元素</span>
        <span>元素之间的对齐方式由vertical-align属性决定</span>
        <span>如果不设置vertical-align属性,多个inline-block元素排序可能会错乱</span>
        <span>inline-block作为inline元素同时又有了block元素的相关作用</span>
        <span>如block元素可以设置宽高与上下外边距</span>
        <span style="white-space: nowrap;">white-space设置不换行</span>
    </p>
    <h3>解决inline-block元素之间的默认间隔</h3>
    <p class="no_interval">
        <span>方法1:父元素font-size:0px 子元素重新设置font-size</span>
        <span>方法2:父元素word-spacing:-8px 设置单词间距为负值,具体多少实际测试</span>
        <span>方法3:子元素设置margin-left:-8px,父元素margin-left:8px 具体多少实际测试</span>
        <span>以上三种是比较合适的方法,其他改变文档结构的方法不建议使用</span>
        <span>间隔引起的原因是标签代码之间的空格或换行导致</span>
    </p>
</div>
</body>
  ![上述代码示例效果图](http://upload-images.jianshu.io/upload_images/1299322-fc993bb2ae00a3fb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  • 块元素(block)
    • block元素中可以包含block元素、inline元素等所有元素
    • 默认情况下,block元素前后会另起一行(假设子元素没有设置float及position属性)
    • margin和padding所有属性均有效
    • block元素在未设置width属性时,默认占据父元素100%的width
    • block元素在未设置height属性时,默认高度根据子元素自适应(假设子元素没有设置float及position属性)
    • 忽略vertical-align属性
    • block代码示例
<head>
    <meta charset="UTF-8">
    <title>block元素</title>
    <style>
        *{
            margin: 0px;
            padding: 0px;
        }
        .parent {
            width: 300px;
            background-color: #7FFF00;
            /*防止子元素与父元素(自己)出现margin-top或margin-bottom的重叠*/
            overflow: auto;
        }
        .sub {
            padding: .5em;
            background-color: #ff00cc;
        }

        .sub span {
            background: #cceeee;
        }
        /*块元素默认占据单独一行,宽度100%,高度根据内容(数据或子元素)自适应*/
        .line{
            /*应用block元素默认宽高*/
            height: auto;
            width: auto;
            /*margin、padding的所有属性均有效*/
            margin:1em;
            padding:1em;
            background-color: #ff0000;
        }
    </style>
</head>
<body>
<div class="parent">
    <p class="sub">block元素(
        <mark>div</mark>
        )内包含的block元素(
        <mark>p</mark>
        ),<span>block元素(<mark>p</mark>)内包含的inline元素(<mark>span</mark>)</span></p>
    <p class="line">块元素默认占据单独一行,未指定宽度时,占据父元素100%宽度,高度根据内容(数据或子元素)自适应</p>
</div>
</body>
上述代码示例效果图

替换元素与不可替换元素

什么是替换元素?
  • 在CSS2.1中,只有替换元素可以带有内置尺寸;
  • 替换元素的实际类型或者实际内容与元素属性有关,如img的实际内容由其"src"属性指定的图像替换,input的实际类型由其"type"属性决定
  • 一部分(并非全部)可替换元素,本身具有尺寸和基线(baseline),会被像vertical-align之类的一些 CSS 属性用到(类似inline-block类型元素)
  • 常见的替换元素:<img>, <object>, <button>, <textarea>, <input>, <select>
什么是不可替换元素?

元素的类型和实际内容和元素内部属性无关,没有内置尺寸属性;如<p>, <span>, <div>等,只能改变元素的样式。

代码示例
<head>
    <meta charset="UTF-8">
    <title>替换元素</title>
    <style>

        input {
            vertical-align: middle;
            border: 1px solid #ccc;
        }

        input:first-of-type {
            /*三个属性均有效*/
            width: 200px;
            height: 200px;
            margin: 5px;
        }

        img {
            /*width:100px;*/
            border: 1px solid #cccccc;
        }

        td {
            background-color: #cceeff;
        }

    </style>
</head>
<body>
<!--元素实际类型由type属性决定-->
<input type="text" value="替换元素">
<!--image类型的input有width height属性-->
<input type="image" src="#" value="替换元素" height="200">
<input type="text" value="替换元素">
<img src="#1" alt="" width="100">
<img src="#2" alt="" height="200" width="100">
<img src="#3" alt="">
<!--rows cols 的内置尺寸属性-->
<textarea rows="3" cols="4"></textarea>
<!--属性实际值由内部option属性决定-->
<select width="100px">select
    <option>option</option>
</select>
<table>
    <tr>
        <td width="100" height="100"></td>
        <td></td>
    </tr>
</table>
</body>

display更多类型的演示代码可点此查看

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,703评论 1 92
  • display: none; 与 visibility: hidden; 的区别 联系:它们都能让元素不可见 区别...
    纹小艾阅读 1,296评论 0 1
  • 1标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的? CSS盒子模型:由四个属性组成的外边距(margi...
    秦小婕阅读 1,148评论 0 1
  • 一:在制作一个Web应用或Web站点的过程中,你是如何考虑他的UI、安全性、高性能、SEO、可维护性以及技术因素的...
    Arno_z阅读 1,126评论 0 1
  • 清晨。 月华奎灵她们跟着动听的电台音乐在荒芜的废土上一路小跑着,铁蹄在后面笨重的跟着。 “铁蹄,你怎么了?之前打匪...
    月华奎灵阅读 529评论 0 2