CSS和CSS选择器:构建网页样式的基础

174 阅读6分钟

CSS和CSS选择器:构建网页样式的基础

什么是CSS?

CSS(层叠样式表,Cascading Style Sheets)是用于描述HTML或XML(包括如SVG、MathML或XHTML等XML文档)文档外观的样式表语言。它是一种用来增强内容(结构化文档)的视觉表现的语言。通过CSS,我们可以定义文本的颜色、字体大小、背景颜色、元素的位置等等,从而控制整个网站或单个页面的布局和外观。

在网页开发中,HTML负责创建内容的结构,而CSS则负责这些结构的外观。二者相辅相成,缺一不可。没有CSS,HTML文档将仅仅是一些基础文本和链接;同样地,没有HTML提供的DOM,CSS也没有任何作用的对象。

CSS的工作原理

浏览器在加载一个网页时,首先是下载并解析HTML文档,在此期间遇到的外部CSS文件会被尽快下载,但不会阻碍HTML文档的继续解析。只有当HTML文档和相关样式都准备好后,才会进入渲染阶段,生成用户最终看到的页面。这种设计确保了即使在网络条件不佳的情况下,用户也能尽早看到页面的基本结构,从而改善用户体验。

样式优先级

CSS的另一个重要概念是样式优先级。当多个样式规则应用于同一个元素时,需要一种机制来决定哪个规则生效。优先级计算遵循以下原则:

  • 内联样式(即通过HTML标签的style属性定义的样式)的特殊性为 1000
  • ID选择器 的特殊性为 100
  • 类选择器、伪类和属性选择器 的特殊性为 10
  • 标签选择器和伪元素 的特殊性为 1
  • !important:可以覆盖其他所有的优先级规则,除非它本身被另一个!important声明覆盖。

此外,如果两个相同优先级的选择器都适用于同一元素,那么后来者居上的原则适用——即最后定义的那个样式规则会被采用。

CSS选择器的分类及其特点

基础选择器
  • 标签选择器:选择特定类型的HTML标签,例如ph1等。
  • 类选择器:通过.符号加上类名来选择所有带有指定类的元素,例如.header
  • ID选择器:通过#符号加上ID名称来唯一标识页面中的某个元素,例如#logo
  • 通配符选择器*匹配页面上的所有元素。尽管简单易用,但由于其非特异性,通常不推荐大量使用,因为它可能导致性能问题。
组合选择器
  • 后代选择器:由空格分隔的两个选择器组成,前者为后者祖先元素时生效,例如nav a表示导航栏内的所有链接。
  • 子代选择器>符号连接的两个选择器,只有当后者是前者的直接子元素时才生效,例如ul > li
  • 相邻兄弟选择器+符号连接的选择器,只影响紧跟在前面元素后的同级元素,例如h2 + p
  • 普通兄弟选择器~符号连接的选择器,影响后面所有同级元素,直到遇到不属于此类别的元素为止,例如label ~ input
伪类和伪元素选择器
  • 伪类选择器:用于选择处于特殊状态下的元素,例如:hover:active:focus等。它们反映了用户交互的状态变化,如鼠标悬停、点击激活或键盘聚焦。
  • 伪元素选择器:允许开发者向选定元素添加额外的装饰性内容,而不必修改HTML结构。常见的有::before::after,分别在元素前后插入生成的内容。注意,伪元素选择器需要使用双冒号::,这是为了区分早期版本的单冒号语法,并且强调它们不是真正的DOM元素。
属性选择器
  • 属性选择器:允许基于元素的属性或属性值进行选择,例如input[type="text"]会选择所有文本输入框。这类选择器提供了更精细的控制能力,特别是在处理表单元素时非常有用。

栗子

标签 1 类名 10 id 100 行内 1000 !important 最大

  • 当选择器比较复杂的时候 优先级加法
  • 一定选择最后的元素
    <style>
       /* 1 */
       p {
           color: blue !important;/*!important 强制覆盖 */
       }
       /* 11 */
       .container p{
           color: red;
       }
       /* 101 */
       .main p {
           color: green;
       }
       .container span{
           color: red;
       }
       /* 101 */
       .main span{
           color: green;
       }
   </style>

