高级样式效果

本文充当技巧盒,介绍了一些有趣的高级样式功能,例如框阴影、混合模式和滤镜。

¥This article acts as a box of tricks, providing an introduction to some interesting advanced styling features such as box shadows, blend modes, and filters.

先决条件: HTML 基础知识(研究 HTML 简介)和 CSS 工作原理的概念(研究 CSS 第一步)。
目标: 了解如何使用现代浏览器中提供的一些高级样式效果。

盒子阴影

¥Box shadows

box-shadow 允许你将一个或多个阴影应用到元素的框。与文本阴影一样,框阴影在各种浏览器中都得到很好的支持,包括 IE9+ 和 Edge。旧版 IE 版本的用户可能只需要应对没有阴影的情况,因此只需测试你的设计以确保你的内容在没有阴影的情况下也清晰可见。

¥box-shadow allows you to apply one or more drop shadows to an element's box. Like text shadows, box shadows are supported pretty well across browsers, including IE9+ and Edge. Users of older IE versions might just have to cope with no shadows, so just test your designs to make sure your content is legible without them.

你可以在 box-shadow.html 找到本节中的示例(也可以参见 源代码)。

¥You can find the examples in this section at box-shadow.html (see the source code too).

一个简单的盒子阴影

¥A simple box shadow

让我们看一个简单的例子来开始吧。首先,一些 HTML:

¥Let's look at a simple example to get things started. First, some HTML:

html
<article class="simple">
  <p>
    <strong>Warning</strong>: The thermostat on the cosmic transcender has
    reached a critical level.
  </p>
</article>

现在是 CSS:

¥Now the CSS:

css
p {
  margin: 0;
}

article {
  max-width: 500px;
  padding: 10px;
  background-color: red;
  background-image: linear-gradient(
    to bottom,
    rgb(0 0 0 / 0%),
    rgb(0 0 0 / 25%)
  );
}

.simple {
  box-shadow: 5px 5px 5px rgb(0 0 0 / 70%);
}

这给了我们以下结果:

¥This gives us the following result:

你会看到 box-shadow 属性值中有四项:

¥You'll see that we've got four items in the box-shadow property value:

  1. 第一个长度值是水平偏移 - 阴影从原始框向右偏移的距离(如果值为负,则向左偏移)。
  2. 第二个长度值是垂直偏移 — 阴影相对于原始框向下偏移的距离(如果值为负,则为向上偏移的距离)。
  3. 第三个长度值是模糊半径 - 应用于阴影的模糊量。
  4. 颜色值是阴影的基色。

你可以使用任何有意义的长度和颜色单位来定义这些值。

¥You can use any length and color units that would make sense to do so to define these values.

多个盒子阴影

¥Multiple box shadows

你还可以在单个 box-shadow 声明中指定多个框阴影,并用逗号分隔它们:

¥You can also specify multiple box shadows in a single box-shadow declaration, by separating them with commas:

html
<article class="multiple">
  <p>
    <strong>Warning</strong>: The thermostat on the cosmic transcender has
    reached a critical level.
  </p>
</article>
css
p {
  margin: 0;
}

article {
  max-width: 500px;
  padding: 10px;
  background-color: red;
  background-image: linear-gradient(
    to bottom,
    rgb(0 0 0 / 0%),
    rgb(0 0 0 / 25%)
  );
}

.multiple {
  box-shadow: 1px 1px 1px black,
              2px 2px 1px black,
              3px 3px 1px red,
              4px 4px 1px red,
              5px 5px 1px black,
              6px 6px 1px black;
}

现在我们得到这个结果:

¥Now we get this result:

我们在这里做了一些有趣的事情,创建了一个具有多个彩色层的凸起框,但你可以以任何你想要的方式使用它,例如,使用基于多个光源的阴影创建更真实的外观。

¥We've done something fun here by creating a raised box with multiple colored layers, but you could use it in any way you want, for example to create a more realistic look with shadows based on multiple light sources.

其他盒子阴影功能

¥Other box shadow features

text-shadow 不同,box-shadow 有一个可用的 inset 关键字 - 将其放在影子声明的开头会使其成为内部影子,而不是外部影子。让我们看一下,看看我们的意思。

¥Unlike text-shadow, box-shadow has an inset keyword available — putting this at the start of a shadow declaration causes it to become an inner shadow, rather than an outer shadow. Let's have a look and see what we mean.

首先,我们将在此示例中使用一些不同的 HTML:

¥First, we'll go with some different HTML for this example:

html
<button>Press me!</button>
css
button {
  width: 150px;
  font-size: 1.1rem;
  line-height: 2;
  border-radius: 10px;
  border: none;
  background-image: linear-gradient(to bottom right, #777, #ddd);
  box-shadow:
    1px 1px 1px black,
    inset 2px 3px 5px rgb(0 0 0 / 30%),
    inset -2px -3px 5px rgb(255 255 255 / 50%);
}

button:focus,
button:hover {
  background-image: linear-gradient(to bottom right, #888, #eee);
}

button:active {
  box-shadow:
    inset 2px 2px 1px black,
    inset 2px 3px 5px rgb(0 0 0 / 30%),
    inset -2px -3px 5px rgb(255 255 255 / 50%);
}

这给了我们以下结果:

¥This gives us the following result:

在这里,我们设置了一些按钮样式以及焦点/悬停/活动状态。默认情况下,该按钮上设置了一个简单的黑框阴影,再加上几个嵌入阴影(一浅一深),放置在按钮的对角上,以提供良好的阴影效果。

¥Here we've set up some button styling along with focus/hover/active states. The button has a simple black box shadow set on it by default, plus a couple of inset shadows, one light and one dark, placed on opposite corners of the button to give it a nice shading effect.

当按钮被按下时,活动状态会导致第一个框阴影被替换为非常暗的插入阴影,从而给出按钮被按下的外观。

¥When the button is pressed in, the active state causes the first box shadow to be swapped for a very dark inset shadow, giving the appearance of the button being pressed in.

注意:box-shadow 值中还可以设置另一个项目 - 可以选择在颜色值之前设置另一个长度值,即展开半径。如果设置,这会导致阴影变得比原始框更大。它不是很常用,但值得一提。

¥Note: There is another item that can be set in the box-shadow value — another length value can be optionally set just before the color value, which is a spread radius. If set, this causes the shadow to become bigger than the original box. It is not very commonly used, but worth mentioning.

过滤器

¥Filters

虽然你无法使用 CSS 更改图片的布局,但你可以做一些创造性的事情。filter 属性是一个非常好的属性,它可以帮助你为你的设计带来兴趣。此属性可以直接从 CSS 启用类似 Photoshop 的滤镜。

¥While you can't change the composure of an image using CSS, there are some creative things you can do. One very nice property, which can help you bring interest to your designs, is the filter property. This property enables Photoshop-like filters right from CSS.

在下面的示例中,我们使用了两个不同的过滤器值。firstblur() — 此函数可以传递一个值来指示图片应模糊的程度。

¥In the example below we have used two different values for filter. The first is blur() — this function can be passed a value to indicate how much the image should be blurred.

第二个是 grayscale();通过使用百分比,我们可以设置要删除的颜色量。

¥The second is grayscale(); by using a percentage we are setting how much color we want to be removed.

使用实时示例中的百分比和像素参数来查看图片如何变化。你还可以将这些值交换为其他值。在上面的实际示例中尝试 contrast(200%)invert(100%)hue-rotate(20deg)。查看 filter 的 MDN 页面,了解你可以尝试的许多其他选项。

¥Play with the percentage and pixel parameters in the live example to see how the images change. You could also swap the values for some others. Try contrast(200%), invert(100%) or hue-rotate(20deg) on the live example above. Take a look at the MDN page for filter for many other options you could try.

你可以将滤镜应用于任何元素,而不仅仅是图片。一些可用的过滤器选项与其他 CSS 功能执行非常相似的操作,例如 drop-shadow() 以非常相似的方式工作,并提供与 box-shadowtext-shadow 相似的效果。然而,过滤器真正好的一点是,它们作用于盒子内内容的精确形状,而不仅仅是盒子本身作为一大块,因此值得了解其中的差异。

¥You can apply filters to any element and not just images. Some of the filter options available do very similar things to other CSS features, for example drop-shadow() works in a very similar way and gives a similar effect to box-shadow or text-shadow. The really nice thing about filters however, is that they work on the exact shapes of the content inside the box, not just the box itself as one big chunk, so it is worth knowing the difference.

在下一个示例中,我们将过滤器应用到一个盒子,并将其与盒子阴影进行比较。正如你所看到的,阴影过滤器遵循文本和边框虚线的确切形状。盒子阴影正好跟随盒子的正方形。

¥In this next example we are applying our filter to a box, and comparing it to a box shadow. As you can see, the drop-shadow filter follows the exact shape of the text and border dashes. The box shadow just follows the square of the box.

混合模式

¥Blend modes

CSS 混合模式允许我们向元素添加混合模式,以指定两个元素重叠时的混合效果 - 每个像素显示的最终颜色将是原始像素颜色与下层像素颜色组合的结果 它。混合模式对于 Photoshop 等图形应用的用户来说再次非常熟悉。

¥CSS blend modes allow us to add blend modes to elements that specify a blending effect when two elements overlap — the final color shown for each pixel will be the result of a combination of the original pixel color, and that of the pixel in the layer underneath it. Blend modes are again very familiar to users of graphics applications like Photoshop.

CSS 中有两个使用混合模式的属性:

¥There are two properties that use blend modes in CSS:

  • background-blend-mode,它将单个元素上设置的多个背景图片和颜色混合在一起。
  • mix-blend-mode,它将设置的元素与重叠的元素混合在一起 - 背景和内容。

你可以找到比我们的 blend-modes.html 示例页面(参见 源代码)和 参考页面上提供的更多示例。

¥You can find a lot more examples than are available here in our blend-modes.html example page (see source code), and on the <blend-mode> reference page.

注意:混合模式也是非常新的,并且比过滤器支持得稍差。Edge 尚不支持,Safari 仅支持部分混合模式选项。

¥Note: Blend modes are also very new, and slightly less well supported than filters. There is no support as yet in Edge, and Safari only supports some of the blend mode options.

background-blend-mode

再次,让我们看一些例子,以便我们更好地理解这一点。首先,background-blend-mode — 这里我们将展示几个简单的 <div>,以便你可以将原始版本与混合版本进行比较:

¥Again, let's look at some examples so we can understand this better. First, background-blend-mode — here we'll show a couple of simple <div>s, so you can compare the original with the blended version:

html
<div></div>
<div class="multiply"></div>

现在一些 CSS — 我们正在向 <div> 添加一张背景图片和一种绿色背景颜色:

¥Now some CSS — we are adding to the <div> one background image and a green background color:

css
div {
  width: 250px;
  height: 130px;
  padding: 10px;
  margin: 10px;
  display: inline-block;
  background: url(colorful-heart.png) no-repeat center 20px;
  background-color: green;
}

.multiply {
  background-blend-mode: multiply;
}

我们得到的结果是这样的 - 你可以在左边看到原始的,在右边看到乘法混合模式:

¥The result we get is this — you can see the original on the left, and the multiply blend mode on the right:

mix-blend-mode

现在我们来看看 mix-blend-mode。在这里,我们将呈现相同的两个 <div>,但每个现在都位于带有紫色背景的简单 <div> 之上,以显示元素如何混合在一起:

¥Now let's look at mix-blend-mode. Here we'll present the same two <div>s, but each one is now sat on top of a simple <div> with a purple background, to show how the elements will blend together:

html
<article>
  No mix blend mode
  <div></div>
  <div></div>
</article>

<article>
  Multiply mix
  <div class="multiply-mix"></div>
  <div></div>
</article>

这是我们将使用的 CSS 样式:

¥Here's the CSS we'll style this with:

css
article {
  width: 280px;
  height: 180px;
  margin: 10px;
  position: relative;
  display: inline-block;
}

div {
  width: 250px;
  height: 130px;
  padding: 10px;
  margin: 10px;
}

article div:first-child {
  position: absolute;
  top: 10px;
  left: 0;
  background: url(colorful-heart.png) no-repeat center 20px;
  background-color: green;
}

article div:last-child {
  background-color: purple;
  position: absolute;
  bottom: -10px;
  right: 0;
  z-index: -1;
}

.multiply-mix {
  mix-blend-mode: multiply;
}

这给了我们以下结果:

¥This gives us the following results:

你可以在此处看到,多重混合混合不仅将两个背景图片混合在一起,而且还混合了其下面的 <div> 的颜色。

¥You can see here that the multiply mix blend has blended together not only the two background images, but also the color from the <div> below it too.

注意:如果你不理解上面的一些布局属性,请不要担心,例如 positiontopbottomz-index 等。我们将在 CSS 布局 模块中详细介绍这些属性。

¥Note: Don't worry if you don't understand some of the layout properties above, like position, top, bottom, z-index, etc. We will cover these in detail in our CSS Layout module.

CSS 形状

¥CSS shapes

虽然 CSS 中的所有内容都是一个矩形框,并且图片也是一个物理矩形框,但我们可以使用 CSS 形状 使内容看起来好像围绕非矩形事物流动。

¥While it is true that everything in CSS is a rectangular box, and images are a physical rectangular box, we can make it look as if our content flows around non-rectangular things by using CSS Shapes.

CSS Shapes 规范允许将文本环绕在非矩形形状周围。当处理具有一些空白的图片时,你可能希望在周围浮动文本,它特别有用。

¥The CSS Shapes specification enables the wrapping of text around a non-rectangular shape. It's especially useful when working with an image which has some white-space you might want to float text around.

在下图中,我们有一个令人赏心悦目的圆形气球。实际文件是矩形的,但通过浮动图片(形状仅适用于浮动元素)并使用值为 circle(50%)shape-outside 属性,我们可以给出文本跟随气球线的效果。

¥In the image below we have a pleasingly round balloon. The actual file is rectangular, but by floating the image (shapes only apply to floated elements) and using the shape-outside property with a value of circle(50%), we can give the effect of the text following the line of the balloon.

此示例中的形状不会对图片文件的内容做出反应。相反,circle 函数从图片文件的中心获取其中心点,就好像我们在文件中间放置了一个指南针并绘制了一个适合文件内部的圆。文本围绕的就是这个圆圈。

¥The shape in this example is not reacting to the content of the image file. Instead, the circle function is taking its center point from the center of the image file, as if we had put a compass in the middle of the file and drawn a circle that fits inside the file. It is that circle that the text flows around.

注意:在 Firefox 中,你可以使用 DevTools 形状检查器 来检查形状。

¥Note: In Firefox you can use the DevTools Shapes Inspector to inspect Shapes.

circle() 函数只是定义的几个基本形状之一,但是有许多不同的方法来创建形状。有关 CSS Shapes 的更多信息和示例代码,请参阅 MDN 上的 CSS 形状指南

¥The circle() function is just one of a few basic shapes that are defined, however there are a number of different ways to create shapes. For more information and example code for CSS Shapes see the Guides to CSS Shapes on MDN.

-webkit-背景剪辑:text

¥-webkit-background-clip: text

我们认为应该简要提及的另一个功能是 background-cliptext 值。当与专有的 -webkit-text-fill-color: transparent; 功能一起使用时,你可以将背景图片剪切到元素文本的形状,从而产生一些不错的效果。这不是官方标准,但由于它很流行并且被开发者广泛使用,因此已在多个浏览器中实现。在此上下文中使用时,这两个属性都需要 -webkit- 供应商前缀,即使对于基于非 Webkit/Chrome 的浏览器也是如此:

¥Another feature we thought we'd mention briefly is the text value for background-clip. When used along with the proprietary -webkit-text-fill-color: transparent; feature, this allows you to clip background images to the shape of the element's text, making for some nice effects. This is not an official standard, but has been implemented across multiple browsers, as it is popular, and used fairly widely by developers. When used in this context, both of the properties would require a -webkit- vendor prefix, even for Non-Webkit/Chrome-based browsers:

css
.text-clip {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

那么为什么其他浏览器实现了 -webkit- 前缀呢?主要是为了浏览器兼容性 - 如此多的网络开发者已经开始实现带有 -webkit- 前缀的网站,以至于看起来其他浏览器都被破坏了,而实际上他们遵循的是标准。因此他们被迫实现一些这样的功能。这凸显了在工作中使用非标准和/或前缀 CSS 功能的危险 - 它们不仅会导致浏览器兼容性问题,而且还可能会发生变化,因此你的代码可能随时中断。坚持标准要好得多。

¥So why have other browsers implemented a -webkit- prefix? Mainly for browser compatibility — so many web developers have started implementing websites with -webkit- prefixes that it started to look like the other browsers were broken, whereas in actual fact they were following the standards. So they were forced to implement a few such features. This highlights the danger of using non-standard and/or prefixed CSS features in your work — not only do they cause browser compatibility issues, but they are also subject to change, so your code could break at any time. It is much better to stick to the standards.

如果你确实想在生产工作中使用这些功能,请务必跨浏览器进行彻底测试,并检查在这些功能不起作用的情况下该网站是否仍然可用。

¥If you do want to use such features in your production work, make sure to test across browsers thoroughly and check that, where these features don't work, the site is still usable.

注意:有关完整的 -webkit-background-clip: text 代码示例,请参阅 background-clip-text.html(另请参阅 源代码)。

¥Note: For a full -webkit-background-clip: text code example, see background-clip-text.html (see also the source code).

概括

¥Summary

我们希望这篇文章很有趣 - 玩闪亮的玩具通常很有趣,并且了解现代浏览器中可用的高级样式工具总是很有趣。

¥We hope this article was fun — playing with shiny toys generally is, and it is always interesting to see what kinds of advanced styling tools are becoming available in modern browsers.