CSS3选择器渲染不懂?小白?这篇文章从底层给你讲清

179 阅读4分钟

小白css教学来啦~~

为什么京东页面这么炫酷,为什么哔站页面看起来就是让人舒服。一篇文章讲清楚css渲染过程和css选择器几种分类,解开CSS3神秘面纱。事不宜迟开始吧

1. CSS 基础概念

CSS(层叠样式表)是一种用于描述HTML文档外观的语言。它通过一系列规则集(ruleset)来定义页面元素的样式,每个规则集由一个或多个选择器(selector)和一组声明(declaration)组成。

  • 规则集(Ruleset) :由选择器和声明块构成。 /* css rules / h1 { / 选择器 / color: red; / 声明 */ text-align: center; }

  • 选择器(Selector) :用于指定要应用样式的HTML元素。

  • 声明(Declaration) :包含属性(property)和值(value),定义具体的样式规则。

    color: red;  /* 声明 */
    

2. CSS 的作用与引入方式

CSS 主要用于描述页面的样式,通过选择DOM元素并应用样式规则,使页面更加美观和功能丰富。CSS可以通过以下几种方式引入到HTML文档中:

  • 内联样式:直接在HTML标签中使用style属性定义样式。

    <p style="color:red;">行内样式</p>
    
  • 内部样式表:在HTML文档的<head>部分使用<style>标签定义样式。

    <style>
      h1 {
        color: red;
        text-align: center;
      }
    </style>
    
  • 外部样式表:通过<link>标签引入外部CSS文件。

    <link rel="stylesheet" href="styles.css">
    

3. 渲染过程

浏览器在解析HTML文档时,会先下载并解析CSS文件,构建渲染树(render tree)。渲染树反映了页面的可视化结构,浏览器引擎根据渲染树生成最终的页面布局和样式。这个过程包括以下几个步骤:

  1. 解析HTML:构建DOM树。
  2. 解析CSS:构建CSSOM(CSS对象模型)。
  3. 构建渲染树:将DOM树和CSSOM合并,生成渲染树。
  4. 布局:确定每个元素的位置和尺寸。
  5. 绘制:将渲染树转换为屏幕上的像素。

4. 样式优先级

CSS样式优先级遵循一定的计算规则,从高到低依次为:

  • !important:赋予最高优先级(权重10000),但应谨慎使用,以免造成维护困难。
  • ID选择器:权重100。
  • 类选择器、伪类和属性选择器:权重10。
  • 标签选择器和伪元素:权重1。
  • 通配符选择器:权重0。

此外,还可以通过组合选择器来增加优先级。例如,.container ul li:nth-child(odd)会选择.container内的ul中的奇数li元素,并且其优先级为10 + 1 + 1 = 12。

基础选择器

  • 标签选择器
  • 类选择器
  • id 选择器
  • 通配符选择器 * 性能不太好
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>css</title>
    <style>
        p {
          color: blue ; /* !important 10000分 ,覆盖所有*/
        }
        /* id 级别更高 ,100 ;p:1; 
        类名container :10分 */
        #main  p {  
            color: green;
        }
        .container p {
            color: red;
        }
    </style>
</head>
<body>
    <!-- id 唯一,class进行分类,都是标签的属性 -->
    <div id="main" class="container">
        <p>这是一段美好的晚上,被id或是container限定,层叠样式</p>
        <p style="color: pink;">行内样式,1000分</p>
    </div>
    <p>这是外面的风</p>
</body>
</html>

image.png 组合选择器

  • 后代选择器 空格
  • 子代选择权 +
  • 相邻兄弟选择器 +
  • 通用选择器 ~
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>选择器</title>
    <style>
        /* 相邻兄弟选择器 相近的p进行渲染 */
        h1 + p {
            color: red;
        }
        /* 通用兄弟选择器  所有的兄弟p进行渲染, */
        h1 ~ p {
            color: green;
        }
        /*子元素选择器 container 里面 p进行加粗 */
        .container > p {
           font-weight: bold ;
        }
        /* 后代选择器  所有p加上下划线*/
        .container p {
           text-decoration: underline;
       } 
    </style>
</head>
<body>
    <div class="container">
        <h1>标题</h1>
        <p>这是一个段落     </p>
        <p>这是第二段</p>
        <a href="#"> 链接</a>    
        <span>是span</span>
        <div class="inner">
            <p>这是内部段落</p>
        </div>
    </div>
</body>
</html>

image.png 伪类选取

  • ::active
  • ::hover
  • ::selection 这些都是鼠标事件,可以进行交互 input:checked + label { color: red; } 当页面上有一个 input 元素(如复选框或单选按钮),并且该元素处于选中状态checked时,这个选择器会查找紧挨着该 input 元素的 label 元素。 一旦找到这样的 label 元素,就会将其文本颜色设置为红色。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>伪类选择2</title>
    <style>
        /* 正在被点击的 */
        button:active {
            background-color: red;
            color: white;
        }
        /* 伪类选择不同状态 */
        p:hover {
            color: pink;
            background-color: yellow;
        }
        /* 选中 */
        ::selection {
            background-color: green;
            color: white;
        }
        input:focus {
            border:2px solid blue;
        }
        /* cheack 选中  */
        input:checked + label {
            color: red;
        }
        /* 选中一类 */
        li:nth-child(odd) {
            background-color: lightgray;
        }
        /* 除了最后一个元素li ,其他加间距 */
        li:not(:last-child) {
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>伪类选择器示例</h1>
        <button>点击我</button>
        <p>鼠标悬浮在这里</p>
        <input type="text" placeholder="输入框">
        <input type="checkbox" id="option1"checked>
        <label for="option1">选项1</label>
        <input type="checkbox" id="option2" >
        <label >选项2</label>
        <ul>
          <li>列表项1</li>
          <li>列表项2</li>
          <li>列表项3</li>
          <li>列表项4</li>
        </ul>
      </div>
</body>
</html>

image.png

nth-child VS nth-of-type

  • nth-of-type :基于子类p进行选择第三个
  • nth-child(n) 第n个,例如:.container :nth-child(3) 选择p第三个
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    /* 注重顺序,前面 p 选中相邻的第三个,但是是div选择不了~!! */
    .container :nth-child(3) {
      color: red;
      background-color: black;
    }
    .container p:nth-child(3) {
      color: red;
      background-color: black;
    }

    /* nth-of-type :基于子类p进行选择第三个 */
   .container p:nth-of-type(3) {
      color: black;
      background-color: aquamarine;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>nth-child vs nth-of-type 例子</h1>
    <p>这是一个段落</p>
    <div>这是一个div</div>
    <p>这是第二个段落</p>
    <p>这是第三个段落</p>
    <div>这是第二个div</div>
  </div>
</body>
</html>

image.png