快进来看!大佬必须掌握的CSS的底层基础!!!

886 阅读7分钟

引言

在现代的网页设计中,CSS扮演着至关重要的角色。本文将从CSS底层基础出发,探讨CSS的四个底层基础:css的组成、引入方式、选择器和优先级。

什么是CSS?

层叠样式表(Cascading Style Sheets,缩写为 CSS)。CSS是一种用于控制网页布局及样式的语言。通过CSS,开发者可以精确地定义HTML元素的颜色、字体、间距等外观属性,从而实现美观的设计风格。

下面是一段简单的css结构 image.png css由这几个部分组成:

  1. Ruleset(css样式规则):css是由多个Ruleset组合而成,形成样式表。样式规则由选择器+{}组成
  2. Select(选择器):用于选中HTML元素并应用CSS样式。
  3. Declaration(声明):声明以键值对的形式由属性(Property)和值(Value)组成,用于定义具体的样式规则。

在这里,h1是选择器,指定了要应用样式的HTML标签,选中h1标签;而font-size:1.25rem;则是声明,设置了字体大小。

CSS的引入方法

CSS依赖于HTML和DOM,他不能单独存在。要想使用CSS,必须先引用它。CSS可以通过多种方式被引入到HTML文档中:

  • 内联样式:直接写在HTML元素的style属性里,style一般放在<head>头部中,在<body>之前。
  • 行内样式:可以在某些情况下快速测试样式效果。
  • 外部链接:通过<link>标签引用外部.css文件,这种方式有利于维护和重用样式表,一般在<head>头部中引入。

这里我想抛出一个问题:为什么CSS要放在<head>中呢?

有以下几点好处:

  1. 提高页面加载速度:当浏览器开始解析HTML文档时,它会从上到下依次读取内容。这意味着即使样式文件较大,用户也能更快地看到基本的页面布局,从而改善用户体验。
  2. 防止FOUC (Flash of Unstyled Content) :FOUC是指在样式加载完成前,用户可能会短暂地看到未经过任何样式处理的内容。将CSS放置于<head>部分有助于减少这种现象的发生,因为浏览器可以更早地获取到样式信息,并尽早应用它们给页面元素。
  3. 遵循最佳实践:根据W3C标准和其他Web开发指南,将外部资源如CSS、JavaScript等声明性地放在<head>部分是一种良好的习惯。这不仅有助于保持代码结构清晰有序,还便于其他开发者理解和维护。
  4. SEO友好:虽然搜索引擎对CSS位置的要求并不严格,但合理安排CSS的位置可以帮助搜索引擎更好地理解你的网页结构,间接提升SEO效果。此外,快速加载的页面往往能获得更好的排名,而优化CSS加载是实现这一目标的重要步骤之一。
  5. 控制文档流:将所有样式定义提前加载,确保了页面中的元素能够按照预期的方式显示出来,避免因样式加载延迟而导致的布局重排问题。

CSS选择器

