实现响应式布局的几个着手点


2024年,回头看响应式布局

现如今,人们通过各种设备访问互联网—无论是手机、笔记本电脑、台式机、平板电脑还是 电视、投影仪等。静态布局的网站早已不再适用,因为它们无法让用户在更换设备时仍能获得舒服的浏览体验。

然而,在Web开发领域,响应式设计的概念往往给初学者带来陡峭的学习曲线。即使在掌握了很多高级概念之后,许多人仍然难以完全掌握响应式设计的原则。

即使是成熟的网站,在响应速度方面也会出现问题。例如: 截屏2024-04-17 10 42 52

那什么是响应式设计呢

响应式设计是一种网页设计理念,根据不同屏幕的尺寸和分辨率自动调整设计。在这种理念下设计的网站,无论用户是在宽大的台式机显示器上还是在小巧的手机屏幕上浏览网页,都能获得流畅的体验。

例如,一个由几列组成的大型网站页面,在移动设备上会被分隔成垂直堆叠的几个区块,方便访客阅读文字和查看图形。 PC端截屏2024-04-17 10 43 58

移动端截屏2024-04-17 10 45 01

其实可以从以下七个方面着手:

  • 尺寸单位
    • 相对于屏幕屏幕可以使用 vwvh
    • 相对于其他元素可以使用百分比
  • max-widthmin-width 属性
  • Flexbox
  • CSS Grid
  • 媒体查询(Media Queries)
  • 响应式图像属性
  • 使用 JavaScript

尺寸单位

大多数开发者都专注于创建一个非常适合屏幕的设计。因此,他们没有意识到用精确的单位(通常是像素px)指定元素大小、paddingmargin 等所带来的弊端。这些元素永远不会随着屏幕尺寸的变化而改变自身大小。但是假如使用百分比viewport单位vwvh等不那么绝对的单位是实现灵活布局的关键。

百分比

初学者必须谨慎使用百分比,因为首先需要理解父子关系的概念,以及当给一个子子元素设定百分比时,它是相对于其父父元素/容器大小的百分比,而不是整个屏幕的百分比。

这里的另一点是,所有看似 “没有父元素 “的外部元素实际上都有,那就是<body>元素。主体的大小如下:

  • 宽度—屏幕的宽度
  • 高度—其内部内容的高度(如果 body 中没有任何内容,则高度为 0)

Viewport 宽度&高度(vw & vh)

当您希望一个元素的大小相对于屏幕进行确定,而不是与其直接容器的大小无关时,那么可以使用vwvh。 下面就是一个例子。

假设您的网站有一个<header>部分和一个<main>部分,您想特别确定标题部分的高度,而让主部分占据屏幕其余部分的高度。 实现这一目标的方法如下:

header {
    height: 300px;
}

main {
    height: calc(100vh - 300px);
}

1vh的意思是视窗高度(屏幕高度)的 1% 。因此,100vh 表示屏幕高度的 100%,而 calc(100vh - 300px) 表示 “屏幕高度的 100%减去 300px”。 这就确保了主部分将占据标题之后屏幕高度的剩余部分。

也可以使用 flex 来实现这种效果,这个稍后再谈。

那么还需使用 px 吗?

有了这些其他选项和我将在下文中详细介绍的选项,并不意味着 px 单位在如今的 CSS 中就没有用武之地了。在很多情况下,你仍然希望某些东西具有特定的尺寸,而这种尺寸不会随着屏幕的变化而变化。

用户界面设计中的许多元素可能都希望有一个永远不会改变的特定尺寸。例如,按钮通常就是这种需求。

max-width 和 min-width 属性

当你希望元素的大小可以增大或缩小,但只到某一点时,这两种属性就会变得非常有用。 一种常见的情况是用户界面顶部的搜索栏。在移动设备上,搜索栏可能会占据屏幕宽度的大部分。虽然笔记本电脑的搜索栏要比手机的大,但一旦设备变大,你就不会希望搜索栏保持几乎整个屏幕的宽度。 看看 Airbnb 的输入栏是如何随着屏幕的增大而变化的(我指的是它的宽度)。

移动端image 平板设备端image

笔记本设备image

这些图片有点难看,但在手机上,搜索栏占据了屏幕的大部分宽度,但就 px 而言仍然很小)。在平板电脑和小型笔记本电脑上,搜索栏会变大。但到了一定程度,随着屏幕尺寸的进一步增大,搜索栏就不会再继续变长了。

Flexbox

使用 flex 时,只要在父元素设定 display: flex;,它就会变成一个 “flex 容器”,而它的所有直系子元素都会变成 “flex items”。你可以在 flex 容器上设置几个与 flex 相关的属性,以描述 “flex items” 应该如何排列。此外,你还可以对“flex items” 本身设置一些属性,以将它们的样式与其他柔性项区分开来。 初学者通常不明白,Flex 关系严格来说是父子关系,而不是父孙关系。而不是父子、子孙等关系。你可以拥有本身也是柔性容器的柔性项。这意味着一个元素的显示方式为:flex;,而它的一个子元素的显示方式也为:flex;。 以下是两种最常见的使用 flex 的情况:

  • Flex 可以在相邻或相顶的元素之间创建位置/空间关系。举例来说,如果一行中有几个项目,只需使用一到两个简单的 CSS 属性,就可以在这一行中将它们均匀地分开。
  • 利用 flex,你可以轻松改变同级元素的定位方向。所谓方向,是指水平(行)或垂直(列),反之亦然。例如,将屏幕顶部导航栏中的链接垂直排列在移动版“汉堡🍔”菜单下。

