☰
CSS核心知识一次打通:从选择器、盒模型到居中与动画实战
2026/9/26 5:20:00 网站建设 项目流程

开头

如果你刚把HTML的基本结构过完,大概率会对着浏览器里那个白底黑字的页面发愣:标签、标题、列表都在,但怎么看都像2005年的内部系统。这就是HTML的极限——它只负责告诉浏览器"这里有什么",至于这些内容长什么样、排在哪、怎么动,全都得交给CSS。

CSS要做的就是三件事:把元素摆到该在的位置,把样式改到该有的样子,把交互响应做到该有的手感。HTML负责结构,CSS负责表现,JS负责行为,这三样东西就是网页开发的铁三角。这一篇我们集中把CSS打透,从选择器、盒模型、布局到动画和真实场景,尽量一篇让你以后看到页面效果能反推出写法,而不是到处复制代码拼拼凑凑。

这篇内容适合两类人:一类是学过一点HTML但CSS一直靠猜的初学者,另一类是能写样式但总在居中、优先级、动画这类细节上反复踩坑的前端爱好者。我会直接从实际开发中的高频场景切入,尽量讲清楚每个属性背后的逻辑,而不是堆语法。

1. 先搞懂CSS在网页三件套里的位置:它到底管什么

1.1 为什么有了HTML还不够

很多人觉得奇怪:我用HTML已经写出了"标题、段落、图片、列表",页面信息都在了,CSS不就是换个颜色、改个大小吗?表面看确实如此,但等你把页面做得复杂一点就会发现,CSS管的事情包括间距、对齐、层级、动效、响应式适配,任何一个环节出问题,页面都谈不上可用。

举个例子。同样一句"限时优惠,全场八折",没有CSS时它就是一个孤零零的黑色文字。加上这段样式:

.tip { color: #e67e22; font-size: 18px; font-weight: 600; padding: 12px 20px; background: #fff7ed; border-left: 4px solid #e67e22; }

它就从一个普通文本变成了一个带底色、左边有强调条、字号突出的促销提示条。内容没变,但视觉层次和信息强调完全不同。这就是CSS的定位:在不改变HTML结构的前提下,重新布置内容的呈现方式。

实际开发里,三者的分工可以这样理解:HTML是毛坯房的墙体结构,CSS是水电泥瓦和软装,JS是智能家居系统。毛坯房能住,但没人愿意直接住毛坯房;有了CSS,房子才符合居住审美的需求;有了JS,灯才自动亮、门才自动开。

1.2 CSS写在哪里:三种方式怎么选

CSS常见的写法有三种:

  • 行内样式:直接写在标签的style属性里,比如<p style="color:red">。优先级最高,后期难维护,只适合临时调试。
  • 内嵌样式:写在HTML的<style>标签里,适合单页demo或邮件模板。
  • 外部样式表:用<link rel="stylesheet" href="style.css">引入,是正经项目里的主流方式。

外部样式最大的好处是缓存和复用。多页面网站只需要一份CSS文件,浏览器加载一次之后其他页面直接读取缓存,不用重复下载。而且改样式不需要翻找HTML,一个文件统一管理。

这里有一个新手常犯的错:在<link>标签里漏写rel="stylesheet",结果就是CSS文件根本没生效,页面光秃秃的。这个属性告诉浏览器"我引入的是一个样式表",不是普通文件。凡是引入CSS不生效的,第一反应不是看选择器写没写对,而是先检查link标签写没写全。

<!doctype html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>商品详情</title> <link rel="stylesheet" href="css/style.css"> </head>

顺带说一句,lang="zh-cn"放在<html>上,中文网页最好是写上的,它对无障碍阅读和浏览器翻译都有帮助。有些模板把这个属性漏掉,实际没多大事,但规范起见最好有。

1.3 浏览器渲染页面的基本流程

理解CSS的加载顺序,对排查"样式为什么没出来"这类问题很关键。浏览器拿到HTML之后,大致按这个顺序工作:

  1. 解析HTML,构建出DOM树,也就是所有元素组成的结构图。
  2. 解析CSS,构建CSSOM,也就是样式规则组成的对象模型。
  3. DOM树和CSSOM合并成渲染树,这一步会把"哪些元素可见、用什么样式显示"确定下来。
  4. 浏览器根据渲染树计算每个元素的位置和尺寸,这叫布局。
  5. 最后一步是绘制,浏览器把像素真正画到屏幕上。

如果你把CSS文件放在HTML末尾的</body>之前,那么在HTML解析完之前CSS还没拿到,首屏会出现短暂的无样式闪烁,就好像页面闪了一下。把<link>放在<head>里,浏览器在渲染之前就能拿到样式,页面第一次出现就是完整的样子。这也是"CSS放头部,JS放底部"这条老规矩的来源。

2. 选择器和优先级:能准确选中元素,才谈得上控制样式

2.1 高频选择器:从类、ID到伪类和伪元素

CSS的第一道门槛不是属性记不住,而是写出来的选择器选不中目标元素。我把日常开发里真正常用的选择器分类整理出来,大家按这个清单去熟悉就够用。

标签选择器:div、p、a这类,选中页面上所有同名标签。适合设置全局的基础样式,比如给所有段落设置行高和字号:

p { line-height: 1.8; font-size: 14px; }

类选择器:.nav-link,选中带有class="nav-link"的元素。这是最推荐的一种,类名可以复用、覆盖、组合,不依赖具体标签名,灵活且易读。实际项目里几乎所有功能性样式都用类选择器。

ID选择器:#header,选中id="header"的唯一个元素。ID是唯一的,所以它只能作用于一个元素。因为ID优先级太高,使用范围受限,一般只用于页面上绝对唯一的区域,比如顶部导航、侧边栏、页面主容器。复用性差,也不利于覆盖,能不用就尽量不用。

属性选择器:[type="text"]、[href^="https"]这类,按照属性名或属性值来匹配。比如[disabled]可以选中所有带disabled属性的按钮。表单前端处理时很常用。

伪类选择器::hover、:focus、:first-child、:nth-child(2)。伪类选中的是"某种状态或位置下的元素"。比如:first-child表示父元素下的第一个子元素,:nth-child(odd)表示奇数位的子元素,做表格隔行变色特别方便。

伪元素选择器:::before、::after。它们在目标元素的内容前面或后面生成一个额外的"虚拟元素"。这个特性常用于做角标、装饰横线、气泡箭头,不需要额外写HTML标签。

举一个实际例子。导航菜单里要给当前页面的链接一个高亮,最常见的做法是同时使用类和伪类的组合:

<nav class="main-nav"> <a href="#" class="nav-link active">首页</a> <a href="#" class="nav-link">课程</a> <a href="#" class="nav-link">社区</a> </nav>
.main-nav .nav-link { display: inline-block; padding: 10px 16px; color: #333; text-decoration: none; } .main-nav .nav-link:hover { color: #409eff; } .main-nav .nav-link.active { color: #fff; background: #409eff; border-radius: 6px; }

.main-nav .nav-link.active这种写法读起来就是"main-nav里的、同时拥有nav-link和active两个类名的链接"。以后页面切换高亮位置,只需要在HTML里移动active类,样式不用改。

2.2 优先级计算:别再"为什么我的样式没生效"

样式不生效是最常见的CSS问题,其中大部分原因都和优先级有关。CSS里每条规则都可以按四个维度打分,哪一条分高,就用哪一条:

类型分值
内联样式(style="...")1000
ID选择器0100
类、属性、伪类选择器0010
标签、伪元素选择器0001

比较规则从左往右看,先比千位,再比百位,然后是十位、个位。比如#header .nav-link分值是110,而.nav-link:hover分值是20,前者一定赢。

举个例子。我之前帮一个同事排查问题,他写了这么一段:

.info { color: #333; } #intro { color: red; }

页面上一个<p id="intro" class="info">,最后文字是红色的。因为ID选择器在优先级上百位上有分,类选择器只有十位,ID获胜了。这个现象在初学者看来就是"为什么我后面写的样式不生效?"——不是书写顺序的问题,而是选择器本身的等级不一样。

所以当你发现样式被覆盖,不要去暗骂浏览器,先打开控制台,看Elements面板里Styles那一栏,浏览器会自动列出当前元素匹配的所有规则,并把被覆盖的属性画上删除线,一眼就能看出是哪个更高等级的选择器在起作用。这个排查习惯,比任何技巧都重要。

还有一个"终极武器"!important,写在属性值后面能强制提升优先级,它比所有选择器都高,但建议非特殊情况不用。一旦项目里大量出现!important,说明选择器的层次已经乱了,后面改起来会非常痛苦。我见过有的项目一行样式里三个!important,那基本就是给自己挖坑。

2.3 继承和层叠:控制样式扩散的边界

CSS还有一个特点是继承。某些属性会自动从父元素传给子元素,最典型的是color、font-family、line-height、text-align。这意味着你给body设置了一个字体,整个页面所有文字默认都会使用它,不用每个段落单独写。

但要注意,并不是所有属性都继承。margin、padding、border、background、width、height这些和布局、尺寸相关的属性都不会继承。如果想让明确不继承的属性强制继承,可以写成margin: inherit,但实际开发中很少这么用,多数时候是在纠结要不要统一某个基础值时才想到。

当你需要重置某条继承下来的属性,有三个关键字很实用,分别是inherit、initial、unset:

  • inherit:强制继承父元素的计算值。
  • initial:恢复成属性的初始默认值。
  • unset:如果属性是可继承的,表现同inherit,否则表现同initial。

做表单重置时,button和input默认不继承font-family,会出现按钮字体和页面字体不一致的情况。这时候给它们加上:

button, input { font-family: inherit; }

按钮就和其他文本长得一样了。这种细节在实际项目里经常遇到,值得养成习惯。

3. 盒模型和"居中":CSS新手最容易卡住的两个点

3.1 标准盒模型和border-box:宽度到底怎么算

每个HTML元素本质上都是一个矩形盒子,盒子里面的结构从内到外是:内容content、内边距padding、边框border、外边距margin。这就是盒模型。

默认情况下,width和height指定的是内容区的尺寸,padding和border是额外增加的。也就是说,一个宽度设为300px、左右padding各20px、border 1px的元素,实际占用的水平宽度是342px。这在做自适应布局时会给你添堵:设计稿里明明算好了300px,结果写进去一量,撑破了。

解决办法是全局开启box-sizing: border-box:

*, *::before, *::after { box-sizing: border-box; }

改成border-box之后,width和height直接包含padding和border,元素总宽度等于你设置的width,不用再手动做减法。现在几乎所有前端框架和重置样式都会默认做这件事,建议你也从一开始就加上。

这里给一个对比表,帮助你记住区别:

盒子类型width 含义元素实际宽度
content-box只有内容区width + padding + border
border-box含内容+内边距+边框width

顺便说说margin。margin影响元素之间的距离,但它不会参与元素自身的宽度计算。两个垂直排列的兄弟元素,如果上面元素margin-bottom是20px,下面元素margin-top是30px,它们之间的实际距离是30px,不是50px。这个"外边距重叠"现象也是初学者容易懵的地方,不过了解即可,遇到时知道不是Bug就行。

3.2 水平居中与垂直居中的完整方案

"把元素居中"是CSS被问得最多的问题之一,热搜里也高频出现"css body居中""怎么调整css容器里的文本位置"。究其原因,是居中分不同场景,每种场景有不同写法,混在一起就容易乱。我按使用频率整理出一套方案。

水平居中,分两种情况:

  • 文本或行内元素(比如inline、inline-block),给父容器加text-align: center即可。
  • 块级元素有固定宽度,给自身加margin-left: auto; margin-right: auto。

垂直居中,常见三种做法:

第一种,单行文本可以用line-height等于容器高度来实现,比如高50px的容器,文字line-height: 50px就会居中。这个方法简单,但只适合确定高度的单行文本。

第二种,Flex布局是现在最推荐的做法。在父元素上写:

.container { display: flex; align-items: center; /* 垂直居中 */ justify-content: center; /* 水平居中 */ }

flex生效后,子元素的两轴都是居中的,这是目前最通用、最稳的组合。无论子元素高矮、大小,甚至在内容数量不固定的情况下都适用。

第三种,Grid布局也可以,写法更短:

body { display: grid; place-items: center; min-height: 100vh; }

place-items: center同时处理主轴和交叉轴居中。min-height: 100vh保证占满整个视口高度,这样配合body,页面里的主容器就能在屏幕正中间。热搜里的"css body居中"就是这么实现的。

我建议你把flex写法背熟,因为后面做卡片、导航、页脚几乎天天用。adjusted文本位置时,先分清是想在"水平方向"还是"垂直方向"上调整,再去对应属性,基本不会乱。

3.3 一个综合小案例:登录卡片居中

把上面的知识串一下。做一个居中显示的登录卡片,左边文案右边输入框。HTML大致是这样:

<div class="login-wrap"> <div class="login-card"> <h2>欢迎回来</h2> <input type="text" placeholder="账号"> <input type="password" placeholder="密码"> <button class="login-btn">登录</button> </div> </div>

CSS里用flex让整个卡片居中,卡片内部也按纵向排列:

.login-wrap { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: #f0f2f5; } .login-card { width: 360px; padding: 40px; background: #fff; border-radius: 12px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); }

这段代码已经可以覆盖绝大多数"居中"场景了。如果你觉得一个项目里总是在做同样的事情,可以考虑抽出一个utility类,比如.center、.flex-center,需要时直接套用。

4. 从静态到动态:伪类、过渡和动画

4.1 hover和transition:让按钮像按钮

纯CSS也可以做交互,核心是伪类和过渡动画。最简单也最常用的是:hover配合transition,让鼠标移入时样式不是瞬变,而是平滑过渡。

先看一个错误示范,很多新手会这样写:

.button { background: #409eff; } .button:hover { background: #ff4757; transition: background 0.3s; }

这样写的问题在于,transition放在了:hover里面,鼠标移入时它才生效,移出时直接弹回原色。正确的做法是把transition放在元素的基础状态上:

.button { background: #409eff; transition: background 0.3s ease, transform 0.3s ease; } .button:hover { background: #ff4757; transform: translateY(-2px); }

这样移入移出都有0.3秒的渐变。transition的四个值分别是属性名、时长、缓动函数、延迟,平时记住transition: all 0.3s ease就能应付多数场景,不过项目体量大了建议只写需要过渡的属性,避免all把不必要的样式也带上动画。

伪类实际不止:hover。:focus在输入框获得焦点时触发,:active在鼠标按下的瞬间触发,:focus-within在自身或后代元素获得焦点时触发。做一个带边框的搜索框,常规写法是把:focus的边框颜色变更亮,配合outline: none去掉系统默认的蓝色外框,表单观感会好很多。热搜里"css 鼠标移入事件"说的就是这组东西的运用。

4.2 删除线、字体渐变和关键文字样式

文字样式里,有两个属性经常被搜到:删除线text-decoration: line-through和字体渐变。

删除线最常见的应用是商品原价。比如"原价399,现价299",原价通常用灰色加删除线,现价用红色加粗,一眼就能看出性价比:

.price .old { color: #999; text-decoration: line-through; font-size: 14px; } .price .new { color: #ff4757; font-size: 22px; font-weight: 700; }

text-decoration除了line-through,还有underline、overline、none。较新的CSS还支持text-decoration-thickness和text-decoration-color,可以单独控制删除线的粗细和颜色。想让删除线淡一点,颜色比正文浅一个色号即可,不然会显得脏。

字体渐变是一个很能提升视觉档次的玩法。比如标题文字从左到右由橙变红:

.gradient-text { background: linear-gradient(90deg, #ff512f, #dd2476); -webkit-background-clip: text; background-clip: text; color: transparent; }

原理是:先把渐变背景铺在文字区域,再用background-clip: text把背景裁剪到文字的形状上,最后把字体颜色设为透明,露出底下的渐变背景。这个效果在大多数现代浏览器都能正常显示,但建议保留一个color作为不支持时的兜底,比如:

.gradient-text { color: #e60012; /* 不支持渐变裁剪时至少还有颜色 */ background: linear-gradient(90deg, #ff512f, #dd2476); -webkit-background-clip: text; background-clip: text; color: transparent; }

留意顺序:color: #e60012写在前面做兜底,后面的color: transparent在支持裁剪的浏览器中会覆盖它。这样既保留视觉效果,也不至于在老旧浏览器里文字看不见。

4.3 transform变形:梯形、旋转和缩放

CSS里做形状变形用的核心属性是transform。热搜里出现过"css 变形 梯形",梯形在网页设计里经常被用作标签页的底部或斜向导航的背景。

实现梯形有两种常用思路。第一种是clip-path裁剪,这也是我更推荐的方式,因为它不改变元素自身的布局盒子,而且形状直观:

.trapezoid { width: 160px; height: 60px; background: #409eff; clip-path: polygon(0 0, 100% 0, 86% 100%, 14% 100%); }

polygon接受一组顶点的坐标,四个点依次表示左上、右上、右下、左下,分别用百分比定位。把底部两个点向内收一点,一个梯形就出来了。想改斜度,调百分比就行。

第二种是用transform: perspective()配合rotateX(),让元素在3D视角下倾斜,看起来像梯形。这种办法适合做卡片轻微倾斜的质感,但会牵涉到透视原点、子元素变形等一系列问题,新手不推荐。

transform的其他常用值也值得一次性掌握:

  • translateX(20px):水平向右移动20px。
  • scale(1.1):放大1.1倍。
  • rotate(45deg):旋转45度。
  • rotateX(30deg):沿X轴三维旋转。

其中"图片hover放大"是特别常见的效果。把图片包在一个有overflow: hidden的容器里,图片基础状态加上transition: transform 0.4s ease,hover时让图片放大到1.05,边缘刚好被容器裁切,不会溢出撑破布局。

4.4 动画:涟漪光圈扩散和动态相册

CSS动画真正厉害的地方,是能做出让人以为背后有JS的效果。涟漪光圈扩散就是一个典型例子,常出现在直播按钮、播放按钮或主页头像外围。

核心思路是用box-shadow向外扩散并逐渐变透明:

.ripple-btn { width: 80px; height: 80px; border-radius: 50%; background: #ff4757; color: #fff; border: none; animation: ripple 1.8s infinite; } @keyframes ripple { 0% { box-shadow: 0 0 0 0 rgba(255, 71, 87, 0.5); } 100% { box-shadow: 0 0 0 24px rgba(255, 71, 87, 0); } }

动画尺寸(24px)就是光圈向外扩散的最远半径,透明度结尾要归零,光圈才会"淡出",形成一波波扩散的感觉。想做出多层光圈,可以在按钮上叠加::after伪元素,让它也跑一套同样的动画,然后设置animation-delay: 0.9s错开半拍。视觉上就是两层涟漪轮流扩散,很接近直播间的效果。

再来看"css动态相册纯代码"。纯CSS实现图片轮播,最简单的方案是把不同图片放到同一个位置,用opacity做交叉淡入淡出。比如三张图,每4秒切换一张:

.slideshow { position: relative; width: 600px; height: 400px; overflow: hidden; } .slideshow img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; animation: fade 12s infinite; } .slideshow img:nth-child(1) { animation-delay: 0s; } .slideshow img:nth-child(2) { animation-delay: 4s; } .slideshow img:nth-child(3) { animation-delay: 8s; } @keyframes fade { 0%, 30% { opacity: 1; } 33%, 95% { opacity: 0; } 100% { opacity: 0; } }

逻辑是这样的:三张图叠在同一个位置,每张图的动画总时长12秒,前4秒显示自己,后8秒隐藏,用animation-delay错开每个人的出场时间。相比之下,用background-image切换图片虽然简单,但背景图无法平滑过渡,观感会突跳;opacity方案更柔和。

动画这块有一个通用提醒:涉及位置、尺寸的动画(比如改left、width)会反复触发浏览器布局和绘制,性能开销比只用transform和opacity高。能用transform实现的效果就不要用left去推。这也是为什么几乎所有高性能动画demo都会用transform: translateX()而不是margin-left。

5. 组合实战:写一个商品详情页的卡片

5.1 需求拆解:商品卡片包含哪些信息

前面讲的都是零散知识点,最后把它们组装到一个真实场景里,看看到底怎么用。这里就选一个热搜里出现过的词:"css商品详情"。我们做一个电商App里非常常见的商品卡片,要求包含这些信息:

  • 商品图片,鼠标移入时轻微放大。
  • 左上角一个"热卖"角标。
  • 标题、简短描述。
  • 原价+现价,原价带删除线,现价高亮。
  • 一个渐变的"立即购买"按钮,hover时有反馈。

页面本身不涉及后端逻辑,只需要HTML结构和CSS样式,属于纯前端静态效果。难点在于怎么用最少的代码做出层次感,并且为后续接JS留好感。

5.2 HTML结构和CSS样式完整实现

HTML先搭出来:

<div class="product-card"> <div class="cover"> <img src="https://example.com/headphone.jpg" alt="蓝牙降噪耳机"> <span class="badge">热卖</span> </div> <div class="info"> <h3 class="name">蓝牙降噪耳机</h3> <p class="desc">主动降噪,30小时续航</p> <div class="price"> <span class="old">¥399</span> <span class="new">¥299</span> </div> <a href="javascript:;" class="buy-btn">立即购买</a> </div> </div>

然后是整套CSS。注意几个地方:

  1. 图片hover放大用transform,容器加overflow hidden裁边。
  2. 角标badge用绝对定位固定在左上角。
  3. 原价和现价分别应用删除线和强调色。
  4. 按钮用渐变+阴影,hover时上浮一点。
body { margin: 0; min-height: 100vh; display: grid; place-items: center; background: #f6f7f9; font-family: "PingFang SC", "Microsoft YaHei", sans-serif; } .product-card { width: 320px; border-radius: 16px; background: #fff; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08); overflow: hidden; transition: box-shadow 0.3s ease; } .product-card:hover { box-shadow: 0 16px 40px rgba(0, 0, 0, 0.14); } .cover { position: relative; height: 220px; overflow: hidden; } .cover img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; } .cover:hover img { transform: scale(1.05); } .badge { position: absolute; top: 12px; left: 12px; padding: 4px 12px; font-size: 12px; color: #fff; background: linear-gradient(90deg, #ff512f, #dd2476); border-radius: 6px; } .info { padding: 16px 20px 20px; } .name { margin: 0 0 8px; font-size: 18px; font-weight: 600; color: #222; } .desc { margin: 0 0 12px; font-size: 13px; color: #888; } .price { display: flex; align-items: baseline; gap: 8px; margin-bottom: 16px; } .price .old { color: #aaa; text-decoration: line-through; font-size: 13px; } .price .new { color: #ff4757; font-size: 22px; font-weight: 700; } .buy-btn { display: block; text-align: center; padding: 10px 0; background: linear-gradient(90deg, #ff512f, #dd2476); color: #fff; border-radius: 8px; font-size: 15px; text-decoration: none; transition: transform 0.3s ease, box-shadow 0.3s ease; } .buy-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(221, 36, 118, 0.3); }

这里面有几个细节很值得说。

.cover:hover img的意思是"鼠标悬停在图片容器上时,修改里面的图片",这样无论鼠标悬停在图片哪个位置,都能触发放大效果。object-fit: cover用来保证图片按比例裁剪填满容器,不然电商图比例不一致时会变形。按钮的hover效果用了translateY(-2px)模拟"浮起",比单纯改颜色更有实感。

如果想要一个"立即购买"按钮真正触发后续流程,比如跳转购物车或者弹窗,那就要在HTML里的href或按钮事件上接JS,这属于系列下一篇的内容。CSS负责的是把按钮营造出"可以点击"的视觉暗示。

5.3 移动端适配:一张卡片在不同屏幕下都不崩

一个商品卡片不能只在电脑上好看。手机屏幕宽度通常不到400px,如果卡片固定320px勉强能放下,但如果是两列商品卡片,或者页面整体要铺满,就要考虑适配。

比较基础也有效的做法,是把固定宽度改为相对单位,再用媒体查询做断点调整:

.product-card { width: 100%; max-width: 320px; } @media (max-width: 480px) { .info { padding: 12px 14px; } .price .new { font-size: 18px; } }

写成width: 100%; max-width: 320px之后,卡片在窄屏上会自动收缩,在宽屏上也不会无限拉长。媒体查询里的断点max-width: 480px表示"视口宽度小于等于480px时,应用这段样式",用来应对手机上字号过大的问题。真正的响应式布局比这复杂得多,但没有这个兜底,页面在手机上很容易出现横向滚动条或者内容被挤压。

另外,要在HTML的<head>里确保有这行viewport设置:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

没有它,手机浏览器会按桌面宽度渲染页面,然后缩放到手机屏幕里,文字和卡片会变得特别小,用户体验很糟。这个meta标签不是CSS,但它是所有静态页面做手机适配的第一步。

结尾

最后分享一点个人感受。CSS是非常容易入门但极难精通的领域,因为它不是线性逻辑,而是在优先级、继承、间距、对齐、动画各个维度之间相互影响。我自己刚学那阵,经常被一个hover不生效或者图片多出几像素搞得怀疑人生。后来总结出的经验是:遇到样式不对,先开控制台看匹配规则和计算样式,不要盲目改属性;写页面时先搭结构,再写基础布局,最后补交互细节,一步到位反而容易乱。

一个小建议:动手做几个小界面,从商品卡片到个人主页到登录页,每个都尽量用今天讲过的选择器、盒模型、flex居中、过渡动画,做完你就有体感了。CSS真正难的从来不是记住属性,而是形成"看到效果能反推实现"的思维习惯。这个系列下一篇会用到大量的class和样式钩子去接JS逻辑,所以这一篇的CSS基础越扎实,后面就越轻松。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询