选择器可以选中HTML元素并应用CSS样式。相信你一定知道,但是我们可以整合一下,把CSS分分类。以下是CSS选择器几种类型:

  • 基础选择器
    • 标签选择器(直接选择标签名)
    • 类选择器(.选取HTML的class属性)
    • ID选择器(#选取HTML的id属性,id值是唯一的,ID选择器选取速度快!)
    • 通配符选择器(*虽然功能强大但性能不好,因此应谨慎使用。)
  • 组合选择器
    • 后代选择器(空格分隔,选择所有后代)
    • 子元素选择器(>只能选取儿子辈的)
    • 相邻兄弟选择器(+选取相邻的兄弟)
    • 普通兄弟选择器(~选取所有兄弟)。
  • 伪类选择器 用于匹配处于特定状态下的元素,如:hover, :active等,增强了交互体验。
  • 伪元素选择器 则用来添加额外的内容或样式,如::before::after
  • 属性选择器 可以根据元素的属性及其值来选择元素,增加了灵活性。

组合选择器: 允许更精细,准确地控制样式继承关系

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>组合选择器</title>
    <style>
        /* 相邻兄弟选择器 连着的 */
        h1+p {
            color: red;
        }
        /* 通用兄弟选择器 位于h1之后所有的 */
        h1~p {
            color: blue;
        }
        /* 子元素选择器 */
        .container>p {
            font-weight: bold;
        }
        /* 后代选择器 */
        .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 :用于定义用户选中文本时的样式

:focus :元素获取焦点时的样式

:checked :被选中的input元素,如单选框和多选框。 在这里使用:checked+label,与相邻兄弟选择器相结合,选中后使后面的label改变

:nth-child(n)  :用来选择属于其父元素的第n个子元素

:not() :不选择

:last-child :最后一个孩子

<!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>
        /* 伪类选择不同的状态 */
        /* 点击时 */
        button:active {
            background-color: red;
            color: white;
        }
        /* 鼠标悬停时 */
        p:hover {
            background-color: yellow;
        }
        /* 选中文本 */
        ::selection {
            background-color: blue;
            color: white;
        }
        /* 获得焦点 */
        input:focus {
            border: 2px solid blue;
        }
        /* 选中的选项高亮 */
        input:checked+label {
            color: blue;
        }
        /* 选取奇数的孩子 */
        li:nth-child(odd) {
            background-color: lightgrey;
        }
        /* 除了最后一个元素 */
        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">
        <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

选择器优先级

CSS优先级决定了当多个规则同时作用于同一个元素时,哪些规则会被实际应用。优先级基于以下几点计算:

  • !important:无穷大!!!
  • 行内样式:具有最高优先级,值为1000。
  • ID选择器:次之,值为100。
  • 类名、伪类和属性选择器:再次,值为10。
  • 标签名和伪元素:最低,值为1。

当遇到复杂的复合选择器时,优先级通过简单相加计算得出。例如,.container ul li:nth-child(odd) 的优先级就是22(10 + 1 + 1 + 10)。如果两个选择器的优先级相同,则最后定义的那个生效,它将前面的覆盖掉了。

下面将给出几个例子帮助我们理解

<!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>
        /* 1 */
        /* important 无穷大 */
        p {
            color: blue !important;
        }
        /* 100 + 1 */
        #main p {
            color: green;
        }
        /* 10 + 1 */
        .container p {
            color: red;
        }
    </style>
</head>
<body>
    <!-- attribute 属性 -->
    <div id="main" class="container">
        <!-- 1000 -->
        <p style="color:pink">这是一段张三的爱情故事</p>
    </div>
</body>
</html>

请看结果:

image.png !important为无穷大,显示为蓝色

如果去掉!important,结果如下:

image.png 正如代码中注释计算的那样,绿色的优先级为101最高,显示为绿色

渲染树(renderTree)

下面我们来介绍一下浏览器的渲染过程:

浏览器首先解析HTML文档构建DOM树,然后下载并解析CSS文件,将样式规则应用到DOM树中的相应元素上,生成包含所有需渲染元素及其样式信息的渲染树。接着,渲染引擎根据渲染树计算每个元素的具体布局和样式,最终将这些信息转换为屏幕上的像素,显示给用户。

lQLPJxNqPKtbtc3NAnDNA5uwHWI_2cmMNqAHL4-dHacYAA_923_624.png

nth-child vs nth-of-type

这里有两个比较相似的伪类选择器,新手小白很容易将它们搞混。 接下来,我们将详细介绍这两者之间的区别。

:nth-child 只考虑数据的顺序,而不考虑数据的类型 :nth-of-type 只考虑数据的类型

通过例子更好了解

<!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,没有选中 不生效 */
        .container p:nth-child(3) {
            background-color: yellow;
            color: black;
        }
        /* 基于子元素的类型 of-type */
        /* 选取第三个 p */
        .container p:nth-of-type(3) {
            background-color: lightblue;
            color: black;
        }
    </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

总结

通过对CSS选择器、优先级等概念的深入理解,我们可以更加高效地组织代码,创造所需要的用户界面,了解浏览器的渲染方式,打好底层基础。