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 的值如果超过元素尺寸的一半,会变成完全的圆形或椭圆形。做头像时,直接设 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);
}
避坑指南:我曾经为了追求炫酷效果,给一个弹窗加了 5 层阴影。结果在低端手机上,滚动时卡得不行。后来我总结:阴影层数控制在 2-3 层,性能最好。

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);
}
注意:3D 变换在移动端 Safari 上可能会有渲染问题。我建议在 transform 后面加上 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);
}
最后说一句:CSS3 的这些特性,单独看都不难。但组合起来,就能做出让人眼前一亮的效果。我建议你每学一个知识点,都去 CodePen 上试试手。看得再多,不如自己敲一遍。

好了,第三章的内容就到这里。下一章咱们要聊 Flexbox 和 Grid 布局,这两个是现代 CSS 布局的基石,准备好了吗?