html5梯形图形代码,CSS秘密花园:梯形标签

《CSS Secrets》是@Lea Verou最新著作,这本书讲解了有关于CSS中一些小秘密。是一本CSSer值得一读的一本书,经过一段时间的阅读,我、@南北和@彦子一起将在W3cplus发布一系列相关的读后感,与大家一起分享。

e5f24a5009a75a71236f46a3b4696930.png

问题

梯形应用得比平行四边形更普遍:只有两条边是平行的。另外两条可以是任何角度。以前,它们都是CSS中很难创建的形状,尽管它们特别常用,特别是对于标签。作者要么是通过精心设计的背景图像来模拟它们,要么是一个矩形旁边带两个三角形来创建,或者是通过边框来伪造一下。

524463385d90a77d49bbd6ed4586075d.png

图注:通过伪元素边框伪造的梯形(为清楚起见,用较暗的蓝色表示伪元素)

尽管这种技术可以节省我们花费在图像上的额外的HTTP请求,也可以非常简单地调整宽度,但还是不理想。这既浪费了可用的伪元素,在样式上也非常不灵活。比如,要添加一个边框,一个背景纹理,或一些标签周围的东西的时候就悲剧了(>﹏<)。

c420016a08c155e2442c8da749f5a070.png

Cloud9 IDE每个打开的文档都有梯形的标签

5a3db80fc34153638af31a1afdbefed6.png

csstricks.com早期的梯形便签,尽管只倾斜了一个方向

因为几乎所有用于梯形设计的技术都非常混乱甚至难以维护,我们在Web上看到的大多不是倾斜的,尽管现实的标签是这样的。是否有一个完整的灵活的方式来创建梯形标签呢?

解决方案

是否存在这样的可以创建梯形的2D变换的组合,我们只需要应用平行四边形中的解决方案稍微转变一下,就可以完成了。可惜,事情并不是这么简单。

想象在一个物理的三维世界里旋转一个矩形。我们看到的二维图像通常是一个梯形,因为角度问题!所以,我们可以通过使用一个3D旋转来在CSS中模拟这个效果:

transform: perspective(.5em) rotateX(5deg);

8596aec17c4822cce0c843e87a5904bc.png

图注:通过3D旋转创建一个梯形。上边:变换前;下边:变换后

你可以在上图中看到它创建出的梯形。当然,因为我们给一整个元素都应用了3D变换,文本也失真了。3D变换不能像2D变换那样,将内部文本的变换抵消(因为2D可以通过一个相反方向的变换来抵消变换)。从技术上将内部元素的变换取消是可行的,但是非常复杂。因此,唯一实用的方式就是利用3D变换来创建一个梯形,把这种变换应用到伪元素上,类似于平行四边形中的方法:

.tab {

position: relative;

display: inline-block;

padding: .5em 1em .35em;

color: white;

}

.tab::before {

content: ''; /* To generate the box */

position: absolute;

top: 0; right: 0; bottom: 0; left: 0;

z-index: -1;

background: #58a;

transform: perspective(.5em) rotateX(5deg);

}

224a02f4e69971ba2fff45deac84b401.png

图注:给伪元素生成的盒子应用3D变换,这样我们的文本就不会受到影响

如上图所示,这可以创建出一个基本的梯形。虽然还有一个问题,当我们在应用的变换没有设置transform-origin,元素会围绕其中心旋转。因此,我们屏幕上的这个2D的投影会因为很多因素改变,如下图所示:

ba6f0bf58c623c1743c80f8e289ed416.png

图注:我们的梯形覆盖在其预变换的版本上,以突出其指标的改变

当宽度增加时,它会向上移动,在高度上稍微有点变小等,这使得它很难设计。

为了让这个指标更可控,我们指定了transform-origin: bottom;,这样在旋转的时候它的基本还是固定的。你可以在下图中看到区别。

1394201ed3786fbe2a96c0f5f6e9df98.png

图注:我们覆盖在预变换版本上的梯形,当使用transform-origin: bottom;时将尺寸变化高亮

现在它更可预见一些:只有高度减少了。但是,高度的减少是非常清晰的,因为整个元素都旋转到远离观察者了,而在此之前,它有一半在屏幕之上,一半在屏幕之下,这样整个元素在三维空间里离观察者更近一些。为了解决这个问题,我们可能会想给它应用额外的顶部内边距。但是,浏览器中的显示结果还是非常糟糕,因为没有支持3D变换(如下图所示)。

c5ef0d22900cc2c255ee9bf65a124418.png

图注:使用额外的padding解决问题导致了一个非常奇怪的降级

相反,我们可以通过一个变换来增加它的尺寸,这样当不支持3D变换的时候,整个内容都会失效。经过几个试验,我们发现约130%的垂直缩放(如scaleY()变换)足以弥补失去的空间:

transform: scaleY(1.3) perspective(.5em) rotateX(5deg);

transform-origin: bottom;

0237d28096ef9a31ff88266df085949d.png

图注:使用scale()来弥补失去的高度,提供了一个非常好的降级(上方的图)

你可以在上图中看到结果和降级。这里,结果只是在视觉上等同于前面提到的基于border的技术,只是这里的语法更简洁。但是,当你开始给标签应用一些样式的时候,这种技术的优势开始出现。例如,看看下面的代码:

nav > a {

position: relative;

display: inline-block;

padding: .3em 1em 0;

}

nav > a::before {

content: '';

position: absolute;

top: 0; right: 0; bottom: 0; left: 0;

z-index: -1;

background: #ccc;

background-image: linear-gradient(

hsla(0,0%,100%,.6),

hsla(0,0%,100%,0));

border: 1px solid rgba(0,0,0,.4);

border-bottom: none;

border-radius: .5em .5em 0 0;

box-shadow: 0 .15em white inset;

transform: perspective(.5em) rotateX(5deg);

transform-origin: bottom;

}

上面代码的效果如下图所示:

29c70f3d734d3d4c938f2526c841f562.png

图注:这种技术的优势在于它样式方面的灵活性

如你所见,我们已经应用了背景、边框、圆角,还有盒阴影——它们都是可行的,没有任何问题!此外,只需要把transform-origin的值改为bottom left 或 bottom right,我们就可以得到向左或向右倾斜的标签,分别!

9ff0c93d6d41d2ff008dd263bd91b2a9.png

图注:通过改变transform-origin的值生成的斜标签

尽管它有这么多的优点,这种技术还是不够完美。它有一个非常重大的缺陷:侧边的角度取决于元素的宽度。因此,当处理不同的内容时,用相同的角度来得到梯形是很棘手的。但是,对于宽度变化小的元素,它还是非常ok的,比如导航菜单。在这些情况中,差异是难以察觉的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值