移动优先和桌面优先的状态

举报
搞前端的半夏 发表于 2021/10/24 23:32:00 2021/10/24
【摘要】 ​您是否经常考虑实施移动优先还是桌面优先的方法?最近,我在 Twitter 上分享了一项关于移动优先与桌面优先的调查,结果很有趣。总票数为 648,统计如下:移动优先:33.3%桌面优先:21.9%两者的混合:24.7%在本文中,我将与您探讨每种方法的含义,我将尝试发现并查看它是否仍然适用于今天,以及当今响应式设计的一些技巧。简介:每一个是什么意思?术语“移动优先”意味着在开发网站时,我们首...


您是否经常考虑实施移动优先还是桌面优先的方法?最近,我在 Twitter 上分享了一项关于移动优先与桌面优先的调查,结果很有趣。

总票数为 648,统计如下:

移动优先:33.3%
桌面优先:21.9%
两者的混合:24.7%
在本文中,我将与您探讨每种方法的含义,我将尝试发现并查看它是否仍然适用于今天,以及当今响应式设计的一些技巧。

简介:每一个是什么意思?
术语“移动优先”意味着在开发网站时,我们首先开始为较小的视口尺寸编写 CSS,然后使用 CSS 媒体查询来改变较大视口(例如:平板电脑或台式机)的体验。

考虑以下示例。

.section {
padding: 2rem 1rem;
}

@media (min-width: 62.5rem) {
.section {
display: flex;
align-items: center;
gap: 1rem;
padding: 4rem 2rem;
}
}

我们有一个padding用于移动的部分,当视口足够大时,它应该是一个具有更大填充的 flex 包装器。

这是一个简化的例子。想象一下整个网站或网络应用程序的规模。

另一方面,当我们使用桌面优先时,情况正好相反。

.section {
display: flex;
align-items: center;
gap: 1rem;
padding: 4rem 2rem;
}

@media (max-width: 62.5rem) {
.section {
display: block;
padding: 2rem 1rem;
}
}

我们首先为较大的视口大小编写 CSS,然后使用 CSS 媒体查询为较小的视口更改 CSS。

移动优先作为工作流程看起来如何?
您是否打开 DevTools 并从那里开始开发,甚至无需查看桌面大小?还是应该同步进行?即:同时为桌面编写 CSS 移动优先和增强?

我可以想到两种情况:

处理移动设备的完整页面。完成后,我们开始增强更大的尺寸。
并行工作。我的意思是,从移动优先开始,然后针对更大的尺寸进行增强,分别处理每个部分/组件。
你通常使用哪一种?对我来说,第二个更好。我更喜欢单独处理每个组件/部分,以便我可以专注于它。此外,这个过程将减少在编写 CSS 时犯的错误。

当您开始移动优先然后为桌面增强时,您可能会为平板电脑和桌面重写 CSS。考虑下图:

我们以英雄部分为例。

.hero {
display: flex;
align-items: flex-end;
background-image: url(‘hero.jpg’);
background-size: cover;
background-repeat: no-repeat;
}

.hero__title {
font-size: 1rem;
}

.hero__thumb {
display: none;
}

@media (min-width: 60rem) {
.hero {
align-items: center;
background-image: initial;
background-color: #7ecaff;
}

.hero__title {
font-size: 2rem;
}

.hero__thumb {
max-width: 320px;
display: block;
}
}

在移动设备上,英雄有一个背景图片,而在桌面上,背景是纯色的,并且有一个图片位于最右边。如您所见,CSS 是移动优先的,除了font-size和之外,我们没有太多覆盖background。

导航呢?移动优先的方法会是什么样子?这里是。

.nav {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow-y: auto;
padding-top: 2rem; /* Space for the toggle */
}

.nav__toggle {
position: absolute;
right: 1rem;
top: 1rem;
}

.nav__item {
padding: 1rem;
display: block;
}

.nav__item:not(:last-child) {
border-bottom: 1px solid #fff;
}

/* Desktop styles */
@media (min-width: 60rem) {
.nav {
position: initial;
width: initial;
height: initial;
overflow-y: initial;
display: flex;
align-items: center;
padding-top: 0;
background-color: blue;
}

<span style="color:#445588"><strong>.nav__toggle</strong></span> {
    display: <span style="color:#0086b3">none</span>;
}

<span style="color:#445588"><strong>.nav__item</strong></span>:hover {
    color: <span style="color:#008080">blue</span>;
    background-color: initial;
}

<span style="color:#445588"><strong>.nav__item</strong></span>:not<strong>(</strong>:last-child<strong>)</strong> {
    border-bottom: <span style="color:#009999">0</span>;
    border-left: <span style="color:#009999">1px</span> <span style="color:#0086b3">solid</span> <span style="color:#009999">#fff</span>;
}

}