<body>
   <!-- attributes属性 -->
   <div class="main" class="container">
       <!-- 行内样式 1000 -->
       <p style="color:pink">This is a paragraph</p>
       <span style="color:pink">This is span</span>
   </div>
</body>

image.png

    <style>
         /* 相邻兄弟选择器 连着  */
        h1 + p {
            color: red;
        }
        /* 通用兄弟选择器    +  ~不影响得分 */
        h1 ~ p {
            color: blue;
        }
        /* 子元素选择器 
            inner 元素内的 p 元素不会加粗
            只有直接子元素才会加粗
        */
        .container > p {
            font-weight: bold;
        }

        /*
        后代选择器
        container内所有的 p 元素都会加下划线
        */
        .container  p {
            text-decoration: underline;
        }
    </style>

<body>
    <div class="container">
        <h1>标题</h1>
        <p>这是第一段文字</p>
        <p>这是第二段文字</p>
        <a href="">链接</a>
        <span>这是一个span元素</span>
        <p>这是第三段文字</p>
        <div class="inner">
            <p>这是内部的段落</p>
        </div>
    </div>
</body

image.png


    <style>
        /* 伪类选择元素的不同状态 */
        button:active {
            background-color: red;
            color: white;
        }
        /*悬停状态和没悬停状态是两种分类,但是我没去添加class
          什么是伪类?-很像类,但是不是类(class) ,是元素特殊状态的一种描述
        */
        p:hover {
            background-color: yellow;
        }
        /*
        什么是伪元素?-很像元素,但是不是元素(element) ,是元素的一些特殊的位置
        */
        ::selection {
            background-color: pink;
            color: white;
        }

        input:focus {
            border: 2px solid red;
        }

        input:checked + label {
            color: blue;
        }

        li:nth-child(odd) {
            background-color: lightgray;
        }

        li:not(:last-child) {
            margin-bottom: 10px;
        }
    </style>

<body>
    <div class="container">
        <h1>伪类选择器</h1>
        <button>点击我</button>
        <p>鼠标悬浮在这里</p>
        <input type="text" placeholder="输入框">
        <input type="checkbox" id="option1">
        <label for="option1">选项1</label>
        <input type="checkbox" id="option2" checked>
        <label for="option2">选项2</label>
        <ul>
            <li>列表1</li>
            <li>列表2</li>
            <li>列表3</li>  
            <li>列表4</li>
        </ul>
    </div>
</body>
</html>

image.png



<style>
    /* 
    nth-child(3) 是一个基于元素在父元素中的位置的伪类选择器,
    匹配 .container 中的第三个子元素。
    如果 .container 中的第三个子元素是一个 p 元素,那么这个样式才会应用;
    但如果在这个位置是其他元素(如 div、h1 等),这个样式将不会应用。
    */
    /*顺序*/
    .container p:nth-child(3) {
        background-color: yellow;
        color: black;
    }


    /*
    nth-of-type(3) 是基于类型的伪类选择器,匹配母元素下的第三个 p 元素。
   这个选择器只关注 p 元素,因此如果在 .container 中的第三个位置是其他类型的元素,则不会被选中。
    */

    /*基于类型*/
    .container p:nth-of-type(3) {
        background-color: red;
        color: black;
    }
</style>
<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


    <style>
        /* 1. 简单属性选择器 */
        a[href] {
            color: yellow;
        }

        /* 2. 属性等于值选择器 */
        input[type="text"] {
            border: 2px solid gray;
        }

        /* 3. 属性包含特定子串的选择器 */
        a[href*="product"] {
            color: red;
        }
    </style>
<body>
<h2>属性选择器示例页面</h2> 
<a href="https://example.com">普通链接</a><br>
<a href="https://shop.example.com/product/shoes">产品链接 (包含 'product')</a><br>
<form>
    <label for="username">用户名:</label>
    <input type="text" name="username" id="username"><br><br>
    
    <label for="password">密码:</label>
    <input type="password" name="password" id="password"><br><br>
</form>
</body>
</html>

image.png