重新审视Css Shapes

原文地址: Take A New Look At CSS Shapes — Smashing Magazine

CSS Shape Level 1规范在Chrome和Safari浏览器上获得支持已经有许多年了,本周(2018/9/4那周)Firefox发布的生产版本Firefox 62中添加了对它的支持,并让我们能在Firefox开发者工具中更好的使用它。 在本文中,我将介绍一些CSS Shapes的使用示例。或许,是时候给你的设计中添加一些弯曲形状了?

CSS Shapes是什么?

CSS Shapes规范Level 1标准中定义了下面三个新的属性:

  • shape-outside
  • shape-image-threshold
  • shape-margin

这个规范的目的是让内容可以围绕在一个非矩形的形状区域外,这在四四方方的网页中并不常见。我们会在这个教程中看到几个创建图形的不同方法。同时也会介绍Firefox中的Shape Path Editor,它会帮助你更好的理解和使用CSS Shapes。

在当前的标准中,shapes只能应用于浮动元素,因此任何使用CSS Shapes属性的元素必须首先是浮动的。在下面的例子中,我使用了一个有着透明背景的PNG图片,并让它向左浮动。图片后的文字内容现在环绕在图片的右边和底部。

我所期望的是内容部分跟随在图片的不透明部分,而不是图片文件的右边线。要达到这个目的,我使用了shape-outside属性,值为我使用的图片的地址。我使用图片文件创建了文字内容要环绕的路径。

注意你的图片需要支持跨域,因此使用和内容相同服务器的图片,或者在CDN上设置合适的返回头部。浏览器开发工具通常会提示是否被跨域阻止。
(注:顺便上面那个例子可能看不到效果也是因为这里)

这种方法中,我们使用一个有透明通道的图片来创建几何图形,我们有一个有着完全透明区域的图形,之后需要做的就是把图片的url传递给shape-outside,图形的路径就会围绕着非透明区域的轮廓。

创建外边距

让内容和图形产生一定距离需要使用shape-margin属性。这会在图形边界和文本内容见创建间距。

使用生成的内容作为图形

在上面的例子中,我们将图片放在页面上并让文字内容弯曲的跟随环绕在后。此外,你也可以用图片创建图形路径同时不将图本身展示在页面上。依然需要设置浮动,为此我们使用content属性。

在这个例子中,我们插入了一些生成的内容,并让它浮动,设置宽度高度然后像之前那样使用shape-outside。之后我们便得到了一个曲线的空白图形,而非一个可见的图片。

为图形使用渐变

CSS渐变就像图片一样,这就意味着我们可以使用渐变来创建形状,并得到一些有趣的效果。在下面的例子中,我创建了一个从蓝色到白色的渐变;为了使用CSS Shapes,创建的渐变中需要有一个透明或者半透明的区域。我又一次的使用了content来创建渐变,并作为shape-outside属性的值。

渐变过渡为全透明的地方就产生了形状,文字内容就跟随在渐变的边缘。

使用shape-image-threshold定位半透明图片周围的文字

到此为止,我们已经看到如何使用一个有全透明区域的图片或者渐变来创建我们的图形,然而CSS Shapes规范中定义的第三个属性意味着我们可以通过设置临界值来使用有半透明区域的图片或者渐变。shape-image-threshold的值为1代表完全不透明,为0代表完全透明。

像上面那个例子中用到的渐变,就可以用来观察当改变shape-image-threshold的值时候,文字内容更多的落在不透明区域还是透明区域。这个属性也可以使用在有着非完全透明区域的图片中。

这种利用图片或者渐变创建形状的方式——在我看来——是最简单的创建图形的方法。你也可以利用图形软件,根据需要在页面上创建更加复杂的图形。也就是说,这里还有其他的创建图形的方法,那就是使用基础图形。

使用Basic Shapes创建CSS Shapes

基础图形是一系类预先设置好的不同类型的常用图形。要使用它,你需要将基础图形的类型(type)作为shape-outside的值。类型使用函数标识,因此名字后面有一对括号(里面传递我们需要的和图形有关的值)。

有以下几种选项

  • inset()
  • circle()
  • ellipse()
  • polygon()

首先我们来看一下circle()类型,以此了解一些基础图形的通用设置。同时也会看一下Firefox中新增的检查工具。

在下面的例子中,我创建了一个最简单的图形:一个圆形shape-outside: circle(50%)。依然使用content,并给盒子设置背景色,添加外边距,边框和内边距来帮助展示CSS Shapes里的一些概念。可以看到,在这个例子中圆形在盒子的中间;这是因为我给circle了一个50%的值。这个值是<shape-radius>图形半径,可以使用长度或者百分比。我使用了百分比因此这个半径是盒子尺寸的一半。

