对于一个网站来说,HTML是它的骨架,而CSS则是赋予这个骨架生命与个性的关键。让我们一起探索CSS的魅力吧!
什么是CSS?
CSS全称为Cascading Style Sheets(层叠样式表),它是一种用来控制网页布局、外观的设计语言。通过使用CSS,我们可以轻松地改变文字的颜色、大小、字体等属性,以及调整页面元素的位置和布局。下面是一个简单的例子:
/* 这是一条CSS规则 */
h1 { /* 选择器 */
color: red; /* 声明:设置颜色为红色 */
text-align: center; /* 声明:居中对齐 */
}
在这段代码中,h1是选择器,它指定了哪一部分HTML内容将被这条规则影响;大括号内的部分被称为声明块,其中包含了具体的样式声明。
CSS的工作原理
-
依附于HTML:CSS本身不能独立运行,它必须与HTML文档相结合才能发挥作用。
-
选择DOM元素并应用样式:CSS通过特定的选择器来定位HTML文档中的元素,并为其添加样式。
-
引入方式:
- 内联样式:直接在HTML标签内部使用
style属性定义样式。 - 外部样式:创建单独的
.css文件并通过<link>标签链接到HTML文档中。 - 行内样式:直接写入HTML元素的
style属性,如<p style="color: pink;"></p>。
- 内联样式:直接在HTML标签内部使用
浏览器首先下载所有需要的资源,然后解析HTML形成DOM树,接着根据CSS规则构建渲染树,最后由渲染引擎将这些信息转化为用户可见的网页。
样式优先级
当多个CSS规则同时作用于同一个元素时,浏览器会根据一定的规则决定采用哪个规则。这里涉及到几个关键点:
- 基础权重:从低到高依次为标签(1) < 类名(10) < ID(100) < 行内样式(1000) <
!important(最大)。 - 复杂选择器的权重计算:当选择器包含多个部分时,其总权重等于各部分权重之和。
- 优先级顺序:行内样式 > 内部样式 > 外部样式。
例如,对于选择器.container ul li:nth-child(odd),其权重为22 (类名10 + 标签1 + 后代选择器1 + 伪类选择器10)。
CSS选择器种类
CSS选择器是CSS中非常重要的组成部分,它们允许开发者精确地定位HTML文档中的元素,并为其应用样式。CSS选择器种类繁多,可以满足各种复杂的需求。下面我将详细介绍CSS的主要选择器类型:
1. 基础选择器
- 标签选择器:直接使用HTML标签名作为选择器,如
p、div等。 - 类选择器:通过
.class_name形式来选择具有特定类属性的元素。 - ID选择器:通过
#id_name形式来选择拥有特定ID的元素。 - 通配符选择器:用
*表示,可以选择所有元素。
2. 组合选择器
- 后代选择器(空格):例如
div p会选择所有位于<div>内部的<p>元素。 - 子元素选择器(>):例如
div > p仅选择直接子元素为<p>的<div>。 - 相邻兄弟选择器(+):例如
h1 + p选择紧跟在<h1>之后的第一个<p>元素。 - 普通兄弟选择器(~):例如
h1 ~ p选择与<h1>处于同一父元素下的所有后续<p>元素。
3. 伪类选择器
伪类用于定义元素的特定状态:
- 动态伪类:
:hover,:active,:focus - 目标伪类:
:target - 结构伪类:
:first-child,:last-child,:nth-child(n),:only-child,:empty
4. 伪元素选择器
伪元素用于选取并设置元素的特定部分:
::before和::after:用于在内容前或后插入生成的内容。::first-line和::first-letter:分别作用于段落的第一行和第一个字母。::selection:用于设置用户选中文本时的样式。
5. 属性选择器
基于元素的属性值来选择元素:
[attribute]:选择有指定属性的元素。[attribute=value]:选择属性值完全匹配的元素。[attribute~=value]:选择包含以空格分隔的多个值之一的元素。[attribute^=value]、[attribute$=value]、[attribute*=value]:分别选择属性值以指定字符串开头、结尾或包含指定字符串的元素。
下面是针对每种选择器类型的具体代码示例:
1. 基础选择器
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>基础选择器示例</title>
<style>
/* 标签选择器:选择所有<p>标签 */
p {
color: blue; /* 设置文字颜色为蓝色 */
}
/* 类选择器:选择所有带有class属性值为"highlight"的元素 */
.highlight {
background-color: yellow; /* 设置背景颜色为黄色 */
}
/* ID选择器:选择ID为"special"的唯一元素 */
#special {
font-weight: bold; /* 设置字体加粗 */
}
/* 通配符选择器:选择文档中的所有元素 */
* {
margin: 0; /* 清除所有元素的外边距 */
padding: 0; /* 清除所有元素的内边距 */
}
</style>
</head>
<body>
<p>这是一个普通的段落。</p>
<p class="highlight">这个段落有高亮背景。</p>
<p id="special">这个段落使用了ID选择器。</p>
<div>所有的元素都有默认的外边距和内边距被清除。</div>
</body>
</html>
2. 组合选择器
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>组合选择器示例</title>
<style>
/* 后代选择器:选择所有位于<div>内的<p>标签 */
div p {
color: green; /* 设置文字颜色为绿色 */
}
/* 子元素选择器:选择直接子元素为<p>的<div> */
div > p {
font-style: italic; /* 设置斜体 */
}
/* 相邻兄弟选择器:选择紧跟在<h1>之后的第一个<p> */
h1 + p {
text-decoration: underline; /* 添加下划线 */
}
/* 普通兄弟选择器:选择与<h1>处于同一父元素下的所有后续<p> */
h1 ~ p {
border: 1px solid black; /* 添加黑色边框 */
}
</style>
</head>
<body>
<div>
<h1>标题</h1>
<p>这是直接子元素。</p>
<section>
<p>这是后代元素。</p>
</section>
</div>
<h1>另一个标题</h1>
<p>这是相邻兄弟元素。</p>
<p>这也是普通兄弟元素之一。</p>
<p>这也是普通兄弟元素之一。</p>
</body>
</html>
3. 伪类选择器
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>伪类选择器示例</title>
<style>
/* 未访问过的链接 */
a:link {
color: blue; /* 设置链接颜色为蓝色 */
}
/* 已访问过的链接 */
a:visited {
color: purple; /* 设置链接颜色为紫色 */
}
/* 鼠标悬停时的链接 */
a:hover {
color: red; /* 设置链接颜色为红色 */
}
/* 链接被激活(点击)时 */
a:active {
color: orange; /* 设置链接颜色为橙色 */
}
/* 第一个子元素 */
p:first-child {
font-size: 1.5em; /* 设置第一个段落的文字大小为1.5倍 */
}
/* 奇数行列表项 */
li:nth-child(odd) {
background-color: lightgray; /* 设置奇数行列表项的背景颜色为浅灰色 */
}
</style>
</head>
<body>
<a href="#">链接文本</a>
<p>第一个段落,字体较大。</p>
<p>第二个段落。</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ul>
</body>
</html>
4. 伪元素选择器
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>伪元素选择器示例</title>
<style>
/* 段落的第一行 */
p::first-line {
font-weight: bold; /* 设置第一行文字加粗 */
}
/* 段落的第一个字母 */
p::first-letter {
font-size: 2em; /* 设置第一个字母的字体大小为2倍 */
}
/* 在段落前插入内容 */
p::before {
content: "开始 -> "; /* 插入的内容 */
color: red; /* 设置插入内容的颜色为红色 */
}
/* 在段落后插入内容 */
p::after {
content: " <- 结束"; /* 插入的内容 */
color: blue; /* 设置插入内容的颜色为蓝色 */
}
/* 用户选中的文本 */
::selection {
background: yellow; /* 设置选中文本的背景颜色为黄色 */
color: black; /* 设置选中文本的颜色为黑色 */
}
</style>
</head>
<body>
<p>这是一个测试段落,用于展示伪元素的效果。</p>
<p>尝试选中一些文本看看效果。</p>
</body>
</html>
5. 属性选择器
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>属性选择器示例</title>
<style>
/* 任何带有data-type属性的元素 */
[data-type] {
color: green; /* 设置文字颜色为绿色 */
}
/* data-type属性值为"important"的元素 */
[data-type="important"] {
font-weight: bold; /* 设置字体加粗 */
}
/* data-type属性值包含"note"(以空格分隔)的元素 */
[data-type~="note"] {
background-color: lightyellow; /* 设置背景颜色为浅黄色 */
}
/* href属性以"http"开头的<a>标签 */
[href^="http"] {
color: blue; /* 设置链接颜色为蓝色 */
}
/* href属性以".pdf"结尾的<a>标签 */
[href$=".pdf"] {
color: red; /* 设置链接颜色为红色 */
}
/* href属性包含"example"的<a>标签 */
[href*="example"] {
text-decoration: none; /* 移除下划线 */
}
</style>
</head>
<body>
<p data-type="important note">这是一条重要信息。</p>
<a href="http://example.com">访问示例网站</a>
<a href="document.pdf">下载文档</a>
<a href="https://another-example.org">另一个示例链接</a>
</body>
</html>
具体例子
下面我们举几个例子让你更加直观的理解CSS的魔法
例1
<!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 */
p {
color: blue !important;
}
/* !important 优先级最高 */
/* 11 */
.container p {
color: red;
}
/* 101 */
#main p {
color: green;
}
</style>
</head>
<body>
<!-- attribute 属性 -->
<div id="main" class="container">
<p style="color: pink;">这是一段文字</p>
<!-- 行内样式1000 -->
</div>
</body>
</html>
这段HTML代码展示了不同CSS选择器的优先级以及!important声明的效果。让我们解释这段代码:
优先级分析
-
行内样式 (
style="color: pink;"):- 优先级:1000
- 通常情况下,行内样式的优先级是最高的。
-
ID选择器 (
#main p):- 优先级:100 + 1
- 如果没有更高的优先级样式,
<p>标签的文字颜色会是绿色。
-
类选择器 (
.container p):- 优先级:10 + 1
- 如果没有更高的优先级样式,
<p>标签的文字颜色会是红色。
-
标签选择器 (
p):- 优先级:1
- 但是这里使用了
!important,所以它的实际优先级非常高。
重要性声明 !important
!important使得该规则的优先级高于普通CSS规则,即使在其他规则有更高优先级的情况下也是如此。- 在本例中,
p { color: blue !important; }的优先级被提升到最高级别,甚至高于行内样式的优先级(1000)。
最终结果
由于 p { color: blue !important; } 使用了 !important,它将覆盖所有其他样式,包括行内样式 style="color: pink;"。因此,最终显示的文字颜色将是蓝色。
结论
- 行内样式虽然通常具有最高的优先级(1000),但在遇到带有
!important的声明时,会被!important声明覆盖。 - 因此,最终
<p>标签的文字颜色是蓝色。
例2
<!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~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>
选择器效果分析
-
相邻兄弟选择器 (
h1 + p) :- 选择紧跟在
<h1>之后的第一个<p>元素。 - 适用元素:
<p>这是第一段文字</p> - 效果:文字颜色为红色。
- 选择紧跟在
-
普通兄弟选择器 (
h1 ~ p) :- 选择所有与
<h1>在同一父元素下的<p>元素。 - 适用元素:
<p>这是第一段文字</p>和<p>这是第二段文字</p> - 效果:文字颜色为蓝色。
- 选择所有与
-
子元素选择器 (
container > p) :- 选择类名为
container的元素内的所有直接子<p>元素。 - 适用元素:
<p>这是第一段文字</p>和<p>这是第二段文字</p> - 效果:字体加粗。
- 选择类名为
-
后代元素选择器 (
container p) :- 选择类名为
container的元素内的所有后代<p>元素。 - 适用元素:
<p>这是第一段文字</p>、<p>这是第二段文字</p>和<p>这是一个内部的段落</p> - 效果:添加下划线。
- 选择类名为
优先级分析
h1 + p { color: red; }的优先级是11。h1 ~ p { color: blue; }的优先级也是11。.container > p { font-weight: bold; }的优先级是11。.container p { text-decoration: underline; }的优先级是11。
最终结果
-
<p>这是第一段文字</p>:- 文字颜色:由于
h1 + p和h1 ~ p都设置了颜色,且它们的优先级相同,所以根据CSS规则,后定义的样式会覆盖前定义的样式。因此,最终文字颜色为蓝色。 - 字体加粗:由
.container > p决定。 - 添加下划线:由
.container p决定。
- 文字颜色:由于
-
<p>这是第二段文字</p>:- 文字颜色:由
h1 ~ p决定,为蓝色。 - 字体加粗:由
.container > p决定。 - 添加下划线:由
.container p决定。
- 文字颜色:由
-
<p>这是一个内部的段落</p>:- 文字颜色:默认颜色(未被任何选择器改变)。
- 字体不加粗:因为它不是直接子元素,而是后代元素。
- 添加下划线:由
.container p决定。
总结
<p>这是第一段文字</p>: 蓝色,加粗,带下划线。<p>这是第二段文字</p>: 蓝色,加粗,带下划线。<p>这是一个内部的段落</p>: 默认颜色,不加粗,带下划线。
例3
<!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: yellow;
color: white;
}
input:focus {
border: 5px solid blue;
}
input:checked+label {
color: blue;
}
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">
<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
- 选择器:
button:active - 适用元素:
<button>点击我</button> - 效果: 当按钮被激活(即鼠标按下时),按钮的背景颜色变为红色,文字颜色变为白色。
p:hover
- 选择器:
p:hover - 适用元素:
<p>鼠标悬浮在这里</p> - 效果: 当鼠标悬浮在段落上时,段落的背景颜色变为黄色。
::selection
- 选择器:
::selection - 适用元素: 选中的任何文本
- 效果: 当用户选中页面上的任何文本时,选中文本的背景颜色变为黄色,文字颜色变为白色。
input:focus
- 选择器:
input:focus - 适用元素:
<input type="text" placeholder="输入框"> - 效果: 当输入框获得焦点(即用户点击或使用Tab键导航到输入框时),输入框的边框变为5像素宽的蓝色实线。
input:checked + label
- 选择器:
input:checked + label - 适用元素:
<input type="checkbox" id="option1" checked>和紧跟在其后的<label for="option1">选项1</label>下面选项2的也如此 - 效果: 当复选框被选中时,紧跟在其后的
<label>标签的文字颜色变为蓝色。
li:nth-child(odd)
-
选择器:
li:nth-child(odd) -
适用元素:
<ul>中的奇数位置的<li>列表项 -
效果: 选择所有奇数位置的
<li>列表项,并将其背景颜色设置为浅灰色。- 适用元素:
<li>列表项1</li>和<li>列表项3</li>
- 适用元素:
li:not(:last-child)
-
选择器:
li:not(:last-child) -
适用元素:
<ul>中除了最后一个<li>以外的所有<li>列表项 -
效果: 选择所有不是最后一个子元素的
<li>列表项,并为其添加10像素的底部外边距。- 适用元素:
<li>列表项1</li>、<li>列表项2</li>和<li>列表项3</li>
- 适用元素:
最终结果
<button>点击我</button>
- 效果:当按钮被激活(鼠标按下时),背景颜色变为红色,文字颜色变为白色。
<p>鼠标悬浮在这里</p>
- 效果:当鼠标悬浮在段落上时,背景颜色变为黄色并且选中任何文本时文字背景颜色变成黄色,文字演示变成白色。
<input type="text" placeholder="输入框">
- 效果:当输入框获得焦点时,边框变为5像素宽的蓝色实线。
<input type="checkbox" id="option1"> 和 <label for="option1">选项1</label>
- 效果:当复选框未选中时,
<label>标签的文字颜色保持默认。
<input type="checkbox" id="option2" checked> 和 <label for="option2">选项2</label>
- 效果:当复选框被选中时,
<label>标签的文字颜色变为蓝色。
<ul> 中的 <li> 列表项
-
效果:
-
奇数位置的
<li>列表项的背景颜色为浅灰色。- 适用元素:
<li>列表项1</li>和<li>列表项3</li>
- 适用元素:
-
除了最后一个
<li>列表项外,其他每个<li>列表项都有10像素的底部外边距。- 适用元素:
<li>列表项1</li>、<li>列表项2</li>和<li>列表项3</li>
- 适用元素:
-
总结
-
按钮:当按钮被激活时,背景颜色变为红色,文字颜色变为白色。
-
段落:当鼠标悬浮在段落上时,背景颜色变为黄色。
-
选中文本:当用户选中页面上的任何文本时,选中文本的背景颜色变为黄色,文字颜色变为白色。
-
输入框:当输入框获得焦点时,边框变为5像素宽的蓝色实线。
-
复选框:当复选框被选中时,紧跟在其后的
<label>标签的文字颜色变为蓝色。 -
列表项:
- 奇数位置的列表项的背景颜色为浅灰色。
- 除了最后一个列表项外,其他每个列表项都有10像素的底部外边距。
例4
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
/* 只有当 <p> 元素正好是其父元素的第三个子元素时,才会被选中。第三个孩子不是p所以不生效 */
/* 如果是:nth-child(3) 那么第三个子元素会被选中 */
.container p:nth-child(3) {
background-color: yellow;
color: black;
}
/* 选择作为其父元素的第n个特定类型的子元素 */
.container p:nth-of-type(3) {
background-color: lightblue;
color: black;
}
</style>
<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>
选择器效果分析
.container p:nth-child(3)
- 选择器:
.container p:nth-child(3) - 适用元素: 无
- 效果: 该选择器试图选择作为其父元素(
.container)的第三个子元素的<p>标签。然而,在这个例子中,第三个子元素是<div>这是一个div</div>,而不是<p>标签,因此这个选择器不会生效。
.container p:nth-of-type(3)
- 选择器:
.container p:nth-of-type(3) - 适用元素:
<p>这是第三个段落</p> - 效果: 该选择器选择作为其父元素(
.container)的第三个<p>类型的子元素。在这个例子中,第三个<p>标签是<p>这是第三个段落</p>,因此这个选择器会生效,将背景颜色设置为浅蓝色,文字颜色设置为黑色。
最终结果
<p>这是第一个段落</p>
- 效果:没有特殊样式。
<div>这是一个div</div>
- 效果:没有特殊样式。
<p>这是第二个段落</p>
- 效果:没有特殊样式。
<p>这是第三个段落</p>
-
效果:
- 背景颜色:浅蓝色(由
.container p:nth-of-type(3)决定)。 - 文字颜色:黑色(由
.container p:nth-of-type(3)决定)。
- 背景颜色:浅蓝色(由
<div>这是第二个div</div>
- 效果:没有特殊样式。
总结
-
.container p:nth-child(3):- 适用元素: 无
- 效果: 由于第三个子元素不是
<p>标签,所以这个选择器不会生效。
-
.container p:nth-of-type(3):- 适用元素:
<p>这是第三个段落</p> - 效果: 背景颜色变为浅蓝色,文字颜色变为黑色。
- 适用元素:
进阶技巧
如果去掉 .container p:nth-of-type(3) 中的p他会选择作为其父元素(.container)的第三个所有类型的子元素。
效果如图
希望这篇介绍能帮助你更好地理解CSS的基础知识!如果你有任何问题或者想要了解更多细节,请随时留言交流。别忘了关注我获取更多技术分享哦~