这一片文章要讲的的是一个很简单的概念:HTML 元素的大小应该由其外部元素决定。 这是因为如此设计的元素能够具有足够的伸缩性,或者说兼容性——能够自适应不同的大小要求。比如说在 PC 端、移动端、平板端能够灵活地调整大小而不需要修改到元素本身。 我在后面会直接用伸缩性来表示这一个要求。

组件和元素的伸缩性

如果使用原生 HTML 编写界面的话那么元素的伸缩性并不需要考虑,因为不存在组件化的功能,同样也就没有了伸缩性的要求。在使用前端框架后的组件化就有了重用的功能,这个组件可能在任何需要的地方使用,那么就有了伸缩性的要求。

所以在后续的内容中我会假设我们在 Vue 中编写我们需要的组件。

我拿 DaisyUI 里的 Phone 组件做一个例子,你可以在 DaisyUI 官网看到这个 Phone 的样子:DaisyUI Phone with color

它是一个苹果手机的样子:

file

看起来十分漂亮。

但打开 DevTool 查看它的样式是嫩巩固看到它使用的是固定数值的 widthheight

file

这样的固定宽高定死了这台手机的大小。如果我们使用 DevToolResponsive Design Mode 模拟出 iPhone 的宽度,它的样式就会开始变得不完美:

file

因为它的屏幕的样式使用了固定的宽高,使得屏幕内容的显示被截断。在上图中能够看到屏幕的宽度超过了手机机身样式的宽度。

同样的另一个例子是我最近在写的一个小项目:nobody-chat,里面有使用到这个手机样式。我想要让这个手机只占据四分之一的屏幕,但由于样式使用了固定的宽高而导致这个手机样式几乎占据了整个移动端的屏幕,就像上图。

上面这个手机样式就是组件伸缩性不好的例子。

让拥有伸缩性

要让它拥有伸缩性的能力也很简单:将组件的大小交给使用到组件的地方。

要做到这一点只需要让组件的宽高变成 100%。假设这个手机组件名为 <Phone />。让它的根元素的 widthheight 都为 100%,同时避免使用固定的宽高样式。

如果我们分析 DaisyUI 的手机样式,就能够看到它的机身的大小完全取决于它的屏幕的大小,它屏幕部分应用的样式为 phone-1

file

如果手动将 phone-1width 增加为 600px,就会变成一台 iPad。并且继续增大为 1000px,你会发现屏幕仍然被截断了:

file

这是因为尽管机身的宽度由屏幕的宽度决定,但机身同样受到它外部的元素的大小限制,使得屏幕的宽度超过了机身的宽度而导致屏幕的内容截断。

所以要让其能够有伸缩性的方式就是让屏幕的大小依赖于机身的大小,让机身的大小依赖于使用它的地方。直接在 DevTool 中操作,设置屏幕的宽高为 100%,设置它的父级元素的宽高为 100%,以及机身的宽高为 100%。然后这个组件就有了伸缩性。

现在你可以修改组件的宿主元素的宽高,组件都将跟着它发生变化,并且屏幕的内容也将始终保持伸缩性。

这个方法也让我的小项目 nobody-chat,使用到的手机样式在 PC 和移动端中能够伸缩为合适的大小。

file

不需要伸缩性

并不是所有的组件都需要伸缩性,如果组件不需要根据不同情况改变大小,那么直接使用固定的宽高也没问题,比如说按钮组件。

DaisyUI 中的普通按钮宽度固定为 48px,还提供了 32px,和 24px 的更小的按钮,可以预见几个数值几乎能够适用于所有的屏幕了。

file