您是否看到其中的 CSS 覆盖量与桌面视图的 CSS 相结合?这不是一件好事。

不仅如此,这也可能导致 CSS 特异性问题。假设开发人员希望使用以下 CSSborder-bottom从 中删除.nav__item。

.nav__item {
border-bottom: 0;
}

它不会起作用,因为:not在这种情况下伪类具有更高的特异性。

仅当您使用以下其中一种方法时,它才有效:

.nav .nav__item {
border-bottom: 0;
}

/* Or */

.nav__item:not(:last-child) {
border-bottom: 0;
border-left: 1px solid #fff;
}

桌面首先看起来像工作流程吗?
基于之前的相同示例,我们将翻转事物并探索桌面优先解决方案。

.nav {
display: flex;
align-items: center;
background-color: blue;
}

.nav__toggle {
position: absolute;
right: 1rem;
top: 1rem;
}

.nav__item {
padding: 1rem;
display: block;
}

.nav__item:hover {
color: blue;
background-color: initial;
}

.nav__item:not(:last-child) {
border-bottom: 0;
border-left: 1px solid #fff;
}

@media (max-width: 25rem) {
.nav {
display: block;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow-y: auto;
padding-top: 2rem; /* Space for the toggle */
}

<span style="color:#445588"><strong>.nav__toggle</strong></span> {
    display: <span style="color:#0086b3">block</span>;
}

<span style="color:#445588"><strong>.nav__item</strong></span>:not<strong>(</strong>:last-child<strong>)</strong> {
    border-bottom: <span style="color:#009999">1px</span> <span style="color:#0086b3">solid</span> <span style="color:#009999">#fff</span>;
}

}

使用这种方法,我们的覆盖次数比使用移动优先的方法少。这不是很有趣吗?原因是通过使用max-width媒体查询,我们将特定设计范围限定为特定视口宽度。

我们不是为移动优先编写 CSS,然后为桌面覆盖它们,而是相反。

这是并排的视觉比较。请注意,桌面优先看起来更短并且没有重复(嗯,它有,但有一点)。

提示:确保测试布局闪烁。

范围样式:更好的方法
就在这里。对我来说,我宁愿不坚持特定的方法。相反,我喜欢将它们混合在一起。这意味着,我们需要首先编写基本样式,然后我们开始考虑移动和桌面会发生什么。我喜欢 Elad Shechter 在这篇很棒的文章中首先称其为基础的方式。

让我们举一个抽象的例子。

.nav {
/* Base styles: not related to any viewport size */
}

/* Desktop styles */
@media (min-width: 800px) {
.nav { }
}

/* Mobile styles */
@media (max-width: 799px) {
.nav { }
}

如您所见,样式是根据视口大小确定的。这意味着我们不需要做任何覆盖。这种方法对于在移动设备和桌面设备上看起来完全不同的组件很有用。在我们的例子中,它是导航。

然而,对于像 a 这样的东西

,使用混合方法是没有用的,因为移动和桌面风格非常相似。

.section {
padding: 1rem;
}

/* Desktop styles */
@media (min-width: 800px) {
.section {
padding: 2rem 1rem;
}
}

我如何处理响应式设计
在某些时候,我觉得移动优先与桌面优先的讨论不会那么重要。现代 CSS 为我们提供了使用无媒体查询 CSS 构建响应式布局的方法。

话虽如此,我认为移动/桌面优先的争论将只是关于在特定视口尺寸(例如:移动设备上的导航切换按钮)显示或隐藏某些元素,除了视口尺寸差异很大的复杂组件。

让我们举一个现实生活中的例子来演示这些概念。

在移动设备和桌面设备上有很多不同的组件是标题和导航。其余的有一些细微的差别。对于标题,我们可以使用媒体查询min-width和max-width媒体查询的混合来确定每个设计所需的视口大小。

但是,英雄部分和文章网格可以有一个基本样式,然后min-width可以在必要时使用。

你看到这种设计的想法吗?这里没有什么严格的。这是关于我们手头的设计。好的,让我们展示更多细节。

如果标题和导航采用移动优先的概念,我们最终会出现大量的 CSS 覆盖(又名重复)。这不好。这是我想象标题和导航的 CSS 的方式:

.header {
/* Base styles */
}

/* Desktop styles */
@media (min-width: 1000px) {
.nav__toggle,
.nav__close {
display: none;
}
}

/* Mobile styles */
@media (max-width: 999px) {
.nav {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: #4777dB;
}
}