这里恰好很适合查看使用Firefox的图形路径编辑器创建的图形。你可以查看创建内容并点击shape-outside旁边的图形图标;此时图形会被高亮。

(注:方便表示这里换了一个图)

你可以看到圆形如何延伸到盒子的外边距边沿。这是因为图形使用的*盒模型*是margin-box。你可能还知道其他的盒模型,如果你曾经在CSS文件中写过box-sizing: border-box。这意味着让CSS使用border-box而不是默认的content-box来计算元素的尺寸。在CSS Shapes中我们也可以修改这个设置,在任何基础图形类型后添加border-box来使用边框定义图形,或者content-box使用内容边界定义图形(在内边距内部)。例如:

.content::before {
  content: "";
  width: 150px;
  height: 150px;
  margin: 20px;
  padding: 20px;
  border: 10px solid #fc466b;
  background: linear-gradient(90deg, #fc466b 0%, #3f5efb 100%);
  float: left;
  shape-outside: circle(50%) content-box;
}

你将看到圆形变得比之前更小。现在它使用了内容的宽度——这里是盒子的宽度150px——而不是包括内边距、边框和外边距的margin盒子。

在Firefox的开发者工具中也会看到这个盒模型,这样你就可以利用它来选择和创建更适合需要的图形。

定位值

可以向circle()传递第二个值作为定位信息;如果忽略,默认值为center。你可以利用这个值移动圆的位置。在下面的例子,我将使用shape-outside: circle(50% at 30%)来改变圆心的位置。

clip-path

值得一提的是,<basic-shape>的值也可以设置给clip-path。这就意味着在创建几何图形之后,你可以裁切掉图片或者背景色中超出图形的部分。下面我将继续修改之前的例子来添加这个属性,以便我们最终从一个方形盒子得到一个被文字曲线环绕的圆形。

上面的概念都可以拿来用在其他的基础图形上。现在我们来简单的看一下它们是如何实现的。

INSET()

inset()定义矩形,作为矩形浮动区域它看起来可能并不是很实用,但是他可以让你在图形周围嵌入内容。它可以使用top,right,bottom,left与一个最终定义边框半径的值为参数。

在下面的例子中,我使用shape-outside: inset(0 30px 100px 0 round 40px)将内容沿浮动的图片右边和底部嵌入,并添加边界半径。现在你可以看到内容是如何浮在盒子背景色的上面。

ELLIPSE()

椭圆是压扁的圆形,它需要两个半径,一个x轴半径一个y轴半径。你也可以移动椭圆的位置就像上面给圆形设置的那样。下面的例子中我创建了一个椭圆形状,并同样用clicp-path去掉图形之外的内容。

在上面的例子中我还使用了shape-margin属性来展示如何给创建的形状添加外边距。

POLYGON()

多边形形状可以使用三个或者更多的点来创建图形,更加灵活。需要传递三个或以上的坐标值作为多边形的参数值。

这里使用Firefox浏览器工具创建多边形会更加方便。在下面的例子中我使用了四个点创建图形。在Firefox开发者工具中,你可以双击任何边线创建新的点,再次双击可以移除。当得到满意的多边形后,可以复制DevTools中的值到css你的样式文件中。

降级处理

由于CSS Shapes是应用在一个浮动元素上,因此常见的降级处理是让内容围绕在浮动元素外(内容总是包裹在浮动元素外的方式)而不是围绕一个图形。浏览器会忽视它们不知道的属性,因此如果它不支持Shapes,写shape-outside也没有关系。

你需要留意的是,在某些情况下没有图形可能会让内容覆盖在某个会降低可读性的区域上。例如,可能你使用Shapes让内容远离一个背景图的繁忙区域。这种情况下,你需要首先确定你的内容对不支持Shapes的用户也可用,然后用Feature Queries检查shape-outside的支持性并添加图形覆盖之前的CSS。例如,你可以为不支持Shapes的访问者添加一个外边距让内容远离,然后在属性查询里移除这个外边距。

.content {
    margin-left: 120px;
}

@supports (shape-outside: circle()) {
    .content {
        margin-left: 0;
        /* 这里添加其他的图形样式 */
    }
}

随着Firefox发布了他们对图形的支持,现在只有一个主流浏览器不支持这个属性——Edge。如果想看Shapes获得比较全面的支可以来这里提议,看是否可以推动这个属性在Edge中的实现。

获取更多关于CSS Shapes的信息

在这篇文章中,我试图简单概述一些可以用CSS Shapes实现的有趣示例。想要更加深入了解每个属性,可以参考MDN的CSS Shapes - CSS: Cascading Style Sheets | MDN。也可以阅读Edit Shape Paths in CSS - Firefox Developer Tools | MDN

Comments
Write a Comment