媒体查询、响应式设计?帮我!
您想了解的有关媒体查询和响应式设计的一切
什么是媒体查询?
媒体查询是一种 CSS 语言功能,它允许作者根据正在查看应用程序的设备或窗口的特征有条件地应用 CSS 规则。最常见的是,这些可能是根据视口宽度,允许 CSS 作者创建响应于正在查看的窗口或设备的大小的组件和布局。但这也可能扩展到用户是否喜欢浅色或深色模式,甚至用户的可访问性首选项,以及更多属性。
什么是响应式设计?
随着如此多不同的设备类型和屏幕尺寸的兴起,Web 应用程序向用户提供更加定制的视觉呈现并针对其首选交互方法的屏幕尺寸进行优化变得越来越重要。
响应式设计可以通过多种技术的组合来完成,包括有条件地应用 CSS 规则与媒体查询、容器查询,以及根据其所容纳的内容选择灵活的布局(例如 Flexbox 或网格)。在本文中,我们将重点关注媒体查询和响应式布局,但随着浏览器支持长尾的增加,容器查询也需要牢记。截至撰写本文时,它们尚未准备好进入黄金时段,但可用于渐进增强。
什么是移动优先设计?
移动优先设计是设计和构建响应式 Web 应用程序时可以采用的原则。理想情况下,这种方法应该作为整个过程的所有阶段(从开始到结束)的指导原则。对于设计而言,这意味着线框或 UI 设计的第一次迭代应重点关注移动体验,然后再转向更宽的视口尺寸。
虽然您可以从另一个方向(宽优先)处理 Web 应用程序,但与尝试将组件塞进较小的屏幕空间相比,随着更多的屏幕空间变得可用,以可视方式重新组织组件是一个更容易的过程。
类似的规则也适用于开发过程。一般来说,您应该为基本情况(最窄的屏幕)编写标记和样式,并在必要时逐步为更宽的屏幕应用条件样式。
虽然您可以从另一个方向实现这一点,或者混合使用窄优先和宽优先的方法,但这可能会使您的样式更难以理解,并增加其他人在审查或维护时的精神负担。当然,也有例外,编写少量的宽优先规则会更简单,因此请酌情考虑。
CSS 像素与设备像素
Apple 于 2011 年推出 iPhone 4,它是第一款采用高密度显示屏的主流智能手机。早期 iPhone 的显示分辨率为 320x480 像素,当 iPhone 推出所谓的“视网膜显示屏”时(在物理显示宽度相同的情况下将分辨率加倍至 640x960 像素),这提出了一个挑战。由于不希望用户不断地问自己“这是什么,一个蚂蚁的网站吗?”,因此设计了一个巧妙的解决方案,让 iPhone 4 遵循 CSS 规则,就像它仍然是一个 320x480px 设备一样,并且只需以双倍密度渲染即可。这使得现有网站能够按预期运行,而无需更改任何代码 - 当新技术引入网络时,您会发现这是一个常见的主题。
由此,创建了术语“CSS 像素”和“设备像素”。
W3C CSS 规范将设备像素定义为:
设备像素是设备输出上能够显示其全部颜色范围的最小区域单位。
CSS 像素(也称为逻辑像素或参考像素)由 W3C CSS 规范定义为:
参考像素是设备像素密度为 96dpi、与阅读器距离为一臂长度的设备上一个像素的视角。对于 28 英寸的标称臂长,视角约为 0.0213 度。因此,对于在手臂长度处读取,1 像素相当于约 0.26 毫米(1/96 英寸)。
参考像素的 96 DPI 规则并不总是严格遵守,并且可能会根据设备类型和典型观看距离而变化。
设备像素比(或 dppx)是每个 CSS 像素使用多少设备像素的一维因子。设备像素比通常是整数(例如1、2、3),因为这使得缩放更简单,但并非总是如此(例如1.25、1.5等)。
如何使我的网站具有响应能力?
默认情况下,移动浏览器会假设网站的设计不适合此类设备的较窄视口。为了向后兼容,这些浏览器可能会像屏幕更大一样渲染站点,然后缩小规模以适应较小的屏幕。这不是理想的体验,因为用户经常需要缩放和平移页面,但允许网站大部分功能与最初创建时一样。
要告诉浏览器网站正在为所有视口尺寸提供优化的体验,您可以在文档中包含以下元标记<head>
:
<元名称= “视口”内容= “宽度=设备宽度,初始比例=1 ” />
非矩形显示器
现在的一些设备具有圆角或显示遮挡(例如显示凹口、相机打孔或软件覆盖),这意味着整个矩形对于内容来说并不“安全”,因为它可能被部分或全部遮挡。
默认情况下,此类设备上的浏览器将在“安全”内接矩形和与文档背景匹配的垂直或水平条内显示内容。
有一些方法可以让内容扩展到此区域并避免丑陋的信箱和邮筒,但这是一个不需要的更高级功能。
文字大小调整
移动浏览器还可能人为地增大字体大小以使文本更具可读性。如果您的网站已经提供了适当大小的文本,您可以包含以下 CSS 来禁用此行为:
html {
-moz-文本大小调整:无;
-webkit-文本大小调整:无;
文本大小调整:无;
}
虽然无障碍标准中没有强制规定文本的最小尺寸,但16px
对于大多数情况来说,这是一个很好的最小尺寸。
font-size
对于输入字段,如果小于,浏览器在聚焦时可能会放大16px
。有一些方法可以禁用此行为,例如maximum-scale=1.0
在元视口声明中设置 a ,但强烈建议不要这样做,因为这可能会干扰依赖缩放的用户。更好的解决方案是确保font-size
至少为16px
.
什么是断点?
样式中的断点是指条件样式规则根据视口大小停止或开始应用于页面的点。最常见的是,这指的是 amin-width
或max-width
,但也可以适用于height
too。
在媒体查询中,这些断点(768px
, 479px
)将像这样使用:
@media (最小宽度:768 px ){
// 这里的条件样式宽度 >= 768 px
}
@media (最大宽度:479 px ){
// 这里的条件样式宽度 <= 479 px
}
当遵循移动优先设计原则时,大多数时候min-width
应该使用媒体查询。
还需要注意的是,min-*
查询max-*
适用于包含范围,因此在断点两侧定义样式时,不应使用相同的像素值。
还需要注意的是,当放大页面时,以 CSS 像素为单位的视口大小可能会随着设备像素比率的变化而变化。这可能会导致视口实际上表现为其长度是小数值的情况。
@media (最大宽度:479 px ){
// 这里的条件样式宽度 <= 479 px
}
@media (最小宽度:480 px ){
// 这里的条件样式宽度 >= 480 px
}
在上面的示例中,如果视口(由于缩放)报告为479.5px
,则两个条件规则块都不会应用。0.98px
相反,通常会对查询应用额外的小数值max-width
,例如
@media (最大宽度:479.98 px ){
// 此处的条件样式适用于宽度 < 480 px
}
@media (最小宽度:480 px ){
// 这里的条件样式宽度 >= 480 px
}
具体为什么呢0.98px
?0.02px
是 Safari 早期版本支持的 CSS 像素的最小划分。请参阅WebKit 错误 #178261。
CSS 在媒体查询第 4 级规范中引入了范围查询的概念,其中运算符<
、>
、<=
和>=
可用于更具表现力的条件,包括包含范围和排除范围。截至撰写本文时,所有主要的常青浏览器均支持这些功能,但是,iOS 等平台上的长尾支持还不够。
@media (宽度< 480像素){
// 此处的条件样式适用于宽度 < 480 px
}
@media (宽度>= 480像素){
// 这里的条件样式宽度 >= 480 px
}
我应该选择什么断点?
这是一个经常被问到的问题,但坦率地说,现在只要 Web 应用程序能够合理地适应您选择的断点之间的所有屏幕尺寸,这并不重要。您也不想选择太多或太少。
当 iPhone 于 2007 年首次推出时,它的屏幕分辨率为 320x480px。按照惯例,此后所有智能手机的视口宽度都至少为 320 CSS 像素。在构建响应式网站时,您至少应该满足此宽度的设备。
最近,一类具有更经典外形的设备(称为功能手机)以及可穿戴技术越来越容易访问网络。这些设备的视口宽度通常小于 320 像素。
如果您使用的设计系统或组件库(例如Material UI、Bootstrap等)为您提供了自己的默认断点,您可能会发现坚持使用这些断点是有益的。
如果您选择自己的断点,则有一些历史相关的断点可以作为灵感:
- 320px -
320px
智能手机视口的最小宽度 - 480px - 智能手机和平板电脑之间的大致边界
- 768px - 原始 iPad 的分辨率为 768x1024px
- 1024px - 同上
- 1280px - 16:9 720p (HD) 显示屏的标准宽度
通常,命名断点是个好主意。但是,请不要试图将它们称为“移动”、“平板电脑”和“桌面”等名称。虽然在平板电脑的早期,移动设备、平板电脑和桌面设备之间的界限更加清晰,但现在设备和视口尺寸的范围如此广泛,以至于这些设备之间的界限变得模糊。如今,我们拥有屏幕尺寸比某些平板电脑还大的可折叠手机,以及令台式机和笔记本电脑屏幕相形见绌的平板电脑屏幕。
将特定范围称为“平板电脑”或“桌面”可能会让您陷入针对单一类型设备进行构建和设计的陷阱(例如,假设“移动”或“平板电脑”视口将始终使用触摸屏)。相反,您应该专注于构建适用于各种设备的体验。
响应式布局技术
有两种 CSS 布局算法特别适合响应式设计:
- 弹性盒
- CSS 网格
弹性盒
Flexbox 是一种 CSS 布局算法,它允许我们指定子元素在页面上的排列方式。此控件适用于特定方向(称为柔性轴)。
尽管 Flexbox 可用于渲染多行(带换行),但一行中的内容元素不会更改元素在其他行上的排列方式。这意味着除非显式设置 Flex 项目的宽度,否则它们的排列可能会不一致。如果需要的话,CSS Grid 可能更合适。
柔性包裹
Flexbox 可以在没有媒体查询的情况下使用,而是依赖属性flex-wrap
来允许内容根据内容大小确定多次跨越横轴。设置flex-wrap: wrap
意味着内容会在下方 ( flex-direction: row
) 或右侧 ( flex-direction: column
) 换行。您还可以设置flex-wrap: wrap-reverse
内容在上方或左侧换行。
弯曲方向
通常,设计可能要求针对水平空间非常宝贵的狭窄视口垂直排列内容,但对于具有更多屏幕空间的更宽视口,这可能会更改为水平排列内容。
.className {
显示:柔性;
弯曲方向:列;
}
@media (最小宽度:768 px ){
.className {
弯曲方向:行;
}
}
网格
网格是一种 CSS 布局算法,它允许我们指定子元素在页面上的排列方式。网格允许开发人员指定元素在行和列之间的排列方式。
尽管存在显着差异,但在可以实现哪种布局方面与 Flexbox 存在重叠。使用网格布局,网格项根据水平轴和垂直轴上的网格轨迹进行约束和对齐。
以下只是与响应式设计完美搭配的常见布局技术的几个示例。
列
设计人员通常会使用 12 列网格(或窄视口的 4 列网格)。您可以使用 CSS 在 CSS 中复制此模型grid-template-columns
。与断点相结合,您可以轻松分配使元素跨越特定数量的列的类。
您可以在此处查看底层网格系统(包括间隙)的图示:
上面的示例仅展示了这种布局技术的一小部分。Google 的 Una Kravets 在One Line Layouts 开发网站上分享了一些交互式示例。请注意,本博客中的示例使用minmax(auto, 1fr)
而不是1fr
考虑gap
.
RAM(重复、自动、最小最大)
另一种网格布局技术通常称为 RAM(重复、自动、最小最大)。我鼓励您查看One Line Layouts 开发网站上的交互式示例。
当您事先不知道网格需要多少列,而是更喜欢在某些预设边界内由内容的大小来确定时,RAM 最有用。auto-fit
和auto-fill
工作方式类似,除了当项目少于填充单行时会发生什么情况。
// 网格项的宽度始终至少为 150px ,
// 并将拉伸以填充所有可用空间
.自动调整{
显示:网格;
网格模板列:重复(自动调整,minmax (150 px ,1 fr ));
}
// 网格项的宽度始终至少为 150px ,
// 并且会拉伸直到有足够的空间
// (如果有的话)添加匹配的空网格轨道
.自动填充{
显示:网格;
网格模板列:重复(自动填充,minmax (150 px ,1 fr ));
}
网格模板区域
网格模板区域是响应式布局最强大的工具之一,允许您以直观的方式将元素排列到网格上。
例如,我们可能有一个包含标题、主要部分、侧边栏和页脚的布局,它们都垂直排列以适应狭窄的视口。grid-template-areas
与grid-template-columns
和结合使用grid-template-rows
,我们可以将这些相同的元素重新排列成具有相同标记的网格图案。
上面的例子会产生类似这样的结果:
响应式图像
对于高密度显示器,使用根据 CSS 像素而不是设备像素调整大小的图像可能会导致质量低于用户预期,并且在看起来清晰的文本或矢量资源旁边可能会特别不和谐。因此,为用户提供更高密度的图像是有意义的。
如果可能的话,请使用基于矢量的图像 (SVG)。矢量不是指定像素光栅,而是描述在屏幕上绘制某些内容的过程,并且该过程可以放大/缩小到始终保持清晰的任何屏幕尺寸。矢量图像通常适用于简单的插图、图标或徽标。它们不适合拍照。
对于光栅图像,有几种方法可以为高密度显示指定多个图像源,从而允许浏览器选择最适合给定设备的图像源。
<img>
对于静态大小的图像,您可以使用srcset
x 描述符(指定最佳设备像素比)指定。例如,如果您有一个以 44 像素宽显示的图标或徽标,您可以创建该图像的许多不同版本并指定如下内容:
<图片
源集= “
/path/to/img-44w.png 1x,
/path/to/img-66w.png 1.5x,
/path/to/img-88w.png 2x,
/path/to/img-132w.png 3x
”
/>
重要的是,这些 x 描述符仅充当提示,设备仍可能出于各种原因(例如用户选择带宽节省条款)选择较低分辨率的版本。
类似的技术可用于在 CSS 中background-image
使用image-set()
(请注意,浏览器支持并不完善):
.选择器{
高度:44像素;
宽度:44像素;
/* 不支持 image-set() 的浏览器的 2x 回退 */
背景图像:url (/path/to/img-88w.png );
/* Safari 仅支持 -webkit-image-set() */
背景图像:-webkit-图像集(
网址( /path/to/img-44w.png ) 1 x ,
网址(/path/to/img-66w.png)1.5 x ,_ _
网址( /path/to/img-88w.png ) 2 x ,
网址( /path/to/img-132w.png ) 3 x
);
/* 标准语法 */
背景图像:图像集(
网址( /path/to/img-44w.png ) 1 x ,
网址(/path/to/img-66w.png)1.5 x ,_ _
网址( /path/to/img-88w.png ) 2 x ,
网址( /path/to/img-132w.png ) 3 x
);
}
对于随着页面大小调整而改变大小的图像,可以使用srcset
和属性的组合。sizes
例如
<图片
源集= “
/路径/到/img-320w.jpg 320w,
/路径/到/img-480w.jpg 480w,
/路径/到/img-640w.jpg 640w,
/path/to/img-960w.jpg 960w,
/路径/到/img-1280w.jpg 1280w
”
尺寸= “ (最小宽度:768px)480px,100vw ”
/>
在上面的示例中,我们在srcset
不同的实际宽度(320px、480px、640px、960px、1280px)中指定了许多不同的图像呈现。在该sizes
属性中,我们告诉浏览器默认情况下这些图像将以视口宽度的 100% 显示,然后对于 768px 及更宽的视口,图像将以固定的 480 CSS 像素宽度显示。然后,浏览器将考虑设备像素比,为设备选择最佳图像呈现(不过,这只是一个提示,浏览器可能会选择使用更高或更低的分辨率选项)。
利用 WebP 和 AVIF 等图像格式的现代压缩技术,通常会出现这样的情况:当图像经过适当优化以 2 倍密度显示时,文件大小仅比 1 倍版本略有增加。而且,对于大于 2 的设备像素比,收益递减。因此,您可以只包含优化的 2x 图像。Google Chrome 团队的开发者倡导者 Jake Archibald 撰写了一篇讨论此问题的博客文章,强调了大多数用户可能正在使用高密度显示器浏览网页的事实。
via https://engineering.kablamo.com.au/posts/2023/media-queries-and-responsive-design/