3、CSS3核心基础:选择器进阶、盒模型详解、背景与边框、渐变与阴影、2D/3D变换
各位同学,欢迎来到第三章。说实话,CSS3 这部分内容,是我在项目里跟它打交道最多的。很多同学觉得 CSS 就是「调样式」,没什么技术含量。但你想想看,一个页面好不好看、交互流不流畅,全看 CSS 功底扎不扎实。今天咱们就把这些核心基础掰开揉碎了讲清楚。
3.1 选择器进阶:从入门到精准控场
基础的选择器大家都会用,但真正到了复杂页面,你会发现光靠 class 和 id 根本不够用。我个人的习惯是,能用结构选择器解决的问题,绝不多写一个 class。
3.1.1 属性选择器
属性选择器可以让你根据 HTML 属性的值来选中元素。这在处理表单、链接时特别有用。
/* 选中所有带有 target="_blank" 的链接 */
a[target="_blank"] {
color: #ff6b6b;
}
/* 选中所有 href 以 "https" 开头的链接 */
a[href^="https"] {
font-weight: bold;
}
/* 选中所有 class 包含 "icon" 的元素 */
[class*="icon"] {
margin-right: 4px;
}
[class*="btn-"] 来统一管理所有按钮变体,省去了大量重复的 class 命名。
3.1.2 结构伪类选择器
这类选择器可以根据元素在父容器中的位置来选中它。嗯,这里要注意,索引是从 1 开始的,不是 0。
/* 选中第一个子元素 */
li:first-child {
font-weight: bold;
}
/* 选中最后一个子元素 */
li:last-child {
border-bottom: none;
}
/* 选中第 3 个子元素 */
li:nth-child(3) {
background: #f0f0f0;
}
/* 选中偶数位置的子元素 */
li:nth-child(even) {
background: #fafafa;
}
:nth-child(2n+1) 做隔行变色,结果因为列表里混入了其他标签,导致样式错乱。后来我改用 :nth-of-type,它只匹配同类型的元素,更安全。
3.1.3 状态伪类选择器
表单元素的状态变化,用伪类来处理最优雅。
input:focus {
border-color: #4a90d9;
box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.2);
}
input:disabled {
background: #e9ecef;
cursor: not-allowed;
}
input:checked + label {
color: #28a745;
font-weight: bold;
}
3.2 盒模型详解:别让 padding 毁了你的布局
盒模型是 CSS 的基石。说白了,每个元素都是一个盒子,由 content、padding、border、margin 组成。但很多人栽就栽在 box-sizing 上。
3.2.1 标准盒模型 vs 怪异盒模型
| 属性 | 标准盒模型 (content-box) | 怪异盒模型 (border-box) |
|---|---|---|
| 宽度计算 | width = content | width = content + padding + border |
| 实际占用 | content + padding + border + margin | width + margin |
| 适用场景 | 传统布局 | 响应式布局、栅格系统 |
box-sizing: border-box;。这样你设置 width: 100% 时,padding 和 border 不会撑破容器。这个习惯帮我避免过无数次布局错乱。
/* 全局重置 */
*, *::before, *::after {
box-sizing: border-box;
}
3.2.2 margin 塌陷与合并
垂直方向上的 margin 会合并,取两者中的较大值。这个问题在父子元素之间尤其常见。
/* 父元素没有 padding 或 border 时,子元素的 margin-top 会穿透 */
.parent {
background: #f0f0f0;
/* 解决方案:加 overflow: hidden 或 padding-top: 1px */
overflow: hidden;
}
.child {
margin-top: 20px; /* 这个 margin 会跑到父元素外面去 */
}
3.3 背景与边框:让元素不再单调
背景和边框是页面视觉的基础。CSS3 给了我们很多新玩具,比如多重背景、圆角边框。
3.3.1 多重背景
一个元素可以叠加多个背景图片,用逗号分隔即可。
.hero {
background:
linear-gradient(135deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
url('bg-pattern.png'),
#1a1a2e;
background-size: cover, auto, auto;
background-position: center, top left, center;
}
3.3.2 边框圆角与图片边框
border-radius 可以单独设置每个角,border-image 则能让你用图片做边框。
.card {
border-radius: 12px 12px 0 0; /* 上圆下方 */
border: 10px solid transparent;
border-image: url('border-frame.png') 30 stretch;
}
border-radius: 50% 就行。
3.4 渐变与阴影:视觉层次感的灵魂
渐变和阴影是提升页面质感的两大利器。用好了,页面瞬间高级起来。
3.4.1 线性渐变与径向渐变
/* 线性渐变:默认从上到下 */
.btn-primary {
background: linear-gradient(to right, #667eea, #764ba2);
}
/* 径向渐变:从中心向外扩散 */
.spotlight {
background: radial-gradient(circle at center, #ffecd2, #fcb69f);
}
/* 重复渐变:做条纹背景 */
.stripes {
background: repeating-linear-gradient(
45deg,
#f0f0f0,
#f0f0f0 10px,
#e0e0e0 10px,
#e0e0e0 20px
);
}
3.4.2 盒阴影与文字阴影
阴影可以叠加多层,做出丰富的立体效果。
.card {
box-shadow:
0 4px 6px rgba(0,0,0,0.1), /* 主阴影 */
0 1px 3px rgba(0,0,0,0.06); /* 辅助阴影 */
}
.text-shadow {
text-shadow:
2px 2px 0 #333,
4px 4px 0 rgba(0,0,0,0.2);
}
3.5 2D/3D变换:让元素动起来
transform 是 CSS 动画的基础。2D 变换有平移、旋转、缩放、倾斜;3D 变换则能做出立体空间效果。
3.5.1 2D 变换
.hover-scale {
transition: transform 0.3s ease;
}
.hover-scale:hover {
transform: scale(1.1); /* 放大 1.1 倍 */
}
.rotate-icon {
transform: rotate(45deg); /* 旋转 45 度 */
}
.skew-card {
transform: skewX(-5deg); /* 水平倾斜 5 度 */
}
3.5.2 3D 变换
3D 变换需要设置透视点(perspective),否则看起来只是 2D 效果。
.scene {
perspective: 1000px; /* 设置透视距离 */
}
.card-3d {
transform: rotateY(45deg); /* 绕 Y 轴旋转 */
transform-style: preserve-3d; /* 保留 3D 空间 */
backface-visibility: hidden; /* 隐藏背面 */
}
/* 翻转卡片效果 */
.card-inner {
transition: transform 0.6s;
}
.card:hover .card-inner {
transform: rotateY(180deg);
}
translateZ(0) 来触发 GPU 加速,比如 transform: rotateY(45deg) translateZ(0);。
3.6 综合实战:一个卡片组件的完整实现
好了,理论讲完了。咱们来写一个真实的卡片组件,把今天学的都用上。
<div class="card">
<div class="card-image">
<img src="product.jpg" alt="产品图片">
<span class="badge">新品</span>
</div>
<div class="card-content">
<h3>智能手表 Pro</h3>
<p class="price">¥1299</p>
<button class="btn-buy">立即购买</button>
</div>
</div>
.card {
width: 300px;
border-radius: 16px;
overflow: hidden;
background: #fff;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}
.card-image {
position: relative;
overflow: hidden;
}
.card-image img {
width: 100%;
display: block;
transition: transform 0.5s ease;
}
.card:hover .card-image img {
transform: scale(1.1);
}
.badge {
position: absolute;
top: 12px;
left: 12px;
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: bold;
}
.card-content {
padding: 20px;
}
.price {
font-size: 24px;
font-weight: bold;
color: #e74c3c;
}
.btn-buy {
width: 100%;
padding: 12px;
border: none;
border-radius: 8px;
background: linear-gradient(to right, #667eea, #764ba2);
color: #fff;
font-size: 16px;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.btn-buy:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
.btn-buy:active {
transform: translateY(0);
}
好了,第三章的内容就到这里。下一章咱们要聊 Flexbox 和 Grid 布局,这两个是现代 CSS 布局的基石,准备好了吗?