对于英雄部分,我们可以使用 flexbox 来处理行与列的样式,也可以用于重新排序或移动元素。

<section class=“hero”>
<div class=“wrapper”>
<img src=“thumb.jpg” alt="" />






.hero {
display: flex;
flex-direction: column;
}

@media (min-width: 1000px) {
flex-direction: row;
}

@media (max-width: 999px) {
.hero__thumb {
order: -1;
}
}

请注意,我order: -1通过使用max-width媒体查询确定范围来编写了唯一一次。我可以做这样的事情:

.hero__thumb {
order: -1;
}

@media (min-width: 1000px) {
.hero__thumb {
order: initial;
}
}

但是你看到重复了吗?此外,请注意使用orderin flexbox,因为视觉顺序与 HTML 源(DOM)中元素的顺序不匹配。

这是一个可视化图表,解释了我的过程。

避免双断点媒体查询
对min-width和max-width媒体查询使用相同的值可能会导致难以注意到/调试的问题。

@media (max-width: 500px) {
.nav {
display: none;
}
}

@media (min-width: 500px) {
.nav__toggle {
display: none;
}
}

这些媒体查询对您来说可能不错。但是,在 99% 的情况下,您会忘记测试一个重要的断点:500px,即两个断点之间 1 像素的间隙。在这个断点处,导航和切换都不可见。

在 DevTools 移动模式下,如果不手动输入 500px 媒体查询的值,则很难调试 1 像素。为防止出现此问题,请避免在两个媒体查询中使用相同的值。

@media (max-width: 499px) {
.nav {
display: none;
}
}

@media (min-width: 500px) {
.nav__toggle {
display: none;
}
}

这个问题是从我的Debugging CSS book,第 43 页借来的。

设计师的移动优先
我自己也是一名设计师,出于不同的原因,我不喜欢设计移动优先:

这是限制性的,很难发挥创意。
处理大高度的设计很烦人,您将不断上下滚动。
另一方面,设计桌面优先要好得多,至少对我而言。它为我提供了一种快速尝试和试验想法的方法,而且我无需上下滚动即可看到整个设计的更广阔的视野(如果我正在设计移动优先)。

我们可以先从桌面开始,然后更改移动设计。从那里开始,我们有了一个很好的起点,我不介意将其余页面放在移动优先位置。然而,对于一个全新的项目,我不喜欢开始设计移动优先。

现代 CSS 减少了考虑移动优先与桌面优先的需要
现在写 CSS 再好不过了。我们有许多当前和即将推出的 CSS 功能,它们将使响应式设计更容易实现。

弹性盒包装
在他的文章如何制作无媒体查询的响应式卡片组件 中,Geoffrey Crofte 探讨了如何在不使用媒体查询的情况下制作响应式卡片组件。我会解释它的基本概念,你可以阅读文章了解更多细节。

当设置一个固定flex-basis值,并允许item在需要时增长和缩小时,这可以实现一个无媒体查询的组件。

以下示例说明了当空间不足时卡片的外观。

CSS 网格 Minmax()
感谢 CSS 网格,我们可以拥有不依赖于 CSS 媒体查询的响应式网格布局。考虑以下示例:

.wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 1rem;
}

这是一个响应式网格,为每个项目提供最小宽度200px. 如果没有 CSS 网格,我们将需要使用媒体查询根据视口大小更改宽度。

在本文中了解有关 CSS 网格 minmax() 的更多信息。

视口单位和比较函数
将 CSS 视口单元与 CSS 比较功能结合使用可以减少更改字体大小、填充、边距和某些元素大小等内容的需要。

.title {
font-size: clamp(16px, (1rem + 5vw), 50px);
}

.hero {
padding: clamp(2rem, 10vmax, 10rem) 1rem;
}

.sidebar {
flex-basis: max(30vw, 150px);
}

容器查询
您知道CSS 容器查询现在在 Chrome Canary 的标志后面可用吗?有了它们,我们可以在不使用任何媒体查询的情况下做很多事情。

考虑以下示例:

这是一个基于容器宽度的响应式分页。不需要媒体查询!

.wrapper {
contain: layout inline-size;
}

@container (min-width: 250px) {
.pagination {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}

.pagination li:not(:last-child) {
margin-bottom: 0;
}
}

@container (min-width: 500px) {
.pagination {
justify-content: center;
}

.pagination__item {
display: block;
}
}

查看Chrome Canary 上的演示。

这只是开始。正如您刚刚看到的,现代 CSS 允许我们在不使用媒体查询的情况下创建响应式布局。所以问题是,我们是否需要考虑是否选择移动优先还是桌面优先?

我希望你喜欢这篇文章。谢谢阅读!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。