参考文章: https://juejin.cn/post/6941206439624966152
前言
CSS
选择器
基础选择器
- 标签选择器:
h1
- 类选择器:
.checked
ID
选择器: #picker
- 通配选择器:
*
属性选择器
可以看看这篇文章: https://juejin.cn/post/6844903870171201549
[attr]
: 选择包含某个属性的所有元素,而不关心属性值
<input type="text" placeholder="Enter your name"> <input type="password"> <input>
<style> input[placeholder] { border: 2px solid blue; } </style>
|
[attr=val]
: 选择属性值完全等于指定值的所有元素
<input type="text" placeholder="Enter your name"> <input type="password"> <input type="email">
<style> input[type="password"] { background-color: lightgray; } </style>
|
[attr*=val]
: 选择属性值中包含指定值的所有元素
<a href="https://google.com">Google</a> <a href="https://github.com">GitHub</a> <a href="mailto:support@example.com">Email Support</a>
<style> a[href*="google"] { color: red; } </style>
|
[attr^=val]
: 选择属性值以指定字符串开头的所有元素
<a href="https://google.com">Google</a> <a href="https://github.com">GitHub</a> <a href="http://example.com">Example</a>
<style> a[href^="https"] { text-decoration: underline; } </style>
|
[attr$=val]
: 选择属性值以指定字符串结尾的所有元素
<a href="index.html">Home</a> <a href="about.html">About</a> <a href="style.css">Stylesheet</a>
<style> a[href$=".html"] { color: green; } </style>
|
组合选择器
- 相邻兄弟选择器:
A + B
, 选择A
元素后紧跟的第一个B
元素
<div class="box">Box 1</div> <div class="box">Box 2</div> <p class="text">Text 1</p> <p class="text">Text 2</p>
<style> .box + .text { color: red; } </style>
|
- 普通兄弟选择器:
A ~ B
, 选择A
元素后所有的B
元素
<div class="box">Box 1</div> <p class="text">Text 1</p> <p class="text">Text 2</p> <div class="box">Box 2</div> <p class="text">Text 3</p>
<style> .box ~ .text { color: blue; } </style>
|
<div class="container"> <div class="box">Box 1</div> <div class="inner"> <div class="box">Box 2</div> </div> </div>
<style> .container > .box { background-color: yellow; } </style>
|
- 后代选择器:
A B
: 选择A
元素内的所有B
元素, 不论层级深度
<div class="container"> <div class="box">Box 1</div> <div class="inner"> <div class="box">Box 2</div> </div> </div>
<style> .container .box { border: 1px solid black; } </style>
|
伪类
条件伪类
<p lang="en">Hello, world!</p> <p lang="fr">Bonjour, le monde!</p> <p lang="zh">你好,世界!</p>
<style> p:lang(en) { color: blue; } p:lang(zh) { color: red; } </style>
|
<p dir="ltr">Left to Right text.</p> <p dir="rtl">من اليمين إلى اليسار.</p>
<style> p:dir(ltr) { background-color: lightblue; } p:dir(rtl) { background-color: lightgreen; } </style>
|
<div> <p class="child">This is a child paragraph.</p> </div> <div> <span>No child paragraph here.</span> </div>
<style> div:has(.child) { border: 2px solid red; } </style>
|
<h1>Heading 1</h1> <h2>Heading 2</h2> <h3>Heading 3</h3>
<style> :is(h1, h2) { font-style: italic; } </style>
|
<div class="box">Box 1</div> <div class="container">Container</div> <div class="box">Box 2</div>
<style> div:not(.box) { background-color: lightgray; } </style>
|
行为伪类
:active
: 当用户点击并按住一个元素时,该伪类会生效。一般用于按钮或链接
<button>Click Me</button> <a href="#">Active Link</a>
<style> button:active { background-color: darkblue; color: white;} a:active { color: red; } </style>
|
:hover
: 当用户将鼠标指针悬停在一个元素上时,该伪类会生效
<div class="hover-box">Hover over me!</div> <a href="#">Hover Link</a>
<style> .hover-box:hover { background-color: lightgreen; cursor: pointer; } a:hover { text-decoration: underline; color: orange; } </style>
|
::selection
: 当用户选中文本时,该伪类会生效。可以用于自定义文本选择时的样式(如背景颜色、文字颜色)
<p> This is a paragraph of text. Select some text to see the effect. </p>
<style> ::selection { background-color: yellow; color: black; } </style>
|
状态伪类
:target
: 匹配当前URL
锚点(#
)对应的元素
<a href="#section1">Go to Section 1</a> <a href="#section2">Go to Section 2</a>
<div id="section1">Section 1</div> <div id="section2">Section 2</div>
<style> #section1:target { background-color: lightblue; } #section2:target { background-color: lightgreen; } </style>
|
:link
: 选择未访问的链接:visited
: 选择已访问的链接
<a href="https://example.com">Unvisited Link</a> <a href="https://google.com">Visited Link</a>
<style> a:link { color: blue; } a:visited { color: purple; } </style>
|
<input type="text" placeholder="Enter your name">
<style> input:focus { border: 2px solid green; outline: none; } </style>
|
:required
: 匹配表单中被标记为必填的元素:optional
: 匹配表单中未标记为必填的元素
<form> <input type="text" required placeholder="Required Field"> <input type="text" placeholder="Optional Field"> </form>
<style> input:required { border: 2px solid red; } input:optional { border: 2px solid gray; } </style>
|
:valid
: 匹配输入值合法的表单元素:invalid
: 匹配输入值不合法的表单元素
<form> <input type="email" placeholder="Enter your email"> </form>
<style> input:valid { border: 2px solid green; } input:invalid { border: 2px solid red; } </style>
|
:in-range
: 匹配输入值在设定范围内的元素:out-of-range
: 匹配输入值在设定范围外的元素
<form> <input type="number" min="10" max="100" placeholder="Enter a number"> </form>
<style> input:in-range { background-color: lightgreen; } input:out-of-range { background-color: lightcoral; } </style>
|
<form> <label><input type="checkbox" checked> Checked</label> <label><input type="checkbox"> Not Checked</label> </form>
<style> input:checked { outline: 2px solid blue; } </style>
|
:enabled
: 匹配启用的表单元素:disabled
: 匹配禁用的表单元素
<input type="text" disabled placeholder="Disabled"> <input type="text" placeholder="Enabled">
<style> input:enabled { background-color: white; } input:disabled { background-color: lightgray; } </style>
|
:read-only
: 匹配只读表单元素:read-write
: 匹配可编辑表单元素
<input type="text" readonly value="Read-only Field"> <input type="text" value="Editable Field">
<style> input:read-only { color: gray; } input:read-write { color: black; } </style>
|
<form> <input type="text" placeholder="Leave me blank"> </form>
<style> input:blank { border: 2px dashed orange; } </style>
|
结构伪类
:root
: 选择文档的根元素, 在HTML
中一般是<html>
标签
<html> <head></head> <body> <p>Hello, World!</p> </body> </html>
<style> :root { font-size: 16px; --main-color: blue; } </style>
|
:empty
: 匹配没有子元素(包括文本节点)的元素
<div class="box1"></div> <div class="box2">Content</div>
<style> div:empty { background-color: lightgray; } </style>
|
:first-letter
: 选择元素的首字母,用于文本样式的特殊处理
<p>This is a paragraph.</p>
<style> p:first-letter { font-size: 2em; color: red; } </style>
|
:first-line
: 选择元素的首行内容,常用于段落样式的特殊处理
<p>This is a long paragraph to demonstrate first-line styling in CSS.</p>
<style> p:first-line { font-weight: bold; color: blue; } </style>
|
:nth-child(n)
: 匹配父元素中第n
个子元素(从第一个开始计数)
<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul>
<style> li:nth-child(2) { color: red; } </style>
|
:nth-last-child(n)
: 匹配父元素中倒数第n
个子元素
<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul>
<style> li:nth-last-child(1) { color: green; } </style>
|
:first-child
: 匹配父元素中的第一个子元素
<ul> <li>Item 1</li> <li>Item 2</li> </ul>
<style> li:first-child { font-style: italic; } </style>
|
:last-child
: 匹配父元素中的最后一个子元素
<ul> <li>Item 1</li> <li>Item 2</li> </ul>
<style> li:last-child { font-weight: bold; } </style>
|
:only-child
: 匹配父元素中仅有的子元素
<div> <p class="single">I am the only child!</p> </div> <div> <p>Child 1</p> <p>Child 2</p> </div>
<style> p:only-child { color: purple; } </style>
|
:nth-of-type(n)
: 匹配同类型标签中的第n
个
<div> <p>Paragraph 1</p> <p>Paragraph 2</p> <span>Span 1</span> <p>Paragraph 3</p> </div>
<style> p:nth-of-type(2) { color: orange; } </style>
|
:nth-last-of-type(n)
: 匹配同类型标签中的倒数第n
个
<div> <p>Paragraph 1</p> <p>Paragraph 2</p> <p>Paragraph 3</p> </div>
<style> p:nth-last-of-type(1) { color: brown; } </style>
|
:first-of-type
: 匹配同类型标签中的第一个
<div> <p>First Paragraph</p> <p>Second Paragraph</p> </div>
<style> p:first-of-type { text-decoration: underline; } </style>
|
:last-of-type
: 匹配同类型标签中的最后一个
<div> <p>First Paragraph</p> <p>Last Paragraph</p> </div>
<style> p:last-of-type { color: teal; } </style>
|
:only-of-type
: 匹配父元素中仅有的某种类型的标签
<div> <p>Unique Paragraph</p> </div> <div> <span>Not Unique</span> <p>Another Paragraph</p> </div>
<style> p:only-of-type { background-color: yellow; } </style>
|
伪元素
::before
: 在在元素内容之前插入内容::before
是一个伪元素,必须与content
属性一起使用,否则不会生效
<p class="example">This is a paragraph.</p>
<style> .example::before { content: "★ "; color: gold; font-size: 1.5em; } </style>
|
::after
: 在元素内容之后插入内容- 和
::before
类似,必须与content
属性一起使用
<p class="example">This is a paragraph.</p>
<style> .example::after { content: " ✎"; color: gray; font-size: 1.2em; } </style>
|
CSS
优先级
优先级就是分配给指定的CSS
声明的一个权重, 它由匹配的选择器中的每一种选择器类型的数值决定。可以把权重分成如下几个等级, 数值越大的权重越高
10000
: !important
01000
: 内联样式 (inline style
)00100
: ID
选择器00010
: 类选择器、伪类选择器、属性选择器00001
: 元素选择器、伪元素选择器00000
: 通配选择器、后代选择器、兄弟选择器
可以看到内联样式(通过元素中style
属性定义的样式)的优先级大于任何选择器。而给属性值加上!important
又可以把优先级提至最高,就是因为它的优先级最高,所以需要谨慎使用它
CSS
层叠性
层叠样式表(CSS
)中的“层叠”是其核心特性之一,它指的是当多个CSS
声明可以作用于同一个HTML
元素时,如何确定最终生效的样式。这是通过一套明确的算法来完成的,用于合并来自多个来源的属性值
- 针对不同源的样式,将按照如下的顺序进行层叠,越往下优先级越高
- 用户代理样式表: 浏览器自带的默认样式,如果我们不设置任何样式,浏览器会使用这些规则。例如,默认的段落
<p>
有一些上下边距 - 作者样式表: 开发者定义的样式,通常是我们编写的
CSS
文件或内联样式。这些样式会覆盖浏览器的默认样式 - 作者样式表中的
!important
声明: 如果开发者在样式中添加了!important
,那么它的优先级最高,哪怕有其他规则覆盖,它也会生效
理解层叠性的时候需要结合CSS
选择器的优先级以及继承性来理解。比如针对同一个选择器,定义在后面的声明会覆盖前面的, 作者定义的样式会比默认继承的样式优先级更高
@
规则
@
规则是一种特殊的CSS
语句,用于在样式表中定义一些全局配置或条件规则,而不仅仅是常规的样式规则。以下是CSS
中常用的@
规则
@namespace
: 用于定义XML
命名空间(适用于特定的XML
文件样式需求)
@namespace svg "http://www.w3.org/2000/svg";
svg|circle { fill: red; }
|
@media (max-width: 600px) { body { background-color: lightblue; } }
@media print { body { font-size: 12px; color: black; } }
|
@page { margin: 1in; }
@page :first { margin-top: 2in; }
|
@font-face { font-family: "CustomFont"; src: url("customfont.woff2") format("woff2"); }
body { font-family: "CustomFont", sans-serif; }
|
@keyframes slide-in { from { transform: translateX(-100%); } to { transform: translateX(0); } }
div { animation: slide-in 1s ease-out; }
|
@import
: 用于导入外部CSS
文件, 与<link>
的区别如下<link>
是HTML
标签,可导入CSS
、图片、脚本等资源。@import
是CSS
规则,仅能导入CSS
文件<link>
会在页面加载时同时加载CSS
。@import
会等页面加载完成后再加载CSS
(所以@import
字体会在网页加载结束后才会被应用)
@import url("styles.css");
|
@supports
: 用于检测浏览器是否支持某些CSS
特性,从而有条件地应用样式。可以使用not
、and
、or
逻辑操作符
body { background-color: white; color: black; transition: all 0.3s ease; }
@supports (color-scheme: dark) { body { color-scheme: dark; background-color: var(--background, black); color: var(--text, white); } }
@supports (prefers-reduced-motion: reduce) { * { transition: none; animation: none; } }
|
CSS
继承性
继承性是CSS
中的一个重要特性,指的是子元素可以继承父元素某些 属性计算后的值。例如,html
元素的文本颜色默认是黑色,页面中的所有子元素会继承这个颜色属性,除非显式指定其他颜色。
body { color: orange; }
h1 { color: inherit; }
|
继承的作用
- 继承性可以减少样式代码的冗余,提高代码的可维护性
- 如果
CSS
不支持继承,那么我们需要为每个文本标签都单独设置颜色或字体,导致样式代码冗长,文件体积变大,维护成本增加
继承的默认行为
CSS
属性很多,但并不是所有的属性默认都是能继承父元素对应属性的,那哪些属性存在默认继承的行为呢?一定是那些不会影响到页面布局的属性,可以分为如下几类
- 字体相关:
font-family
、font-style
、font-size
、font-weight
等 - 文本相关:
text-align
、text-indent
、text-decoration
、text-shadow
、letter-spacing
、word-spacing
、white-space
、line-height
、color
等 - 列表相关:
list-style
、list-style-image
、list-style-type
、list-style-position
等 - 其他属性:
visibility
、cursor
等
显式控制继承行为
对于其他默认不继承的属性也可以通过以下几个属性值来控制继承行为
unset
- 如果属性默认可以继承,则效果等同于
inherit
- 如果属性默认不继承,则效果等同于
initial
CSS
文档流
在CSS
的世界中,文档流是内容按照从左到右、从上到下的顺序排列和显示的一种默认布局方式。通常情况下,页面会被分割成一行一行的显示,每行可能包含多个元素。从视觉效果来看,文档流呈现为从上到下、从左到右的排列方式。这种布局也被称为流式布局,类似水流般灵活,可以自适应所在的容器
什么是文档流
- 在没有额外样式(如
position
或float
)的情况下,HTML
元素会按照文档流的默认规则进行排列 - 块级元素: 占据一整行,从上到下垂直排列,例如
<div>
、<p>
等 - 行内元素: 按从左到右的顺序水平排列,例如
<span>
、<a>
、<strong>
等
<div>块级元素 1</div> <div>块级元素 2</div> <span>行内元素 1</span> <span>行内元素 2</span>
|
块级元素 1 块级元素 2 行内元素 1 行内元素 2
|
脱离文档流
脱离文档流指的是将某个元素从正常文档流中移除后,其他元素将忽略该元素的存在,并填补其原先占据的空间。脱流的元素不会影响父容器的高度计算,即脱流元素不占据空间
浮动float
浮动(float
)属性最初在CSS
中被引入是为了实现文字环绕图片的效果
如果没有float
,img
默认是inline
元素,那么文字图片的显示就会像这样
- 使用
float
会让元素脱离正常文档流,移动到父容器的左/右侧 - 后续的块级元素不会受到浮动元素的影响,但其他浮动或行内元素会受影响
<div style="float: left;">浮动元素</div> <div>普通元素</div>
|
现代的CSS
布局技术如Flexbox
和Grid
已经几乎完全取代了浮动布局,但在某些特定情况下,浮动仍然有其用武之地,比如文字环绕图片和简单的左对齐或右对齐
定位position
绝对定位 (absolute
)
- 使用
position: absolute;
脱离文档流 - 元素的位置由最近的非静态父容器决定,空出的位置会被后续节点填补
固定定位 (fixed
)
- 使用
position: fixed;
脱离文档流 - 元素的位置固定在视口的某处,不受滚动影响
<div style="position: absolute; top: 50px; left: 100px;">绝对定位元素</div> <p>这是一段普通文本,将填补绝对定位元素的位置。</p>
|
附录
文件还未上传 Github