🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> 原文出处:http://www.w3cplus.com/css3/css-secrets/parallelograms.html ## 问题 平行四边形是矩形的一个超集:它的边是平行的,但是角不一定是直角。 ![平行四边形](https://box.kancloud.cn/2015-10-05_5611e0b5971a3.png "灵活的椭圆形") *图注:一个平行四边形* 在视觉设计,它们往往可以使设计显得更具活力,传达运动感。 ![平行四边形](https://box.kancloud.cn/2015-10-05_5611e0bb720ac.png "灵活的椭圆形") *图注:eb设计中的平行四边形(design by Martina Pitakova)* 我们尝试用CSS创建按钮样式的链接。从普通的扁平按钮开始,带一些简单的样式,如图下图所示: ![平行四边形](https://box.kancloud.cn/2015-10-05_5611e0bc249ca.png "灵活的椭圆形") 然后,我们应用`skew()`变换创建出倾斜的矩形,如下: ~~~ transform: skewX(-45deg); ~~~ 但是,这也会导致平行四边形中的内容被倾斜,这使得它看起来很丑而且没有可读性。 ![平行四边形](https://box.kancloud.cn/2015-10-05_5611e0bc4916b.png "灵活的椭圆形") *图注:倾斜后的按钮,文本变得难以阅读* 有什么办法可以只倾斜外边的形状容器,而不倾斜里边的内容吗? ## 嵌套元素的解决方案 我们可以给内容应用一个相反的`skew()`变换,把外边的变换抵消,这样就可以得到我们想要的结果。但是,这也意味着我们必须使用额外的HTML元素来包裹内容,如一个`div`: ~~~ <a href="#yolo" class="button"> <div>Click me</div> </a> .button { transform: skewX(-45deg); } .button > div { transform: skewX(45deg); } ~~~ > 如果你是给默认内联的元素应用这个效果,记得把它的`display`属性设置为`inline-block`或`block`,否则应用的变换不会生效。内部元素也一样。 正如下图的效果: ![平行四边形](https://box.kancloud.cn/2015-10-05_5611e0bc72819.png "灵活的椭圆形") 如如你看到,它运行没有问题,但是我们使用了一个额外的HTML元素。如果修改标签不是一个可选的方案,或者你真的希望保持标签纯度,别担心,这里还有一个纯CSS的解决方案。 ## 伪元素解决方案 另一个方案是把所有的样式应用在伪元素上(背景、边框等等),然后为其应用变换。因为我们的内容不是被包裹在伪元素中的,它不会被变换影响。我们尝试使用这种技术给一个链接添加样式,跟前一节一样的方法。 我们需要让伪元素保持灵活性,并自动继承父元素的尺寸,即使它们的大小由内容决定。一个简单的方法时是父元素应用`position: relative`,然后给生成的元素应用`position: absolute`,然后把所有的偏移量都设置为`0`,这样它的水平和垂直方向都会继承父元素的大小。代码如下: ~~~ .button { position: relative; /* text color, paddings, etc. */ } .button::before { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; } ~~~ 此时,生成的盒子是悬浮在内容上边的,一旦给它应用了背景,它将会覆盖住内容: ![平行四边形](https://box.kancloud.cn/2015-10-05_5611e0bcbb53e.png "灵活的椭圆形") *图注:我们的伪元素当前是悬浮在内容上边的,所以应用`background: #58a`来覆盖* 我们可以给伪元素应用一个`z-index: -1`,这样它就会移动到父元素下方了。 现在,终于可以给我们的主要元素应用变换,然后查看结果了。最后的代码如下,生成的效果和前面的方案生成的效果完全一样: ~~~ .button { position: relative; /* text color, paddings, etc. */ } .button::before { content: ''; /* To generate the box */ position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: -1; background: #58a; transform: skew(45deg); } ~~~ 这些技术不仅对`skew()`变换有效。它们还可以结合其它变换使用,这样既可以改变元素的形状,但又不会对它的内容造成影响。例如,给一个方形元素使用`rotate()`变换,可以很容易地生成一个钻石( 菱形)形状。 还有,使用伪元素和定位来生成一个盒子,并添加样式,然后放置在父元素之下的方法,在很多其它的不同类型的效果实例中都可以使用,如: * 一种常见的解决IE8中多背景的方法,由[Nicolas Gallagher](http://nicolasgallagher.com/multiple-backgrounds-and-borders-with-css2/)提供。 * 可以解决像[第二章第四节中的“Inner rounding”这样的效果](http://www.w3cplus.com/css3/css-secrets/inner-rounding.html),能猜到是怎么实现的吗? * 可以用来单独给背景应用像`opacity`这样的属性,由[Nicolas Gallagher](http://nicolasgallagher.com/css-background-image-hacks/)首创。 * 可以用来模拟多边框,以一种更灵活的方法。这样我们不可以使用[第二章第二节的“Multiple borders”的技术](http://www.w3cplus.com/css3/css-secrets/multiple-borders.html)。例如,当我们需要多个虚线边框,或多个用空格分隔的边框和透明度时。