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

问题

为元素的一个角落添加样式,让它看起来像是折起来的(通常是右上角或是左下角),有不同程度的逼真效果,是这几年来一个非常受欢迎的效果。

近来,有几个纯CSS的解决方案,第一个是在2010年的时候由伪元素大师——Nicolas Gallagher发布的。它们通常是通过添加两个三角形在左上角:一个用于翻页,一个用于模糊主元素的角。这些三角形通常是通过旧的border技巧来创建的。

图注:几个早期的csstricks.com上的折角效果的设计,在每篇文章的右上角都可以看到

这些解决方案在当时是令人印象深刻的,现在它们却在下面这几种情况下有非常多的限制以及不足:

当我们的元素的背景不是纯色,而是一个图案、纹理、照片、渐变,或其它任何这样的背景图像

当我们想要一个不同于45°的角,或是一个旋转折叠

有没有一种方法可以用CSS直接创建一个更灵活的折叠角效果,而且在这些情况下也不会失效的?

针对45°角的解决方案

我们从一个右上角带有斜角的元素开始,在第三章第四小节中提到的基于渐变的解决方案上创建。为了用这种技术创建一个1em的右上斜切角,代码如下:

background: #58a; /* Fallback */

background:linear-gradient(-135deg, transparent 2em, #58a 0);

效果如下:

图注:我们的起点:一个右上角带有斜切角的元素,通过一个渐变完成

在这时候,我们已经完成了一半的工作:我们需要做的是添加一个暗色的三角形用于翻页效果。我们需要通过添加另一个渐变来创建三角形,因此我们将根据需求重新调整background-size的值和右上角的position。

要创建三角形,我们需要做一个倾斜的线性渐变:

background:linear-gradient(to left bottom,transparent 50%, rgba(0,0,0,.4) 0) no-repeat 100% 0 / 2em 2em;

图注:我们为了折叠三角形的完成的第二个渐变,此处的文本显示的是淡淡的灰色而不是白色,这样你就能大概看到文本所处的位置

你可以在上图中看到只有这个渐变背景的效果。最后一步是把它们结合起来,这个我们会做,对吧?我们来试试,确保三角形翻页是在我们的缺角渐变上的:

background: #58a; /* Fallback */

background:

linear-gradient(to left bottom,transparent 50%, rgba(0,0,0,.4) 0) no-repeat 100% 0 / 2em 2em,

linear-gradient(-135deg, transparent 2em, #58a 0);

正如你在下图中看到的,结果和我们预期的并不一样。为什么大小不匹配呢?都是2em呀!

图注:把两个渐变结合起来,并没有产生我们所期待的结果

原因是(如我们在第三章第四小节中讨论过的),2em的斜角尺寸在我们的第二个渐变中是颜色结点,并由此沿着渐变线测量,也就是斜角方向上的。另一方面,2em长度在background-size是背景平铺的宽度和高度,是在水平方向和垂直方向测量的。

为了让两个对齐,我们可以采用下列操作中的一种,这取决于这两个尺寸中我们想要保留哪个:

要保留对角方向2em的尺寸,我们可以把background-size乘以根号二。

要保留水平和垂直方向2em的尺寸,我们可以把切口斜角渐变颜色结点的位置除以根号二。

因为background-size重复两次,大多数其他的CSS尺寸不是以对角线测量的,所以通常保留水平方向的2em是更好的选择。这样颜色结点的位置将变成2除以根号二等于根号二,约等于1.414213562,也就是最后会变成1.5em。

background: #58a; /* Fallback */

background:

linear-gradient(to left bottom,

transparent 50%, rgba(0,0,0,.4) 0)

no-repeat 100% 0 / 2em 2em,

linear-gradient(-135deg,

transparent 1.5em, #58a 0);

如下图所示,最后我们会得到一个漂亮的、灵活的、简单的圆角。

图注:在改变蓝色渐变颜色结点的位置之后,我们的折叠角终于完成了

请确保有足够多的padding,至少能大于折叠角的尺寸,否则文本将覆盖在角上(因为它只是一个背景),破坏了折叠角的视觉效果。

其它角度的解决方案

现实生活中的折叠角很少有正好是45°的。如果我们想要它更加逼真一点,我们可以使用一个稍微不同的角度,比如使用-150deg来完成一个30°的角。如果我们只改变斜角的角度,但是,代表翻页效果的三角形不会自己调整,会导致两角分裂,如图所示。

图注:改变切口的角度会导致分离

但是,我们不能直接调整它的尺寸。三角形的大小不是通过角度定义的,而是通过它的width和height值确定的。那我们要怎样才能找到我们需要的width和height值呢?Well,三角函数的知识是时候派上用场了!

目前的代码是长这样的:

background: #58a; /* Fallback */

background:

linear-gradient(to left bottom,

transparent 50%, rgba(0,0,0,.4) 0)

no-repeat 100% 0 / 2em 2em,

linear-gradient(-150deg,

transparent 1.5em, #58a 0);

你可以在下图中看到,如果我们需要计算两个30-60-90直角三角形斜边的长度,我们需要知道它们其中一条边的长度。

图注:我们的切角,放大(灰色标记的角为30°)

下图所示的极坐标中的三角函数提醒我们,如果我们知道角度和三角形一条边的长度,我们可以通过使用正弦、余弦、和勾股定理计算它的另外两条边的长度。

图注:正弦和余弦根据一个角和斜边,帮我们计算出了直角三角形的边长

通过数学知识(或计算器),我们知道cos 30°等于根号三除以2和sin 30°等于二分之一。我们还知道,在我们的示例中,根据三角函数,sin 30° = 1.5 / x以及cos 30° = 1.5 / y,因此:

在这里,根据勾股定理,我们可以计算出z的值:

现在我们可以调整三角形的大小了:

background: #58a; /* Fallback */

background:

linear-gradient(to left bottom,

transparent 50%, rgba(0,0,0,.4) 0)

no-repeat 100% 0 / 3em 1.73em,

linear-gradient(-150deg,

transparent 1.5em, #58a 0);

现在,我们的折叠角如图所示。

图注:尽管我们确实达到了我们想要的结果,事实却证明,它看起来非常不真实

你可以看到,现在的三角形虽然和我们的切口相匹配,但是效果看起来并不逼真!虽然我们可能还不能很快找出原因,我们前面已经看到过很多折叠角了,所以我们一眼就能看出它和我们的视觉习惯严重偏离了。你可以通过给一个实际的纸片折一个这样角度的角,来帮助弄明白为什么这个效果看起来这么假。在纸上我们找不出能够折叠出隐约如上图这样效果的角的方法。

你可以拿张纸折一个角看看,如图所示

图注:模拟折叠角效果(Leonie and Phoebe Verou的可爱纸片)

我们想要的三角形是稍微旋转的,并且和我们“剪”掉的三角形的尺寸是一样的。因为我们不能旋转背景,所以是时候用伪元素来移动效果了:

.note {

position: relative;

background: #58a; /* Fallback */

background:

linear-gradient(-150deg,

transparent 1.5em, #58a 0);

}

.note::before {

content: '';

position: absolute;

top: 0; right: 0;

background: linear-gradient(to left bottom,

transparent 50%, rgba(0,0,0,.4) 0)

100% 0 no-repeat;

width: 3em;

height: 1.73em;

}

这里,我们复制了刚刚下图中的效果,放到伪元素中。

我们的下一步是通过交换其width和height来让它变成我们切掉的角的对称角,改变三角形的方向,而不是互补。然后我们将其按照30° ((90° – 30°) – 30°) 的方向逆时针旋转。使其斜边平行于我们的切口角:

.note::before {

content: '';

position: absolute;

top: 0; right: 0;

background: linear-gradient(to left bottom,

transparent 50%, rgba(0,0,0,.4) 0)

100% 0 no-repeat;

width: 1.73em;

height: 3em;

transform: rotate(-30deg);

}

你可以在下图中看到我们改变后的效果。

图注:我们差不多完成了,但是我们需要移动三角形

正如你看到的,我们现在只需要移动三角形,使我们的两个三角形(黑色的和切开的那个)的斜边重合。就目前看,我们需要在水平和垂直方向移动三角形,所以比较难确定要怎么移动。我们可以通过把transform-origin设置为bottom right,让事情变得简单一点,这样三角形的右下角就会变成旋转中心,然后,保持固定在同一个地方:

.note::before {

/* [Rest of styling] */

transform: rotate(-30deg);

transform-origin: bottom right;

}

确保把translateY()变换放在旋转之前,否则我们的三角形将沿它的30°角移动,因为每个变换都将让元素的整个坐标系统一起变换,而不仅仅是元素本身!

如下图所示:

图注:添加transform-origin: bottom right;可以让事情变得简单很多:现在我们只需要在垂直方向移动我们的三角形就ok了。

现在我们只需要向上垂直移动我们的三角形。为了找到确切的值,我们可以再次使用几何来解决问题。如下图所示

图注:知道我们的三角形要移动多少并不像看起来那么难

我们的三角形需要的垂直偏移量是x-y=3-(根号三) 1.267949192,结果约为1.3em:

.note::before {

/* [Rest of styling] */

transform: translateY(-1.3em) rotate(-30deg);

transform-origin: bottom right;

}

下图中的效果,终于给了我们想要的效果。

图注:我们的三角形终于对上了~~好感动有木有

呼~真是不容易!此外,现在我们的三角形是通过伪元素生成的,我们可以让它变得更加逼真,通过添加圆角,(实际的)渐变,还有box-shadows!最后的代码如下所示:

.note {

position: relative;

background: #58a; /* Fallback */

background:

linear-gradient(-150deg,

transparent 1.5em, #58a 0);

border-radius: .5em;

}

.note::before {

content: '';

position: absolute;

top: 0; right: 0;

background: linear-gradient(to left bottom,

transparent 50%, rgba(0,0,0,.2) 0, rgba(0,0,0,.4))

100% 0 no-repeat;

width: 1.73em;

height: 3em;

transform: translateY(-1.3em) rotate(-30deg);

transform-origin: bottom right;

border-bottom-left-radius: inherit;

box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.15);

}

你可以在下图中欣赏我们的劳动成果。

效果看起来不错,但是代码重用的情况如何呢?我们来想一些常见的修改和变化:

只需要一次编辑就可以改变元素尺寸或其它参数(如padding)。

只需要编辑两次就可以改变背景颜色(没有降级的情况下)。

需要四次编辑和几个普通的计算,就可以改变折叠角的大小。

只需要五次编辑和几个甚至更少的琐碎的计算来改变折叠角的角度。

最后两个是比较难的。可能需要使用预处理器的@mixin:

@mixin folded-corner($background, $size,$angle: 30deg)

{

position: relative;

background: $background; /* Fallback */

background:

linear-gradient($angle - 180deg,

transparent $size, $background 0);

border-radius: .5em;

$x: $size / sin($angle);

$y: $size / cos($angle);

&::before {

content: '';

position: absolute;

top: 0; right: 0;

background: linear-gradient(to left bottom,

transparent 50%, rgba(0,0,0,.2) 0,

rgba(0,0,0,.4)) 100% 0 no-repeat;

width: $y; height: $x;

transform: translateY($y - $x)

rotate(2*$angle - 90deg);

transform-origin: bottom right;

border-bottom-left-radius: inherit;

box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.2);

}

}

/* used as... */

.note {

@include folded-corner(#58a, 2em, 40deg);

}

注意:在本书写作期间,SCSS还没有原生支持三角函数。要启用支持,你可以使用Compass框架,相对于其它库。你甚至可以自己写,使用泰勒展开函数!LESS,同样可以调用它们。

css直角线_CSS秘密花园:折角效果相关推荐

  1. 纯CSS实现圆角阴影的折角效果

    纯CSS实现圆角阴影的折角效果  2016-10-04 13:14   网页设计   标签:css   1637    2 把元素的一角处理类似折角的形状,再配上或多或少的修饰,这种效果已经成为一种非 ...

  2. css直角线_CSS魔法堂:重拾Border之——不仅仅是圆角

    前言 当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-to ...

  3. css直角线_css斜切角 斜边 倒角

    css斜切角 斜边 倒角 .m-test { width: 100px; height: 16px; background: linear-gradient(135deg, transparent 5 ...

  4. backgroundLinearGradient线性渐变制作折角效果

    backgroundLinearGradient线性渐变,制作折角效果 语法 线性渐变 - 从上到下(默认情况下) background: linear-gradient(direction, col ...

  5. CSS3实现精美的纸张折角效果 -- 进阶版

    改变的要素 昨天那个CSS3实现折角,需要到纯色背景下才能比较完美,今天就遇到问题了-背景是渐变的;所以改良一下; 适用于任何背景,控制::before和::after 两个案例,第一个是适用于任何背 ...

  6. html 怎么让div卷角,css实现简约的纸张卷角效果

    英文原文 http://designshack.net/articles/css/code-a-simple-folded-corner-effect-with-css/ 这篇文章中我们将介绍如何制做 ...

  7. css直角线_直角符号和垂直符号 过射线的端点和刚作的点,画射线

    是"Rt" 在 几何学和 三角学中,直角,又称正角,是角度为90度的角.它相对于四分之一个 圆周(即四分之一个圆形),而两个直角便等于一个 半角(180°). 角度比直角小的称为 ...

  8. css直角线_css3做圆角右边是圆角左边是直角?

    holdtom 问题:css3做圆角右边是圆角左边是直角 解答:注意css改动这里,nav ul li{ float:left; margin:0 20px; background-color:#99 ...

  9. CSS图片裁剪:实现切角效果

    img {border: 1px gray solid;width: 400px;height: 200px;clip-path: polygon(0 20px, 100% 0, 100% 100%, ...

  10. html中切角文本框,css实现切角效果

    1. 一个切角 思路:如果我们要得到有一个切角的元素,我们只需要使用一个径向渐变就可以达到这个目标,这个渐变需要把一个透明色标放在切角处,然后再相同的位置设置另一个色标,并且把它的颜色设置成我们想要的 ...

最新文章

  1. 盘点:近两年人工智能和机器学习领域部分收购案
  2. 卷积神经网络(Convolutional Neural Networks,CNNS/ConvNets)
  3. css --- 使用scss生成常用的基本css样式
  4. 使用 Pandas 分析 Apache 日志
  5. 苹果电脑上超级好用的双栏文件管理器Commander One PRO版推荐给大家!
  6. Python列表:list
  7. Vue2.0 探索之路——生命周期和钩子函数
  8. 洛谷 P1137 旅行计划
  9. AMESim软件建模
  10. [转载] 4.Pandas处理丢失数据
  11. 玩转Android Camera开发(一):Surfaceview预览Camera,基础拍照功能完整demo
  12. redis,memcache二者的区别
  13. Oracle数据库学习
  14. 华为ICT认证是什么意思?
  15. Android吉他调音器,吉他调音器:GuitarTuna
  16. 系统运行时间校准的重要性
  17. 页面可视化搭建工具技术要点
  18. Ionic入门学习(一)
  19. 【Collaborative Perception - 2】V2X-ViT(ECCV2022)
  20. 面试官:为啥要axios 的二次封装呢 及其使用是干啥的

热门文章

  1. 两阶段最小二乘法原理_什么是两阶段最小二乘法(2sls)?
  2. mac怎么无线打印机连接到服务器,Mac如何连接打印机-Mac连接打印机教程 - 河东软件园...
  3. 《东周列国志》第三十一回 晋惠公怒杀庆郑 介子推割股啖君
  4. 2018 初入IT十年(上)----成为一名优秀的程序员
  5. linux启动盘恢复成普通U盘,u盘启动盘还原普通u盘win10 制作
  6. mybatis事务处理
  7. 高德地图获取经纬度、高德地图坐标转为百度地图坐标
  8. PRAM模型与Amdahl定律
  9. 大数据查询怎么优化?
  10. PowerPoint放映时的动画怎么取消?