大多数设计师都熟悉响应式设计,这是一种基于列的布局方法,通过固定的断点来适应所有屏幕尺寸。然而,我们可以通过现代 CSS 布局超越刻板的结构,打造灵活且动态的设计,使其能够无缝地适应不同的屏幕尺寸。
在讨论布局时,设计师和开发者对于网格等内容有不同的思维模式,这导致了我们在协作中产生了很多误解。
本文不是关于完美的交接(我仍然怀疑这样的事情是否存在),而更多地是关于理解彼此的工具及其限制,以找到共同的基础进行交流和协作。
-
响应式基于列的设计与现代 CSS 布局
-
作为设计师理解 CSS Flexbox
-
作为设计师理解 CSS Grid
-
断点:我们还需要它们吗?
首先让我们了解一下我们的起点。作为一个 UI 设计师,你可能更熟悉经典的列网格设置,它由列、间距和边距组成,你可以在其中放置元素。这个网格作为你设计的基础,提供了一个结构化的框架。
这种响应式设计方法的核心在于断点,它们由 CSS 媒体查询定义,并且对于适应不同的屏幕尺寸至关重要。网站的结构在这些预定义的点上动态调整:元素可能重新排列,紧凑的导航菜单可能展开,或者文本大小可能调整以提高可读性。这种灵活性确保设计在各种设备上都能够功能正常且美观。
在实现这些设计时,像 Bootstrap 或 Foundation 这样的 CSS 框架是常用的选择,你可能也听说过 Tailwind。它们提供了预设计的组件和网格系统,简化了创建响应式网页布局的过程。
虽然这些框架在几年前创建响应式设计时是必不可少的,但如今我们仍然可以使用它们,但并不真正需要,因为现代 CSS 布局技术的出现。
📍 小提示: 现在,许多框架在底层使用 Flexbox 和/或 CSS Grid,比起最初的刻板的基于列的布局,它们变得越来越灵活。
简而言之:在传统的响应式基于列的设置中,针对不同的屏幕尺寸进行设计更改是通过对一组固定断点做出反应来实现的。换句话说,它涉及向外看并根据外部因素进行调整,比如改变视口大小。
使用 Flexbox 和 CSS Grid 的现代 CSS 布局可以采用更加内向的方法,有时被称为内在设计。这意味着我们的设计不仅适应视口大小,还适应内容本身和可用空间。
因此,与其将项目放置在由视口定义的静态网格中,这种内在的方法使我们能够更好地控制内容在不同空间中的行为方式。它结合了固定和灵活的元素,提供了丰富的微调空间,例如定义最小和最大尺寸等。
这个概念对于设计师来说可能需要一些时间才能理解,因为它涉及到对 CSS 的基本理解。所以,让我们开始吧!
📍 小提示: 我强烈推荐观看 Jen Simmons 在她的 Layout Land 频道上的免费视频,这些视频对这个主题进行了非常好的解释!
我们主要使用的 CSS 工具是 Flexbox 和 CSS Grid。它们可以单独使用或结合使用。我们可以使用它们来设置组件以及整体布局。
我们主要使用的 CSS 布局工具是 Flexbox 和 CSS Grid。它们可以单独使用或结合使用,我们可以使用它们来设置组件以及整体布局。
📍 小提示: 还要注意 容器查询,这是 CSS 布局家族的最新成员。我写了一篇关于在 Figma 中如何规划容器查询的文章。
使用 Flexbox(CSS 弹性盒布局是其正式名称),我们可以将元素整齐地堆叠在一起,并控制它们的对齐方式,同时精确调整它们的行为和大小,以适应可用空间并适应内容的变化。我们可以使用 Flexbox 来设置我们的组件、整个组或页面,这都与嵌套有关。
CSS Flexbox 使用两个主要元素:父容器和子元素。
这是应用了 display: flex;
的外部包装器。这个声明将容器转换为一个 Flex 容器,并将其直接子元素转换为 Flex 项目。在 Flex 容器内部,你可以控制 Flex 项目的方向(行或列)、换行方式以及它们在主轴上的对齐方式或在交叉轴上的对齐方式。换句话说,父容器控制着整体规则,因此所有子元素都遵循相同的规则。
这些是 Flex 容器内部的元素,也就是直接子元素。虽然它们仍然遵循父容器的整体规则,但它们具有一些个体的自由。我们可以控制它们的增长(如何扩展以填充容器)、收缩(当空间不足时如何减小尺寸)和基准(在增长或收缩之前的默认尺寸)。还有一些更高级的设置,比如将单独的项目与其他项目对齐。
📍 小提示: 你可以在我的完整 CSS Codepen 集合 中找到非常简化的示例,涵盖了所有这些概念。
因此,对于像这个卡片这样的简单设置,你可以看到它只是一个简单的 Flexbox;卡片是父容器,里面有三个子元素,图像、标题和文本,都沿着一个方向排列,它们之间的距离很容易调整。
但对于更复杂的设计,比如下面这个导航栏,其中包含不同的元素组合在一起,距离、方向和行为各不相同,我们需要嵌套 Flexbox。因此,每个嵌套的 Flexbox 都是其直接父级的子元素,从上方获取一般的位置(例如导航栏的导航),但也对其直接子元素制定新的规则...就像在任何一个家庭中一样。
这听起来熟悉吗?这与在 Figma 中使用自动布局或在 Penpot 中使用弹性布局完全相同,因为它们都基本上反映了 Flexbox。当你探索开发模式或使用检查工具时,这种直接的关联变得明显起来。为了更深入地了解这个主题,我制作了一个免费视频,探讨了自动布局在 Figma 中如何对应 Flexbox,包括我们遇到的限制。
重要的是要理解,Flexbox 是一种一维设计方法,将每个项目放置在一条线上。在许多情况下,这是完全可以的,但它无法提供具有行和列的网格布局的控制。如果您想要类似网格的设计控制,您需要使用类似 CSS Grid 的二维布局方法。
没有对错之分;这取决于您要构建的内容。它们可以很好地协同工作。
我喜欢 CSS Grid;它非常强大,您几乎可以用它构建任何东西。是的,真的是任何东西 - 重叠、子网格对齐,甚至是不定义任何内容,它会自动为您创建一切。这太神奇了。然而,这也可能会让人感到非常压力山大,而且在大多数情况下,我们并不会创建非常花哨的布局(但您绝对可以!)。CSS Grid 的好处在于,我们可以创建最简单的布局结构,例如经典的列网格,并通过更灵活的方式打开布局,以便在构建超出标准网格感知的创意设计时进行构图和调整大小。CSS Grid 将为您提供支持。
如果我们将 Flexbox 想象成一串串的珠子,可以水平或垂直排列。那么 CSS Grid 就像是将这些珠子放入便当盒中,我们可以自由地将它们排列在任何行或列中。就像是那种可以移动隔板并连接隔间的酷酷的便当盒。它甚至会自动扩展。
如果 Flexbox 是一串串的珠子,那么 CSS Grid 就像是一个超级灵活的便当盒,您可以将珠子放入其中。
让我们逐步了解 CSS Grid 结构的细节:
作为 UI 设计师,我们通常将布局网格视为具有列的容器,然后将项目放置在这些列上或跨列。但是在 CSS Grid 中,情况有所不同。我们仍然有一个容器,但网格本身由创建网格单元的线组成。默认情况下,网格项按顺序放置,遵循其 HTML 顺序。但是,我们可以使用 CSS Grid 的坐标线来精确控制它们的水平和垂直位置。
这使我们能够创建网格区域,实现重叠和更复杂的布局结构等效果。此外,我们当然可以在容器中添加边距和行之间的间隔。
这是一个 Codepen;如果您想更好地理解这一点,请尝试调整定位。我有一篇关于 CSS 网格的详细文章,其中更详细地解释了定位。
我们的列和网格单元不一定都需要相同的大小;我们可以根据需要进行自定义。这包括固定大小或使用“fr 单位”,即将可用空间分成分数单位。通过使用 fr 单位,我们可以均匀分配剩余空间或调整比例 - 例如,一个单元格为 2 fr,另一个单元格为 1 fr。
当尺寸发生变化时,所有内容都会自动调整:固定元素保持其大小,而 fr 单位根据剩余空间重新分配。
这里有一个小的 Codepen,您可以在其中尝试使用 CSS 中的不同单位:
到目前为止,我一直在讨论显式网格,其中我们作为设计师明确定义行和列。然而,当我们不定义每个单元时,CSS Grid 也可以工作;浏览器会根据内容自动生成网格。这被称为隐式网格,在处理动态或未知内容(例如博客文章或随时间变化的产品列表)时非常有用。
显式方法对我们作为 UI 设计师来说更自然,而隐式方法则是我们在浏览器中主要见证的行为。因此,我们需要超越我们的 UI 软件进行思考,并作为设计师和开发人员进行协作。
CSS Grid 也可以嵌套。例如,如果您有一个包含标题、侧边栏和内容区域的总体布局,并希望进一步构造该内容,您可以轻松地在其中嵌套另一个 CSS Grid。根据您的要求,此嵌套网格可以是隐式的或显式的。
为了实现完美对齐的设计,CSS Grid 的子网格功能允许您在整个布局中创建一致的网格结构。
我们已经介绍了 CSS Grid 的基础知识,但它的对齐方式、调整方式以及如何组合和嵌套元素等方面还有更多的功能。因此,深入了解其复杂性将会很有趣。此外,我强烈推荐阅读这篇文章以获取更多信息:Gridless.design
虽然 CSS Grid 提供了无限的可能性,但保持专注并尽可能简单以创建可维护和可扩展的产品非常重要,这是我们在大多数情况下所需要的。因此,在许多项目中,您可能希望坚持使用每个人都同意的基本列网格,这完全没有问题!我们可以使用 CSS Grid 的最简单设置。但是,当创意呼唤时,您现在知道该去哪里了。
Figma 提供了网格功能,但仅限于标准列。虽然我们有自动布局(对应 Flexbox),但目前 Figma 缺乏代表 CSS Grid 的功能,尽管我非常欣赏 Figma。您可以查看我关于如何在 Figma 中处理此问题的课程。
您可能还想探索一个新兴的明星,Penpot,这是一款免费的 UI 设计软件,提供了 Flex 布局和 CSS Grid 功能(即将发布)。您可以在这里预览,它非常令人印象深刻(而且免费!)。
这不是选择一个而不选择另一个,Flexbox 和 CSS Grid 都是 CSS 家族的一部分,它们可以很好地协同工作。
这不是选择一个而不选择另一个,Flexbox 和 CSS Grid 都是 CSS 家族的一部分,它们可以很好地协同工作。
大多数情况下,组件将使用 Flexbox 进行设置,而 CSS Grid 将控制整体布局。但是,完全可以使用 Flexbox 来构建整个页面。您可以混合使用;有时候,两种方法都很好,而其他时候,一种方法可能是更好的解决方案。事实上,您甚至可能会发现组件使用 CSS Grid(我个人喜欢这种方法)和/或 Flexbox 这些天,任何方法都可以。没有正确或错误的选择;它们根据您的具体情况,结合一维或二维布局的需求,无缝地相互补充。
作为 UI 设计师,您可以将琐碎的决策留给前端开发人员。您的重点是理解为什么会做出某些选择,并在设计时考虑现代 CSS 的潜力和限制。请记住,您在 Figma 或 Penpot 中构想的内容可能并不总是能直接转化为浏览器中的效果。您没有做错任何事情;这只是创意过程的一部分。设计和开发之间的合作至关重要!
“旧”方式是使用具有固定列的响应式网格,其中我们的设计会在特定断点处“断裂”为新版本。在这些断点处,网格布局本身可以发生变化,从不同数量的列到更改间距或边距。我们还可以重新排列项目在网格中的位置或显示和隐藏特定项目。此外,我们可以选择显示不同的版本,例如汉堡菜单变为链接菜单,并且文本大小可能会在这些断点之间变化。
这种更为严格的响应式布局方法通常使用框架,并且通常有相应的文档提供必要的信息。例如,使用像Bootstrap这样的框架,文档将包括有关列数、间距宽度和断点的详细信息。因此,这使得我们作为 UI 设计师可以很容易地在工具如 Figma 或 Penpot 中进行镜像。
通过现代 CSS 布局,我们的设计方法可以变得更加直观,使设计能够在不断需要断点的情况下自适应。这意味着布局可以在很多情况下自动重新组织。
然而,仍然会有一些情况下你可能会发现需要使用断点。与其依赖一组固定的断点(尽管你仍然可以这样做,我将很快讨论这个问题),你可以检查你的设计,并以更大的灵活性确定断点。
更改布局尽管现代 CSS 本身已经做得非常好,但你可能希望为更“激进”的布局更改设置断点,例如更改网格设置、显示或隐藏元素,或以不同于其自然流程的方式分布元素。
更改组件布局一个例子可能是从汉堡菜单更改为链接菜单的导航更改。这样,我们可以找到我们想要设置断点的最佳位置。
**📍 提示:**这也可以通过容器查询非常优雅地解决。
更改排版排版是一个更复杂的领域。简单来说,理论上我们也可以在这里设置单独的断点,但通常更合理的做法是为你的排版使用一组固定的断点。这种方法简化了流程,确保我们的排版在不同的屏幕尺寸上保持一致和可读。我非常想听听你在这方面有其他的方法!
使用 CSS Clamp 的其他方法:除了断点之外,我们还可以利用 CSS 中的 clamp() 函数,使我们的排版在指定范围内自适应,确保其响应性。这种方法允许文本大小在最小和最大值之间调整,独立于断点考虑一般视口宽度。
然而,使用 clamp()
需要与开发团队密切合作,因为需要考虑性能和可访问性问题,并且需要进行更多的测试。因此,这是一个很好的工具,但它需要适应你特定的设置和项目。
我面临的一个挑战是在 CSS 布局提供的各种可能性和自由之间带来一些秩序。我发现首先坐下来仔细考虑项目及其范围非常重要。
我们是在创建一个一次性的、非常花哨的艺术页面吗?那么,你可能希望充分利用 CSS 布局的魔力。Jen Simmons 的惊人创意示例展示了你可以通过现代 CSS 布局实现的效果。你可能会完全放弃传统的断点,让浏览器决定布局,或者对每个项目仔细考虑每个断点。
请记住,这种方法可能不适用于你的整个网站;它可能只适用于主页或英雄区域,你希望在这里实现这种图形设计的活力。
在这种情况下,我会在 Figma 或 Penpot 中设置一些固定的屏幕作为图形表示。然后,需要一个非常熟练的前端开发人员(以及适当的预算!)密切合作。重点是尽早进入浏览器;在 Figma 或 Penpot 中过度规划任何行为是没有意义的。
灵活性是可扩展产品的关键,但结构也是如此。虽然现代 CSS 布局允许通过让浏览器决定流程来实现更流畅的设计,但创建可扩展的设计通常需要设置更清晰的规则以保持事物的可管理性。将一些魔力放入结构化的盒子中,不是为了使设计变得乏味,而是为了提供坚实的基础。
Brad Frost 在设计系统中处理网格的文章绝对是太棒了。我真的相信这是我们可以很好地合作的一种方法,因为这种使用固定布局模式的方法在 Figma(由于缺乏 CSS Grid 的限制)或 Penpot 中与在 CSS 中一样有效。我个人也会选择一些固定的断点来设置整体布局和排版,以简化生活。重要的是,我们仍然可以在需要时轻松地摆脱这个系统。
我在 Figma 中有一门详细的课程介绍了我如何处理这个问题。此外,请确保订阅我的通讯,以便我可以向您发布更多文章。我目前正在探索关于这个主题的更多想法。
让我非常明确:这篇文章不是关于设计师需要编码。如何在 CSS 中实现这一点的决策,不应该由设计师做出;它始终应该由前端开发人员,这个领域的专家来决定!因此,这不是要在设计中提供代码解决方案。但是,如果我们在设计时了解 CSS 的能力和限制,那么我们就可以与开发团队进行更好、更理解的合作和对话...而且这样做非常有趣!
如何在 CSS 中实现这一点的专业知识始终掌握在前端开发人员手中。这不是要在设计中提供代码解决方案;它是为了在设计时了解 CSS 的能力和限制,以促进更好的合作和有意义的对话。
正如前面提到的,要密切关注容器查询。同时,作为 UI 设计师!我写了一篇关于容器查询的文章,介绍了它们是什么以及如何在 Figma 中进行规划。