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标签,例如
p、h1等。 - 类选择器:通过
.符号加上类名来选择所有带有指定类的元素,例如.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>
<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
<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>
<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>
<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>