主题
媒体查询和响应式布局与BFC(Day16 2/3)
本页对应 Day16_CSS3,共 6 段视频,约 1 小时 17 分。
学习目标
- 能够解释移动端视口默认缩放为 980px 的原因,并说明
meta viewport中width=device-width、initial-scale=1的作用及适用场景。 - 能够使用
@media按all、screen、print等媒体类型编写样式,并通过屏幕显示与打印预览验证样式生效范围。 - 能够使用
width、min-width、max-width等媒体特性编写范围条件,并正确区分max-width表示“小于等于”、min-width表示“大于等于”。 - 能够使用
and、逗号、only、not组合媒体查询条件,实现如 600–800px 区间、400px 以下或 1000px 以上等条件样式。 - 能够通过
<link media="...">按条件加载独立 CSS 文件,并说明其与 CSS 内@media写法相比在文件数量和加载性能上的取舍。 - 能够根据页面不同模块的内容与布局需求确定响应式阈值/断点,并解释阈值不是固定统一值,而应随模块内容调整。
知识点
本节回顾的边界与同音字说明
本节笔记标题是“1 回顾”,提纲集中在多列布局和伸缩盒布局(Flex)。转写稿实际讲的是视口、媒体查询、阈值/断点,与本节提纲并不一一对应;因此下面只按笔记提纲做回顾,不把后续视口、媒体查询内容硬塞进多列/Flex。转写稿中“市口、适口、矢口、狮口”应纠正为“视口”,“无忧port”应纠正为“viewport”,“显应式、详式、想要式”应纠正为“响应式”,“预直、玉齿”应纠正为“阈值/断点”。这些词在本节不展开。
本节笔记原属性清单如下,保留备查:
css
/* 多列布局:设置给多列容器 */
column-count;
column-width;
columns;
column-gap;
column-rule-style;
column-rule-color;
column-rule-width;
column-rule;
/* 多列布局:设置给子元素 */
column-span;
-webkit-column-break-before;
-webkit-column-break-after;
-webkit-column-break-inside;
/* Flex:设置给伸缩容器 */
display: flex;
flex-direction;
flex-wrap;
flex-flow;
justify-content;
align-items;
align-content;
/* Flex:设置给伸缩项目 */
flex-basis;
flex-grow;
flex-shrink;
flex: grow shrink basis;
order;
align-self;多列布局:先设容器
为什么需要:长文本一行铺满会很宽,阅读时眼睛回行累;多列能把内容切成报纸式栏目。怎么想:列数、列宽、列间距、列间分隔线都由“多列容器”统一控制,不是给每个子元素分别设。怎么做:用 column-count 定列数,column-width 定理想列宽,columns 做简写;column-gap 控间距;column-rule-style/color/width 控分隔线,column-rule 做简写。易错点:这些属性写给子元素通常无效;column-rule-style 不写,分隔线不会显示;column-rule 是画在列间的线,不要把它当占位边框理解。
多列布局:子元素跨列与断点
为什么需要:标题、图片、卡片有时不该被拆到两列里,需要跨列或控制断点。怎么想:跨列看 column-span;分列断点看 break-before/after/inside 这一类属性。怎么做:笔记中列的是 column-span、-webkit-column-break-before、-webkit-column-break-after、-webkit-column-break-inside,分别控制跨列、分列前断、分列后断、分列内部断。易错点:带 -webkit- 的是旧前缀写法,兼容性要按项目目标确认;column-span 常见取值是 all/none,不要和 Flex 的跨行跨列混为一谈。
Flex:容器与项目
为什么需要:一维排列、对齐、分配剩余空间,用 Flex 比浮动和定位直接。怎么想:先分清“伸缩容器”和“伸缩项目”:给父元素 display:flex,它的直接子元素才成为项目。怎么做:容器侧用 display、flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content;项目侧用 flex-basis、flex-grow、flex-shrink、flex、order、align-self。易错点:display:flex 只影响直接子元素;主轴方向一变,justify-content 和 align-items 的方向含义也跟着变。
主轴方向、换行与主轴对齐
为什么需要:项目要横排还是竖排、要不要换行、在主轴怎么分布,是 Flex 最基础的控制。怎么想:flex-direction 定主轴,flex-wrap 定是否换行,flex-flow 是二者简写;justify-content 管主轴对齐。怎么做:横排用 row,竖排用 column;不换行时项目可能被压缩,换行后多行才有 align-content 的用武之地。易错点:把 justify-content 和 align-items 记反;不换行时误以为 align-content 一定生效。
侧轴对齐:一行与多行
为什么需要:项目在交叉轴上要居中、拉伸或靠边。怎么想:单行看 align-items,多行看 align-content,单个项目想例外就用 align-self。怎么做:容器设 align-items 统一侧轴对齐;换行形成多行后,用 align-content 控行与行之间;项目设 align-self 覆盖自身。易错点:align-content 在单行且不换行时通常没有多行可分配;align-self 写给容器无效,要写给项目。
伸缩性、排序与总结
为什么需要:项目要按比例放大、按空间收缩、按基准分配,还要调整视觉顺序。怎么想:flex-grow 管放大,flex-shrink 管收缩,flex-basis 管基准;flex 简写顺序是 grow shrink basis;order 改视觉顺序,align-self 单独改侧轴。怎么做:常用 flex: 1 让项目参与分配;order 数值越小越靠前。易错点:order 只改视觉顺序,不改 DOM 顺序,注意可访问性;Flex 简写不要漏写顺序;本节是回顾,真正写页面时仍要按“容器属性”和“项目属性”分组检查。
视口与完美视口:先解决移动端缩放
为什么需要:移动端浏览器默认会把视口缩放成约 980px。转写稿里在 iPhone 375px 屏幕中放一个 350px 的盒子,结果盒子显得很小,审查元素发现 html 宽是 980px,因为浏览器把 375px 屏幕“当成 980px 来用”。响应式布局要求屏幕多宽、视口就多宽,所以必须先设置完美视口。
怎么想:视口是浏览器可视区域,也是根元素的包含块;给根元素设 width:100%、height:100% 都参照视口。PC 端默认基本是完美视口,移动端需要网页自己声明。
怎么做:在 head 中写:
html
<meta name="viewport" content="width=device-width, initial-scale=1.0">它的作用是设置完美视口:视口宽度等于设备宽度,不缩放。
易错点:做响应式页面、手机端页面要加;专门针对 PC 的固定版型页面不要乱加,否则可能显示不全。width=device-width 和 initial-scale=1.0 常一起写,写一个也行,但习惯上两个都写。
媒体类型:先学会 @media 语法
为什么需要:媒体查询要按设备或条件写样式。媒体类型有 all、screen、print、speech 等,但手机和电脑都属于 screen,它不能区分手机和电脑。
怎么想:语法是 @media 媒体类型 { 选择器 { 声明 } },大括号里仍要写选择器。媒体查询里的样式不会提高权重,冲突时仍看选择器权重;权重相同则后写覆盖先写。
怎么做:
css
@media screen {
h1 { text-align: center; }
}
@media print {
h1 { text-align: right; }
body { border: 1px solid red; }
}转写稿中用打印预览验证:屏幕样式在打印预览不生效,print 样式只在打印预览生效。
易错点:媒体查询不提高权重;想让条件样式覆盖前面的,可提高选择器权重,或把媒体查询写到后面。实际开发很少专门给打印机写样式。
媒体特性:用宽度做判断
为什么需要:媒体类型区分不了手机电脑,真正常用的是视口宽度。
怎么想:width 是固定视口宽度;max-width 是小于等于;min-width 是大于等于。高度很少用,重点看宽度。device-width 是屏幕宽度,PC 调试时和视口宽度有区别;移动端屏幕多宽视口就多宽,基本没区别。推荐用视口宽度,方便在 PC 调试工具里拖动模拟。
怎么做:
css
@media (width: 800px) {
body { background: #900; }
}
@media (max-width: 600px) {
body { background: green; }
}
@media (min-width: 1000px) {
body { background: #090; }
}转写稿中把视口调到 800px 验证固定宽度;小于等于 600px 时绿色生效;大于等于 1000px 时另一套生效。
易错点:max-width 是“小于等于”,min-width 是“大于等于”;固定宽度太死,实际更常用范围;媒体特性名和值要放在小括号里。
运算符:and、逗号、only、not
为什么需要:一个条件不够时要组合,例如 600 到 800 之间,或 400 以下、1000 以上。
怎么想:and 表示“并且”,逗号表示“或者”;only 表示“仅仅”,实际不加也常是同一意思,常见写法是兼容老 IE;not 是否定媒体类型。
怎么做:
css
@media (min-width: 600px) and (max-width: 800px) {
body { background: #900; }
}
@media (max-width: 400px), (min-width: 1000px) {
body { background: #009; }
}
@media only screen and (max-width: 768px) {
h1 { text-decoration: underline; }
}易错点:and 连接两个媒体特性,每个特性各自用小括号;逗号是“或”,不能把“小于等于 400 且大于等于 1000”这种不存在条件写成 and;only 不提高权重。
link 标签的 media 属性:第二种写法
为什么需要:可以把基础样式和条件样式拆成不同 CSS 文件,用 link 的 media 属性控制加载条件。
怎么想:style.css 始终加载,min1000.css 只在视口大于等于 1000px 时加载。
怎么做:
html
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="min1000.css" media="(min-width: 1000px)">易错点:不推荐拆太多文件,CSS 文件过多会增加请求,不利于页面加载;条件多时会有多个 link。更推荐在一个 CSS 文件里写 @media。
阈值/断点:先定分界,再写响应式
为什么需要:页面在不同宽度下要切换布局,例如微软官网导航在约 860px 收起,产品列表在约 1084px、480px 变化。阈值就是分界点。
怎么想:常见参考有 640/1080,或 Bootstrap 的 768/992/1200,但这些只是参考,不是死规定。不同组件阈值可以不同,要看内容是否放得下:导航放不下就收起,商品列表放不下就减少每行个数。
怎么做:先设计阈值,再在对应组件样式后写媒体查询。转写稿强调:写导航时就把导航各宽度样式写完,写商品列表时再写商品列表的媒体查询,各写各的,不要等整页写完再统一补。
易错点:阈值不是固定值,不能一套阈值硬套所有组件;媒体查询建议写在对应样式后面,便于覆盖;不要怕同一条件写两遍,符合条件就会执行。
说明:本节笔记标题写作“3 BFC”,但转写稿实际讲的是视口、媒体查询与阈值,通篇没有出现 BFC 的定义、触发条件或清除浮动内容。为避免编造,下面严格按转写稿整理;转写稿未提供图片,代码片段按原意保留并纠正同音字。
视口:页面初始包含块
为什么需要:给根元素或 html 设 width: 100% 时,参照的是视口;不理解视口,就不知道百分比宽度、移动端缩放到底相对谁计算。
怎么想:视口就是浏览器可视区域,英文 viewport。地址栏、标题栏不属于视口。视口是页面的初始包含块,也是根元素的包含块。
怎么做:PC 端浏览器窗口多宽,视口通常就多宽;移动端默认不是这样,后面要用 meta 修正。
易错点:不要把“屏幕宽度”和“视口宽度”混为一谈;调试工具拉动窗口改变的是视口,不是物理屏幕。
移动端为什么默认缩放成 980
为什么需要:早期手机访问的是为 PC 设计的固定版心网页。若 320/375 宽屏幕直接显示 960/980 版心,只能看到一部分,所以浏览器默认把布局视口放大到约 980,再整体缩小显示。
怎么想:调试 iPhone 375 宽时,写一个 350px 的盒子却显得很小;审查元素发现 html 宽度是 980,说明 375 的屏幕被当成 980 来排版。换三星 360、iPhone 5 320,html 仍常见 980。
怎么做:做响应式或手机端页面时,在 head 中写:
html
<meta name="viewport" content="width=device-width, initial-scale=1.0">易错点:width=device-width 和 initial-scale=1.0 只写一个通常也能达到目的,但实际项目常两个都写。PC 老页面不要随便加,否则固定版心可能显示不全。
完美视口与 PC/移动端差异
为什么需要:响应式布局要求“屏幕多宽,视口就多宽”,不能默认缩放成 980。
怎么想:PC 端默认基本就是完美视口;移动端默认会缩放。所谓完美视口,就是视口宽度等于设备宽度、不缩放。
怎么做:通过 meta viewport 设置完美视口。它是响应式开发第一步。
易错点:不是所有页面都加。专门针对 PC 的固定版心页面不加;响应式页面和专门手机端页面要加。
媒体查询语法:媒体类型
为什么需要:同一套 HTML 要在屏幕、打印等不同设备上应用不同样式。
怎么想:@media 后写媒体类型,大括号里仍要写选择器和声明块。常用 screen、print、all,屏幕阅读器等发声设备实际很少针对它做样式。媒体类型不能区分手机和电脑,因为二者都归 screen。
怎么做:
css
@media screen {
h1 { text-align: center; }
}
@media print {
body { border: 1px solid red; }
h1 { text-align: right; }
}调试时用打印预览看 print 样式,屏幕样式在打印预览中不生效。
易错点:媒体查询不会提高选择器权重。若内外选择器相同,后写的覆盖前面的;因此常把媒体查询写在后边。
媒体特性:用宽度做断点
为什么需要:媒体类型区分不了屏幕大小,实际开发要看视口宽度。
怎么想:width 是视口宽度;max-width: 600px 表示小于等于 600;min-width: 1000px 表示大于等于 1000。固定写 width: 800px 太死,范围才是常态。
怎么做:
css
@media (max-width: 600px) {
body { background: green; }
h1 { text-decoration: underline double #900; }
}
@media (min-width: 1000px) {
body { background: #090; }
h1 { text-decoration: underline wavy; }
}调试时在 F12 中拉动视口宽度,观察样式切换。device-width 是设备屏幕宽度,width 是视口宽度;移动端二者基本一致,PC 调试时用 width 更方便。
易错点:max- 是小于等于,min- 是大于等于;不要写反。高度特性很少用,重点在宽度。
运算符:and 与逗号
为什么需要:一个条件不够时,要组合范围。
怎么想:and 表示“并且”,逗号表示“或者”。only 基本是历史兼容写法,不提升权重;not 表示否定。
怎么做:
css
@media (min-width: 600px) and (max-width: 800px) {
body { background: #900; }
}
@media (max-width: 400px), (min-width: 1000px) {
body { background: #009; }
}易错点:only 不要误以为能提高优先级;同一媒体查询可以写多遍,只要条件满足就会执行,最终仍看选择器权重和书写顺序。
link 的 media 属性与阈值
为什么需要:媒体查询还可以配合 link 标签按条件加载 CSS。
怎么想:link 的 media 是 HTML 属性,不是 CSS 属性。条件写在小括号里。
怎么做:
html
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="min1000.css" media="(min-width: 1000px)">易错点:这种写法不推荐,因为条件多时会产生多个 CSS 文件,增加请求。更推荐把 @media 写进同一个 CSS 文件。
所谓阈值/断点,就是“多少宽度以上算大屏、以下算小屏”。常见参考有 640、1080,或 Bootstrap 的 768、992、1200。但阈值不是死的:微软官网导航约 860 收起,产品列表约 1084 从四列变两列,再小到约 480 变一列。实际开发要按组件内容定阈值,并按组件分别写外层样式和媒体查询,不要等整页样式写完再统一补媒体查询。
课堂画面






代码示例
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<!-- 移动端完美视口:取消注释后,视口宽度 = 设备宽度,不再缩放为 980 -->
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<title>视口测试</title>
<style>
body {
margin: 0;
}
.box {
width: 350px;
/* height: 200px; */
padding: 20px;
box-sizing: border-box;
background: #900;
color: #fff;
}
</style>
</head>
<body>
<div class="box">
视口测试文字:在移动端模拟器中,注释掉 viewport 时,html 宽度通常为 980px,350px 的元素会被明显缩小;取消注释后,视口宽度等于设备宽度。
</div>
</body>
</html>关键行与易错点:
width=device-width表示视口宽度等于设备宽度;initial-scale=1.0表示初始不缩放。转写稿明确说“写一个也行,但习惯两个都写”。- 移动端浏览器默认会把视口缩放成约
980px,所以 375px 宽的手机上,350px 的元素看起来会非常小;加上 viewport 后才是“完美视口”。 - PC 端默认就是完美视口,不需要这个 meta;做响应式页面、手机端页面要加;只做 PC 固定版型的页面不要加,否则移动端会显示不全。
- 易错点:不要以为 PC 浏览器里看不出效果就是没生效,要在移动端模拟器里看
html的宽度。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>媒体类型</title>
<style>
body {
background: #000;
}
h1 {
color: #fff;
font-size: 3em;
}
/* 屏幕设备:居中 */
@media screen {
h1 {
text-align: center;
}
}
/* 打印机 / 打印预览:靠右,并加边框 */
@media print {
h1 {
text-align: right;
}
body {
border: 1px solid red;
height: 100px;
}
}
</style>
</head>
<body>
<h1>媒体类型</h1>
</body>
</html>关键行与易错点:
@media screen只针对带屏幕的设备;@media print只在打印或打印预览时生效。@media大括号里仍然要写选择器,再写声明块,不能直接写样式声明。- 媒体查询本身不会提高样式权重;如果选择器权重相同,后写的覆盖前面的,所以实际开发常把媒体查询写在后边。
screen不能区分手机和电脑,手机、电脑、智能电视都属于屏幕设备。- 易错点:打印预览里背景色通常不打印,不要用背景色判断
@media print是否生效;看文字对齐、边框更明显。body默认没有固定高度,加height是为了更清楚看到边框。 only screen and (max-width: 768px)这种写法中的only对现代浏览器基本没有实际过滤作用,主要是老 IE 不认识会跳过;not才是否定媒体类型。
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>媒体特性与运算符</title>
<style>
body {
margin: 0;
background: #333;
}
h1 {
text-align: center;
font-size: 4em;
color: #fff;
}
/* 视口宽度正好等于 800px */
@media (width: 800px) {
body {
background: #900;
}
}
/* 视口宽度 <= 600px */
@media (max-width: 600px) {
body {
background: green;
}
h1 {
text-decoration: underline double #900;
}
}
/* 视口宽度 >= 1000px */
@media (min-width: 1000px) {
body {
background: #090;
}
h1 {
text-decoration: underline wavy;
}
}
/* 600px <= 视口宽度 <= 800px:and 表示“并且” */
@media (min-width: 600px) and (max-width: 800px) {
body {
background: #900;
}
}
/* <= 400px 或 >= 1200px:逗号表示“或者” */
@media (max-width: 400px), (min-width: 1200px) {
body {
background: #009;
}
}
</style>
</head>
<body>
<h1>媒体特性</h1>
</body>
</html>关键行与易错点:
- 媒体特性必须用小括号包起来,例如
(max-width: 600px);and两边条件都要各自加小括号。 max-width是“小于等于”,min-width是“大于等于”;width: 800px是精确等于,实际开发少用。and表示“并且”,逗号,表示“或者”。例如(min-width: 600px) and (max-width: 800px)是 600 到 800 之间;(max-width: 400px), (min-width: 1200px)是小于等于 400 或大于等于 1200。- 易错点:600px 会同时命中
(max-width: 600px)和(min-width: 600px) and (max-width: 800px),后写的#900会覆盖绿色;1200px 以上也会同时命中min-width: 1000px和min-width: 1200px,后写蓝色覆盖绿色。媒体查询不提高权重,覆盖看选择器权重和书写顺序。 - 移动端
width和device-width基本没区别;PC 端调试时width会随调试窗口变化,device-width不随窗口变化。推荐用视口宽度width,方便调试。 - 实际响应式开发常用阈值/断点如
640 / 1080、Bootstrap 的768 / 992 / 1200,但阈值不是死的,要按页面某一部分的内容决定。 - 第二种写法
<link rel="stylesheet" href="min1000.css" media="(min-width: 1000px)">可以用,但不推荐:条件多时要写多个 link、多个 CSS 文件,不利于页面加载;更推荐写在一个 CSS 文件里用@media。
常见错误
- 现象:移动端页面元素明显变小,
html宽度被当成 980 → 原因:缺少视口声明,移动端浏览器按默认视口缩放 → 修法:响应式/移动端页面加入<meta name="viewport" content="width=device-width, initial-scale=1.0">,PC 固定版页面不要盲目加。 - 现象:媒体查询里的样式没有覆盖外部样式 → 原因:误以为
@media会提高权重,实际仍看选择器权重和书写顺序 → 修法:保持相同选择器时把媒体查询写在后面,或必要时提高选择器权重。 - 现象:
max-width/min-width条件写反,断点表现相反 → 原因:把“最大视口宽度”理解成“大于”,把“最小视口宽度”理解成“小于” → 修法:记成max-width为小于等于、min-width为大于等于,并用浏览器拖动宽度验证。 - 现象:给
screen写媒体查询后,手机和电脑仍然区分不开 → 原因:screen只表示带屏幕设备,不区分手机/电脑 → 修法:用width、min-width、max-width等媒体特性按视口宽度做条件。 - 现象:大量使用
<link media="...">拆分多个 CSS 文件,页面请求变多 → 原因:把媒体查询条件分散到多个外链文件 → 修法:优先在一个 CSS 文件内用@media组织,除非确有独立加载需求。 - 现象:不同组件在同一宽度下布局拥挤或过早折叠 → 原因:全页只拍一个阈值,忽略各组件内容容量 → 修法:按组件内容分别设定断点,导航、商品列表、页脚可不同;阈值只作参考。
- 现象:调试媒体查询时用
device-width在 PC 上拖动窗口不生效 → 原因:device-width看设备屏幕宽度,不随调试窗口变化 → 修法:开发调试优先用width/min-width/max-width,需要模拟设备时再切换设备模式。
练习
- 给一个移动端响应式页面补齐视口声明,并说明不加时在 iPhone 375px 屏幕上的异常表现及原因。
- 改写条件:视口宽度在 600px 到 800px 之间生效;视口宽度小于等于 400px 或大于等于 1000px 生效。分别写出媒体查询条件。
- 给出外部样式与媒体查询样式冲突的代码片段,要求调整为“同等选择器下媒体查询样式能覆盖”,并说明调整依据。
- 某页面导航在 860px 折叠、商品列表在 1084px/480px 变化、页脚在 1084px/480px 变化。判断是否应全页统一一个断点,并给出修改方案。
- 将一段写在多个
<link media="...">中的响应式样式改为单个 CSS 文件内的@media组织,说明这样改的取舍。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 视口 | 20:19 |
| 2 | 媒体查询-媒体类型 | 11:06 |
| 3 | 媒体查询-媒体特性 | 16:15 |
| 4 | 媒体查询运算符 | 12:53 |
| 5 | 第二种使用媒体查询的方式 | 10:15 |
| 6 | 阈值 | 06:45 |
小结
- 响应式开发第一步是确认视口策略:移动端/响应式页面需要视口声明,PC 固定版页面不应机械添加。
- 媒体查询不改变选择器权重,冲突时仍按权重和先后顺序决定,工程上常把媒体查询写在对应模块样式之后。
screen不能区分手机和电脑,真正用于布局判断的是视口宽度相关媒体特性。max-width是小于等于,min-width是大于等于;范围组合用and,多条件任选其一用逗号。only多为历史兼容写法,现代开发不必依赖;打印等媒体类型只在特定场景使用。- 阈值不是全页死数,应按组件内容容量分别设定;常见参考断点只能作为起点。
- 调试媒体查询优先用视口宽度,PC 拖动窗口即可验证;
device-width在移动端与视口宽度接近,但不利于 PC 调试。 - 外链
media可用但不优先推荐,减少 CSS 文件拆分更利于加载与维护。