CSS 底层基础解析
何为CSS?
CSS,全称Cascading Style Sheets(层叠样式表),是用于描述HTML或XML文档外观的一种样式表语言。它通过一系列的规则集(Ruleset)来定义网页元素的样式。一个典型的规则集由两部分组成:选择器(Selector)和声明块(Declaration Block)。选择器用来指定要应用样式的HTML元素,而声明块则包含了具体如何改变这些元素样式的属性和值。
/* css rules */
/* 规则集Ruleset */
h1 { /* 选择器 */
color: red;/* 声明 */
text-align: center;/* 声明 */
}
在这个例子中,h1
是选择器,表示所有 <h1>
元素将被这个规则集所影响;color
和 text-align
则是声明,它们分别设置了文本颜色和对齐方式。
CSS为什么叫“层叠”样式表?
渲染过程
整个渲染过程大致如下:
- 下载样式:浏览器从服务器获取所有必要的CSS文件。
dom + css = rander tree(显示页面 数据结构) 渲染树 - 解析DOM:同时,浏览器解析HTML代码,构建出DOM树。
- 构造渲染树:一旦样式和DOM准备就绪,浏览器就会结合两者创建渲染树。在这个阶段,非显示元素(如
<script>
标签或带有display: none;
样式的元素)不会被加入到渲染树中。 - 布局计算:接下来,浏览器根据渲染树中的信息计算每个元素的位置和尺寸。
- 绘制页面:最后一步是绘制,浏览器将渲染树转化为屏幕上的像素,完成页面的实际显示。
css——style示例:
<style>
/* css_Ruleset */
/* 1分 */
p{
/* important权重值最高 */
color:blue !important;
}
/* 101分 */
.container p {
color:red;
}
/* 11分 */
#main p{
color:green;
}
/* 111分 */
#main.container p{
color:yellow;
}
/*
标签优先级为1
class 优先级为10
id 优先级为100
important 优先级为无穷大
权重值相等 就近原则
*/
</style>
查找相应标签的css样式大致流程如下:
样式引入方式
CSS可以通过以下几种方式引入到HTML文档中:
- 内联样式:直接在HTML标签内使用
style
属性定义样式。 - 外联样式:通过
<link>
标签链接外部样式表文件。 - @import:在样式表内部导入其他样式表,注意这种方式可能会影响加载性能。
- 行内样式:与内联样式类似,但在某些情况下,它指的是在JavaScript中动态设置元素的样式属性。
优先级机制
CSS有一套严格的优先级计算规则,用于决定当多个规则应用于同一元素时哪一个应该生效。优先级从低到高排列如下:
- 标签选择器:1分
- 类选择器:10分
- ID选择器:100分
- 行内样式:1000分
!important
:强制最高优先级,10000分
如果选择器组合变得复杂,优先级会相应地累加。例如,.container ul li:nth-child(odd)
这个选择器总共有22分的优先级(类选择器10分 + 标签选择器2分 + 伪类选择器10分)。
这里需要注意的是选择器都是选择最后的元素,在这里是 li"
CSS选择器分类
CSS选择器大致可以分为几大类:
-
基础选择器
- 标签选择器:匹配特定类型的HTML标签。
- 类选择器:匹配拥有特定类名的元素。
- ID选择器:匹配具有唯一ID属性的元素。
- 通配选择器:匹配所有元素,但不推荐频繁使用,因为它可能会导致性能问题。
-
组合选择器
- 后代选择器:通过空格分隔两个选择器,表示后者是前者的后代。
- 子选择器:使用
>
符号,表示后者是前者的直接子元素。 - 相邻兄弟选择器:使用
+
符号,表示后者紧跟在前者之后。 - 普通兄弟选择器:使用
~
符号,表示两者同级但不必紧邻。 示例:
<!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 */
h1 + p{
color: red;
}
/* 通用兄弟选择器 */
h1 ~ p{
color: blue;
}
/* 后代选择器 */
.container p{
color: green;
}
/* 直接子元素选择器 */
.container > p{
color: pink;
}
</style>
</head>
<body>
<div class="container">
<h1>标题</h1>
<p>这是第一段文字</p>
<p>这是第二段文字</p>
<span>这是一个span元素</span>
<div class="inner">
<p>这是一个内部的段落</p>
</div>
</div>
</body>
</html>
效果图:
需要注意的是,这里的.container p
和.container > p
优先级是一样的,所以后面的会覆盖上面的样式。
/* 后代选择器 */
.container p{
color: green;
}
/* 直接子元素选择器 */
.container > p{
color: pink;
}
-
伪类选择器
- 动态伪类:例如
:active
,:hover
,:focus
,::selection
等,用于匹配处于特定状态下的元素。 - 结构性伪类:如
:first-child
,: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>伪类选择器示例</title>
<style>
/* 伪类选择不同的 */
button:active{
background-color: red;
color: white;
}
/* 鼠标覆盖 */
p:hover{
background-color: yellow;
}
/* ::选中文字 */
::selection{
background-color: blue;
/* 背景颜色 */
color: white;
/* 字体颜色 */
}
/* focus是一个伪类选择器,用于选择当前具有焦点的元素。 */
input:focus{
border:5px solid blue;
}
input:checked + label{
color: blue;
}
li:nth-child(odd){
background-color: silver;
}
/* 除了最后一个 */
li:not(:last-child){
border-bottom: 1px solid red;
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>
效果展示:
button:active:
p:hover:
::selection:
input:focus 和 input:checked + label:
li:nth-child(odd) 和 li:not(:last-child):
注意哦!在结构性伪类中,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:nth-child顺序选择 选择子元素,且要满足是p标签,否则不会显示 */
.container p:nth-child(3){
background-color: yellow;
color: black;
}
/*p:of-type根据选择子元素(p)的类型来选择该元素 */
.container p:nth-of-type(3){
background-color: lightblue;
color: black;
}
</style>
</head>
<body>
<div class="container">
<h1>nt-child vs nth-of-type 例子</h1>
<p>这是第一个段落</p>
<div>这是一个div</div>
<p>这是第二段落</p>
<p>这是第三段落</p>
<div>这是第二个div</div>
</div>
</body>
</html>
效果如下:
- 这里为什么没有显现
p:nth-child(3)
里面的属性呢,是因为在.container
容器里面的第三个元素是div
,而不是p
所以不满足查找需求,不显示。- 这里如果把
p:nth-child(3)
替换成div:nth-child(3)
或者把p
去掉可以显示效果,因为第三个元素是div,而去掉p那就无论是哪个元素都显示效果。
- 这里如果把
- 反之这里的
p:nth-of-type(3)
显示是因为在.container容器里面存在三个p元素类型标签,所以就显示了效果。- 那我们会想如果把p去掉,是不是就显示第三个.container容器里面所有的元素。这里博主试过了显然显示效果没变。为什么?因为把p去掉后,选择器会查找里面所有类型的第三的元素,然后显示效果。
- 这里我们添加上第三个
<div>
元素试试。
修改
<body>
<div class="container">
<h1>nt-child vs nth-of-type 例子</h1>
<p>这是第一个段落</p>
<div>这是一个div</div>
<p>这是第二段落</p>
<p>这是第三段落</p>
<div>这是第二个div</div>
<div>这是第三个div</div>
</div>
</body>
显示效果:
-
属性选择器
- 根据元素的属性及其值来选择元素,提供了更精确的选择能力。
理解这些基础知识对于任何想要深入学习CSS的人来说都是至关重要的。掌握它们可以帮助开发者更好地控制网页布局和设计,创造出既美观又高效的用户界面。