引言
在现代的网页设计中,CSS扮演着至关重要的角色。本文将从CSS底层基础出发,探讨CSS的四个底层基础:css的组成、引入方式、选择器和优先级。
什么是CSS?
层叠样式表(Cascading Style Sheets,缩写为 CSS)。CSS是一种用于控制网页布局及样式的语言。通过CSS,开发者可以精确地定义HTML元素的颜色、字体、间距等外观属性,从而实现美观的设计风格。
下面是一段简单的css结构
css由这几个部分组成:
- Ruleset(css样式规则):css是由多个Ruleset组合而成,形成样式表。样式规则由选择器+{}组成
- Select(选择器):用于选中HTML元素并应用CSS样式。
- 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>中呢?
有以下几点好处:
- 提高页面加载速度:当浏览器开始解析HTML文档时,它会从上到下依次读取内容。这意味着即使样式文件较大,用户也能更快地看到基本的页面布局,从而改善用户体验。
- 防止FOUC (Flash of Unstyled Content) :FOUC是指在样式加载完成前,用户可能会短暂地看到未经过任何样式处理的内容。将CSS放置于
<head>部分有助于减少这种现象的发生,因为浏览器可以更早地获取到样式信息,并尽早应用它们给页面元素。 - 遵循最佳实践:根据W3C标准和其他Web开发指南,将外部资源如CSS、JavaScript等声明性地放在
<head>部分是一种良好的习惯。这不仅有助于保持代码结构清晰有序,还便于其他开发者理解和维护。 - SEO友好:虽然搜索引擎对CSS位置的要求并不严格,但合理安排CSS的位置可以帮助搜索引擎更好地理解你的网页结构,间接提升SEO效果。此外,快速加载的页面往往能获得更好的排名,而优化CSS加载是实现这一目标的重要步骤之一。
- 控制文档流:将所有样式定义提前加载,确保了页面中的元素能够按照预期的方式显示出来,避免因样式加载延迟而导致的布局重排问题。
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>
伪类选择器:
用于匹配处于特定状态下的元素。伪类有很多种,在这里我们只简单介绍几个。
: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>
选择器优先级
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>
请看结果:
!important为无穷大,显示为蓝色
如果去掉!important,结果如下:
正如代码中注释计算的那样,绿色的优先级为101最高,显示为绿色
渲染树(renderTree)
下面我们来介绍一下浏览器的渲染过程:
浏览器首先解析HTML文档构建DOM树,然后下载并解析CSS文件,将样式规则应用到DOM树中的相应元素上,生成包含所有需渲染元素及其样式信息的渲染树。接着,渲染引擎根据渲染树计算每个元素的具体布局和样式,最终将这些信息转换为屏幕上的像素,显示给用户。
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>
结果如图
总结
通过对CSS选择器、优先级等概念的深入理解,我们可以更加高效地组织代码,创造所需要的用户界面,了解浏览器的渲染方式,打好底层基础。