• 记录--纯CSS实现骚气红丝带


    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

    在本文中,我们将探讨如何使用 CSS 以最少的代码创造出精美的 CSS 丝带形状,并最终实现下面这个效果:

    下面我们使用html和css来实现这个效果。我们使用内容自适应方式布局,不用担心里面的文字长度。本文介绍两种丝带:左侧的丝带称为“折叠丝带”,右侧的丝带称为“旋转丝带”。

    通过CSS创建折叠丝带形状

    首先要实现折叠 CSS 丝带,先定义形状的变量。

    1. .ribbon {
    2.   --r: 20px; /* 控制丝带的切割效果 */
    3.   --s: 20px; /* 折叠部分的尺寸 */
    4.   --c: #d81a14/* 颜色控制 */
    5. }

    --r--s这两个变量控制形状,--c控制颜色。

    如果要在CSS中实现多边形,我们可以使用css的 clip-path 属性。我们提前在图形上添加一些填充内容避免文本被切割,然后使用clip-path

    1. .ribbon {
    2.   --r: 20px; /* 控制丝带的切割效果 */
    3.   --s: 20px; /* 折叠部分的尺寸 */
    4.   --c: #d81a14/* 颜色控制 */
    5.   line-height: 1.6/* 控制高度 */
    6.   padding-inline: 1.2lh calc(var(--r) + .2lh);
    7.   background: var(--c);
    8.   clip-path: polygon(1lh 01000, calc(100% - var(--r)) 50%, 100100%, 100100%, 0 100%, 0 100%);
    9. }

    使用 CSS lh 单位

    很多同学可能不知道 lh 单位是什么,它是与 line-height 值相对应的新单位。由于这里使用了一行文本,所以设置 line-height 来控制元素的高度,因此 1lh 就等于元素的高度。所以在 clip-path 中,我们使用这个高度来切割等腰三角形的形状。如下图:

    接着我们需要创建折叠部分,需要使用 clip-path 更新上面的多边形。 clip-path 可以切割元素边界的外部区域,包括盒子阴影、轮廓、伪元素等。

    在下面示例中,利用 box-shadow 配合clip-path 来实现切割。通过更新 XiYi 来切割多边形的四个新点,其中三个点位于元素的外部区域。因为我们要切割的部分在外部,但是它是不可见的,这里我们添加了大的 box-shadow 让元素变得可见。代码如下:

    1. .ribbon {
    2.   --r: 20px; /* 控制丝带的切割效果 */
    3.   --s: 20px; /* 折叠部分的尺寸 */
    4.   --c: #d81a14/* 颜色控制 */
    5.   line-height: 1.6/* 控制高度 */
    6.   padding-inline: 1.2lh calc(var(--r) + .2lh);
    7.   background: var(--c);
    8.   clip-path: polygon(1lh 01000, calc(100% - var(--r)) 50%, 100100%, 1lh 100%, 1lh calc(100+ var(--s)), .5lh calc(100+ var(--s) + var(--r)), 0 calc(100+ var(--s)), 0 100%);
    9.   box-shadow: 0 0 0 999px var(--c); /* 较大的阴影扩散半径 */
    10. }

    最后通过引入渐变和另一个框阴影,就实现了阴影效果。到这里我们的 CSS 丝带形状已经成型了。

    现在介绍如何创建第二种形状(绿色丝带)。这里使用相同的方法,用第一个多边形并将其反转一下。

    这样写:

    clip-path: polygon(X1 Y1, X2 Y2, ..., Xn Yn)
    

    要获得相反的形状,我们将所有 Xi 更改为 100% - Xi!在查看代码之前,大家尝试单独使用第一个形状的多边形来实现这一点。

    在上面的动画中,当鼠标悬停在形状上时,可以看到漂亮的展开收起动画。为了实现这一点,需要通过偏移一些点来更新悬停时的多边形。这里不需要重新编写整个多边形,可以重新定义一个 CSS 变量来控制偏移。

    如果大家关注动画部分,就会注意到有三个点向左移动,同时有三个点向下和向左移动。

    修改 Xi 的点向左移动,修改 Yi 的点向下和向左移动来实现这一点。然后再修改 d 以控制这一运动:

    1. .ribbon {
    2.   --d: 0px; /* 这将控制偏移量 */
    3.   clip-path: polygon(calc(1lh + var(--d)) 01000, calc(100% - var(--r)) 50%, 100100%, calc(1lh + var(--d)) 100%, calc(1lh + var(--d)) calc(100+ var(--s) + var(--d)), calc(.5lh + var(--d)) calc(100+ var(--s) + var(--r) + var(--d)), var(--d) calc(100+ var(--s) + var(--d)), var(--d) 100%);
    4. }
    5. .ribbon:hover {
    6.   --d: .2lh;
    7. }

    部分同学第一次看到这种多边形,可能会感到困惑,因为它看起来有些复杂。我们从一个简单的多边形开始,然后逐步添加更多点和计算,最终得到这个复杂的多边形。

    创建旋转的 CSS 丝带形状

    现在让我们处理第二种形状。对于这种形状,我们将使用新的三角函数以及 CSS 变量和 calc(),方法与前一个形状类似。为了理解这个形状背后的逻辑,让我们旋转它并确保文本保持在一条直线上。

    下面添加了一些透明度以查看主要元素背后的部分,然后使用伪元素来创建这些部分。这里添加了蓝色轮廓来说明元素的区域。该形状将由两个变量控制:

    1. .ribbon {
    2.   --r: 30px;  /* 控制丝带的切割效果 */
    3.   --a: 15deg; /* 控制旋转角度 */
    4. }

    其中 r 的作用与前一个形状相同。a 将控制主要元素的旋转。

    下面我们从主要元素开始说。从图中我们可以看到,我们需要从每一面切割它,但是这次不能使用 clip-path,我们将使用渐变颜色,其中需要切割的部分需要使用透明的颜色:

    1. .ribbon {
    2.   --r: 30px;  /* 控制丝带的切割效果 */
    3.   --a: 15deg; /* 控制旋转角度 */
    4.   background:
    5.     linear-gradient(calc(90deg + var(--a)),
    6.       #0000 calc(1lh*sin(var(--a))),
    7.       var(--c) 0 calc(100% - 1lh*sin(var(--a))),
    8.       #0000 0
    9.     );
    10. }
    效果如图:

    这里的高度等于 1lh/cos(a)。宽度等于 (100% - x)*cos(a),其中 100% 是主要元素的宽度,x 是我们带有透明度的那一小部分,它等于 1lh*tan(a)

    两个伪元素具有相同的尺寸,代码如下:

    1. .ribbon:before,
    2. .ribbon:after {
    3.   content"";
    4.   position: absolute;
    5.   heightcalc(1lh/cos(var(--a)));
    6.   widthcalc(100%*cos(var(--a)) - 1lh*sin(var(--a)));
    7. }

    在确定尺寸后,我们需要正确定位每个伪元素,并对其进行旋转和切割:

    1. .ribbon:before,
    2. .ribbon:after {
    3.   content"";
    4.   position: absolute;
    5.   transformtranslate3d(0,0,-1px);
    6.   rotate: var(--a);
    7.   heightcalc(1lh/cos(var(--a)));
    8.   widthcalc(100%*cos(var(--a)) - 1lh*sin(var(--a)));
    9.   background: color-mix
    10. (in srgb,var(--c),#000 40%);
    11. }
    12. h1:before {
    13.   right0;
    14.   top0;
    15.   transform-origin: top right;
    16.   clip-pathpolygon(0 0,100% 0,100% 100%,0 100%,var(--r) 50%);
    17. }
    18. h1:after {
    19.   left0;
    20.   bottom0;
    21.   transform-origin: bottom left;
    22.   clip-pathpolygon(0 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,0 100%);
    23. }

    这里代码应该比较清晰易懂,clip-path 的值应该也容易理解。要注意的是,我们使用了 color-mix() 函数,这个属性允许创建主颜色的深色版本。现在如果我们将元素旋转相反的方向,就会得到旋转的 CSS 丝带形状。

    完整代码

    1. <h1>I am a ribbon</h1>
    2. <h1 class="alt">I am a ribbon</h1>
    1. @property --a {
    2.   syntax: "";
    3.   initial-value: 0deg;
    4.   inherits: true;
    5. }
    6. h1 {
    7.   --r30px;  /* control the cutout of the ribbon */
    8.   --a15deg/* control the rotation (only positive values) */
    9.   --c#d81a14;
    10.   
    11.   line-height1.6/* this will control the height */
    12.   padding-inline: .5lh; /* OR calc(tan(var(--a))*1.5lh) */
    13.   color#fff;
    14.   background:
    15.     linear-gradient(calc(90deg + var(--a)),
    16.       #0000 calc(1lh*sin(var(--a)) - 1px),
    17.       var(--c) calc(1lh*sin(var(--a))) calc(100% - 1lh*sin(var(--a))),
    18.       #0000 calc(100% - 1lh*sin(var(--a)) + 1px)
    19.     );
    20.   position: relative;
    21.   rotate: calc(-1*var(--a));
    22.   transform-style: preserve-3d;
    23.   transition: --a .5s;
    24.   cursor: pointer;
    25.   white-space: nowrap;
    26. }
    27. h1.alt {
    28.   --c#8FBE00;
    29.   rotate: var(--a);
    30.   background:
    31.     linear-gradient(calc(90deg - var(--a)),
    32.       #0000 calc(1lh*sin(var(--a)) - 1px),
    33.       var(--c) calc(1lh*sin(var(--a))) calc(100% - 1lh*sin(var(--a))),
    34.       #0000 calc(100% - 1lh*sin(var(--a)) + 1px)
    35.     );
    36. }
    37. h1:before,
    38. h1:after{
    39.   content"";
    40.   position: absolute;
    41.   transformtranslate3d(0,0,-1px);
    42.   rotate: var(--a);
    43.   heightcalc(1lh/cos(var(--a)));
    44.   widthcalc(100%*cos(var(--a)) - 1lh*sin(var(--a))) ;
    45.   backgroundcolor-mix(in srgb,var(--c),#000 40%);
    46.   pointer-events: none;
    47. }
    48. h1.alt:before,
    49. h1.alt:after {
    50.   rotate: calc(-1*var(--a));
    51. }
    52. h1:before {
    53.   right0;
    54.   top0;
    55.   transform-origin: top right;
    56.   clip-pathpolygon(0 0,100% 0,100% 100%,0 100%,var(--r) 50%);
    57. }
    58. h1.alt:before {
    59.   bottom0;
    60.   top: auto;
    61.   transform-origin: bottom right;
    62. }
    63. h1:after {
    64.   left0;
    65.   bottom0;
    66.   transform-origin: bottom left;
    67.   clip-pathpolygon(0 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,0 100%);
    68. }
    69. h1.alt:after {
    70.   top0;
    71.   bottom: auto;
    72.   transform-origin: top left;
    73. }
    74. h1:hover {
    75.   --a0deg;
    76. }
    77. /* we fallback to something else if lh is not supported
    78.    1lh = 1.6em (the line-height value)
    79. */
    80. @supports not (height:1lh) {
    81.   h1 {
    82.     padding-inline: .8em
    83.     background:
    84.       linear-gradient(calc(90deg + var(--a)),
    85.         #0000 calc(1.6em*sin(var(--a)) - 1px),
    86.         var(--c) calc(1.6em*sin(var(--a))) calc(100% - 1.6em*sin(var(--a))),
    87.         #0000 calc(100% - 1.6em*sin(var(--a)) + 1px)
    88.       );
    89.   }
    90.   h1.alt {
    91.     background:
    92.       linear-gradient(calc(90deg - var(--a)),
    93.         #0000 calc(1.6em*sin(var(--a)) - 1px),
    94.         var(--c) calc(1.6em*sin(var(--a))) calc(100% - 1.6em*sin(var(--a))),
    95.         #0000 calc(100% - 1.6em*sin(var(--a)) + 1px)
    96.       );
    97.   }
    98.   h1:before,
    99.   h1:after{
    100.     heightcalc(1.6em/cos(var(--a)));
    101.     widthcalc(100%*cos(var(--a)) - 1.6em*sin(var(--a))) ;
    102.   }
    103. }
    104. body {
    105.   margin0;
    106.   min-height100vh;
    107.   display: grid;
    108.   place-content: center;
    109.   grid-auto-flow: column;
    110.   gap50px;
    111. }
    112. h1 {
    113.   font-family: sans-serif;
    114.   text-transform: uppercase;
    115.   font-size2.5rem;
    116. }

    本文转载于:

    https://juejin.cn/post/7288178532861345832

    如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

     

  • 相关阅读:
    IDEA Out of memory 问题
    4-SpringBoot架构设计与实现原理-SpringBoot自定义starter
    python 基于PHP+MySQL的驾校信息管理系统
    Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现
    账务处理程序、记账凭证账务处理程序、汇总记账凭证账务处理程序、科目汇总表账务处理程序、会计信息化概述、信息化环境下会计账务处理的基本要求(此章出1道小题)
    四元数插值
    day60
    数据库的三大范式(重要)
    Redis学习记录------Redis6的事务操作(九)
    数字人直播软件多少钱,数字人直播系统多少钱,真正赚钱的是?
  • 原文地址:https://blog.csdn.net/qq_40716795/article/details/133793755