CSS Grid

Flex 有一个缺点,那就是当你试图同时控制两个方向(x 轴和 y 轴)上的元素时。Flex 主要是为沿同一轴(X 轴或 Y 轴)对齐的元素定义属性。要做到这一点,最常见的情况是制作项目网格。

在确保它们大小相同时,可能会遇到麻烦。请参见下图中的示例: image

有了 CSS Grid,只需应用一两个简单的 CSS 属性,问题就迎刃而解了。请看下面代码:

#card-container {
    padding: 20px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 20px;
    justify-content: center;
}

有些人实际上选择使用 CSS Grid 多页面进行布局处理。其实,flex基本可以满足大部分的业务场景。但是,在一些特定场景,使用 CSS Grid 可以让代码变得更加“优雅”。另外,我们也可以在Flex Item中使用 CSS Grid;或者在CSS Grid中使用 flex,这有何不可呢?

媒体查询

在几乎所有的设计中,当屏幕达到一定尺寸时,你都需要让事物发生更大的变化。小屏幕有利于垂直滚动。对于较宽的电脑屏幕,则可以在水平方向容纳更多元素。

使用媒体查询,你可以定义所谓的 “断点”————在这些点上,某些样式将被覆盖,以适应不同的设备大小。 可以先创建移动或桌面用户界面,然后再创建一个断点,在断点上定义新的样式,覆盖现有的样式,以适应你最初没有设计的平台。

让我们以移动设备为例,某些元素应按列排列,但在较大的设备上,这些元素应按行排列。

假设我们选择了 “移动优先设计”,即首先设计移动 UI,然后再考虑响应性,以实现大型设备的设计。如今,这种选择被认为比首先为笔记本电脑/台式机设计更好,因为人们花在手机上的时间比花在电脑上的时间更多,公司更愿意让更多用户满意。

那么,告诉您的应用程序在平板电脑宽度和更大的情况下改变外观的方法基本上就是—通过媒体查询断点—说:“在此像素宽度和更高的情况下,现在将这些项目的组织改为一行”。

如下图所示,这种更改可能只是将 flex 容器的 flex-direction 属性从列改为行:

#flex-container {
    display: flex;
    flex-direction: column;
}
screen and (min-width: 768px) {
    #flex-container {
        flex-direction: row;
    }
}

这段代码意味着id为“flex-container”的元素对于宽度小于768px的屏幕将具有flex-direction: column;,但对于宽度为768px及以上的屏幕,该元素将具有flex-direction: row;

每种设备都有相对标准的像素宽度,因此你可以查找像素宽度,在此设置断点,用以控制从手机到平板电脑、平板电脑到笔记本电脑等不同大小设备的过渡效果。

响应式的图片属性

通常情况下,网站中的图片大小由上述属性组合而成,无需使用其他 CSS。

不过,有时图片的属性并不能随屏幕缩放。在这种情况下,其实有两个属性可以提供一些帮助。

其中一个是aspect-ratio。通过该属性,你可以为图片定义一个首选的宽高比,这样图片就能在不同尺寸的屏幕上始终保持相同的高宽比。

另一个是object-fit,可以为它设定以下这些值:

  • fill:被替换的内容正好填充元素的内容框。整个对象将完全填充此框。如果对象的宽高比与内容框不相匹配,那么该对象将被拉伸以适应内容框、
  • cover:被替换的内容在保持其宽高比的同时填充元素的整个内容框。如果对象的宽高比与内容框不相匹配,该对象将被剪裁以适应内容框;
  • contain:被替换的内容将被缩放,以在填充元素的内容框时保持其宽高比。整个对象在填充盒子的同时保留其长宽比,因此如果宽高比与框的宽高比不匹配,该对象将被添加“黑边”;
  • none:被替换的内容将保持其原有的尺寸;
  • scale-down:内容的尺寸与 nonecontain 中的一个相同,取决于它们两个之间谁得到的对象尺寸会更小一些;

黑边:为屏幕中显示的内容除了正常影像外,两侧或四周多出来的未显示区域。因该区域为黑色,故称之为黑边。黑边的产生是由于原始影像与屏幕的尺寸规格不同所造成的。

对于更复杂的响应行为,请使用JavaScript

JS 在响应式设计中起着至关重要的作用,它可以根据用户交互或设备规格自定义行为,从而实现仅靠 CSS 无法处理的更复杂的变更。

例如可以对更多事件类型(如按钮点击、滚动、拖放等)做出反应,而不仅仅是屏幕尺寸的变化。 也可以利用 JS编写一些逻辑代码,根据想要的任何条件动态调整元素的大小。例如,可以根据用户的设备、行为、偏好或位置来调整内容。

其实 JS 是页面的主要代码;如果 HTML 和 CSS 无法轻松实现某些功能,通常就需要使用 JS 来解决。

结论

实现响应式设计是一个取舍的过程,需要将精巧的 CSS 和策略性的 JavaScript 相融合。通过理解和应用上述七个关键概念,开发人员可以创建出不仅具有视觉吸引力,而且可以适应所有必要设备的网站。

掌握响应式设计的过程就是不断学习和实践的过程;而且随着每个项目的进行,这一过程会变得更加 easy 。

PS:希望这篇文章能让你不再对响应式设计感到迷惑和畏惧。