添加元素边框的 3 种 CSS 方法
说到 CSS,有时边框 border
并不是真正的边框 border
。
在本集中,我们将介绍以下两者之间的区别:
border
outline
box-shadow
我们还将讨论在什么情况下可以使用其中一种而不是另一种。
复习 CSS Box 模型
这三种边框方法的主要区别在于它们在元素上的位置以及对元素尺寸的影响。这种行为由 CSS 框模型控制。
-
border
边框恰好是元素的边界,位于 padding 和 margin 之间,它的宽度会影响计算出的元素尺寸 -
outline
轮廓紧靠border
边框,但在border
边框之外,与box-shadow
和margin
重叠,但不影响元素的尺寸 - 默认情况下,
box-shadow
从border
边缘向外延伸,覆盖所定义方向的空间,也不会影响元素的尺寸
border 语法和用法
自网络诞生以来,border 边框一直是设计的标准。
与我们将要介绍的其他两种方法相比,border边框的一个重要区别是,默认情况下border边框包含在元素的计算尺寸中。即使设置了 box-sizing: border-box,border边框仍会被计算在内。
border边框最基本的语法是定义宽度和样式:
border:3px solid;
如果没有定义,默认颜色将是 currentColor
,这意味着它将使用 css 中最近的颜色定义。
不过,还有更多的 border 边框样式可供选择,如果你愿意,还可以使用 border-style
为每一侧定义不同的样式。
请访问 MDN 文档查看所有可用的 border-style
值和示例。
何时使用 border
当可以接受在元素尺寸中计算样式时,border 边框是一个可靠的选择(双关语)。默认样式提供了很大的设计灵活性。
继续阅读,了解只有 border 才能做到的额外提示!
outline 语法和用法
对于 outline (轮廓),要使其可见,唯一需要的属性是提供样式,因为默认值是无:
outline: solid;
与 border 一样,它将通过 currentColor
获得颜色,默认宽度为medium
。
outline
的典型应用是在链接和按钮等交互式元素的:focus
上使用本地浏览器样式。
除非您能提供符合 WCAG 成功标准 2.4.7 “焦点可见 “的自定义 :focus
样式,否则出于无障碍访问的目的,应允许出现这种特殊应用。
就设计而言,outline
的一个常见问题是它无法从任何border-radius
样式继承曲线。
何时使用outline
如果不想影响元素的尺寸,也不需要它遵循border-radius
,那么使用outline
可能是可取的。它与 border
使用相同的样式值,因此可以获得相似的外观。
box-shadow 语法和用法
box-shadow
所需的最少属性是 x
轴和 y
轴的值以及颜色:
box-shadow: 5px 8px black;
可选择添加第三个单元来创建blur
模糊效果,添加第四个单元来添加spread
扩散效果。
请观看我在 egghead 上演示的 4.5 分钟视频,进一步了解扩展语法以及使用 box-shadow
的技巧。
要使用它创建边框,我们要将 x
轴和 y
轴值以及模糊度blur
设为 0,然后为spread
设置一个正数::
box-shadow: 0 0 0 3px blue;
这将在元素周围创建一个边框的外观,甚至可以遵循应用的border-radius
:
何时使用 box-shadow
特别是当您想在不引起布局偏移的情况下为边框设置动画时,您可能更喜欢使用 box-shadow
。下一节将举例说明这种情况。
此外,由于 box-shadow
可以分层,因此它是一个非常适合用来增强布局效果的工具。
不过,它无法完全模仿 border
和outline
提供的某些样式。
把一切组合起来
以下是几种可能需要使用border
替代方案的实际情况。
按钮边框
在为有边框和无边框按钮提供样式时,以及它们彼此相邻的情况下,真实border
成为问题的常见情况。
典型的解决方案通常是增加无边框按钮的尺寸,使其等于border-width
。
根据我们的新知识,另一种解决方案是使用 box-shadow
和 inset
关键字,将伪边框置于按钮内部:
请注意,您的填充必须大于border-width
,以防止文本内容重叠。
另外,也许您想在 :hover
或 :focus
时添加边框。如果使用真正的边框,由于边框会短暂增加这些状态下的尺寸,因此会出现布局变化带来的不理想的视觉跳跃。
在这种情况下,我们可以使用box-shadow
来创建伪边框,这样就不会增加真实尺寸,而且我们还可以使用transition
效果将其制作成动画:
以下是上述示例的精简代码:
button {
transition: box-shadow 180ms ease-in;
}
button:hover {
box-shadow: 0 0 0 3px tomato;
}
升级 CSS 调试方法
一个经典的 CSS 笑话是,要想弄清 CSS 问题,尤其是溢出滚动或定位问题,就必须添加:
* { border:1px solid red; }
这将为每个元素添加红色边框。
但正如我们已经了解到的,这也会影响它们的计算尺寸,从而可能意外地给你带来额外的问题。
取而代之的是使用
* { outline: 1px solid red; }
使用 border
的一个潜在后果是,一旦重新绘制内容,就会增加滚动条。而使用outline
则不会出现这种副作用。
此外,你很可能已经为元素使用了border
,因此普遍改变border
会导致布局移动,这肯定会带来新的问题。
题外话:浏览器开发工具也发展出了更复杂的方法来帮助你识别元素,Firefox 甚至添加了 “scroll”(滚动)和 “overflow”(溢出)标签,这对调试溢出很有帮助。我鼓励你花些时间了解更多 DevTool 功能!
确保可见焦点
在可访问性方面,Windows 高对比度模式(WHCM)用户可能是您不知道的一种情况。
在这种模式下,你所提供的颜色会被剥离成一个缩小的高对比度调色板。并非所有 CSS 属性都是允许的,包括box-shadow
。
一个实际影响是,如果删除了 :focus
时的outline
并用 box-shadow
代替,WHCM 的用户将不再获得可见焦点。
要消除这种负面影响,可以在 :focus
上应用透明 outline :
button:focus { outline: 2px solid transparent; }
outline
和 box-shadow
的陷阱
由于outline
和 box-shadow
位于 box model 的边框之外,因此可能会遇到的一个问题是,它们会在视口边缘消失。因此,如果你希望元素保持可见,可能需要为元素添加 margin
或为主体添加 padding
作为对策。
它们的位置也意味着它们可以被诸如 overflow: hidden
或使用 clip-path
等属性剪切掉。
额外提示:渐变边框
按照承诺,这里有一个额外提示,在我们讨论过的方法中,只有border
可以做到。
border-image
是一个经常被遗忘的边框相关属性。当试图将其用于实际图像时,语法可能有点奇怪。
但它还有一个隐藏的功能–它还允许你创建渐变边框,因为 CSS 渐变在技术上也是一种图像:
这就需要定义常规的边框宽度和样式(尽管无论样式值如何,它都只会显示为solid),然后再定义border-image
属性,该属性可以使用渐变语法,但只需增加一个附加值。梯度后面的数字是slice
值,对于我们的梯度,我们可以简单地使用 1
,这样基本上就不会改变梯度的大小/变形。
div {
border: 10px solid;
/* simplified from preview image */
border-image: linear-gradient(to right, purple, pink) 1;
}
如果只在一边添加边框,请确保先将其他边框设置为零,否则某些浏览器仍会在所有边框上添加边框:
div {
border-style: solid;
border-width: 0;
border-left-width: 3px;
/* border-image */
}
缺点是这些边框不遵循border-radius
,所以如果你需要一个遵循border-radius
径的解决方案,可以使用 Inspector 来查看 ModernCSS 主页上的卡片是如何添加渐变效果的