谈谈如何利用 CSS 的 border 属性绘制三角形

绘制三角形

如图所示, 我们构造一个宽高都为 50pxdiv 元素(图中的白色盒子),并将边框宽度 设置为:上边框 80px、下边框 40px、左边框100px、右边框 50px

代码如下

html 复制代码
<div id="box">
   <span>50px</span>
</div>

<style>
 #box {
      width: 50px;
      height: 50px;
      line-height: 50px;
      text-align: center;
      border-top: 80px solid rgb(248, 180, 180);
      border-bottom: 40px solid rgb(155, 155, 255);
      border-left: 100px solid rgb(169, 255, 169);
      border-right: 50px solid yellow;
   }
</style>

这时,我们得到 4 个梯形 ,那么,怎么获得三角形 呢? 如果运用极限的思想三角形 可以看成是梯形一条边长度为 0 的结果。因此,我们尝试将 div 元素的宽高都设置为 0 ,即 width: 0height: 0

html 复制代码
<div id="box"></div>

<style>
 #box {
      width: 0;
      height: 0;
      line-height: 50px;
      text-align: center;
      border-top: 80px solid rgb(248, 180, 180);
      border-bottom: 40px solid rgb(155, 155, 255);
      border-left: 100px solid rgb(169, 255, 169);
      border-right: 50px solid yellow;
   }
</style>

我们成功获得了 4 个三角形:

那么,如何获得一个单独的三角形,比如左边这个绿色的三角形呢?这时候,我们就需要通过 transparent 这个 CSS 值将边框颜色设置为透明 ( transparent 的意思是 透明的 ):

html 复制代码
<div id="box"></div>

<style>
 #box {
      width: 0;
      height: 0;
      line-height: 50px;
      text-align: center;
      border-top: 80px solid tranparent;
      border-bottom: 40px solid transparent;
      border-left: 100px solid rgb(169, 255, 169);
      border-right: 50px solid transparent;
   }
</style>

成功了!

绘制直角三角形

但是,当我们想获得任意形状的三角形时,上面的思路显然不够简洁。怎么办呢?首先,让我们换个思路来看看这个绿色三角形的产生过程。

因为任意一个三角形都可以过顶点作对边的垂线,所以任意一个三角形都可以由两个直角三角形拼接而成。我们的问题便转化为了如何绘制任意直角三角形

让我们继续从上面的绿色三角形入手。左边三角形的 100px80px40px 分别来自左边框、上边框和下边框。我们如何从这个三角形出发,获得右上角的三角形呢?是的,我们可以再次运用极限 的思想,右上角的三角形相当于将下边框 的宽度设置为 0 : border-bottom: 0px solid transparent;

html 复制代码
<div id="box"></div>

<style>
 #box {
      width: 0;
      height: 0;
      border-top: 80px solid transparent;
      border-bottom: 0px solid transparent;
      border-left: 100px solid rgb(169, 255, 169);
      border-right: 50px solid transparent;
   }
</style>

更进一步,我们可以直接删除border-bottom 属性的声明:

html 复制代码
<div id="box"></div>

<style>
 #box {
      width: 0;
      height: 0;
      border-top: 80px solid transparent;
      border-left: 100px solid rgb(169, 255, 169);
      border-right: 50px solid transparent;
   }
</style>

当我们仔细观察代码的时候,可以发现右边框的 50px 并没有在图片中体现出来,让我们再试试删除 border-right 属性:

html 复制代码
<div id="box"></div>

<style>
 #box {
      width: 0;
      height: 0;
      border-top: 80px solid transparent;
      border-left: 100px solid rgb(169, 255, 169);
   }
</style>

依然可以。现在,让我们从代码反推回去,找找套路。假设我们想画一个直角三角形,我们可以从它的任意一个锐角顶点 出发,用一笔画的方法画出三角形。比如:

第一笔 ,向 画,对应左边框 被设置为有颜色border-left: 100px solid rgb(169, 255, 169);第二笔 ,向 画,对应上边框 颜色被设置为透明border-top: 80px solid transparent;

我们得出以下规律:

  1. 锐角顶点作为上下左右方向的参考点
  2. 往哪个方向画,就设置哪个方向的边框
  3. 第一笔对应的边框设置为有颜色;第二笔对应的边框颜色设置为透明

现在,我们可以随意画出一个三角形了:

html 复制代码
<div id="triangle"></div>
</div>

<style>
    #triangle {
        width: 0;
        height: 0;
        border-bottom: 80px solid greenyellow;
        border-left: 200px solid transparent;
        border-right: 20px solid transparent;
    }
</style>

旋转三角形

我们能够随心所欲地画出四平八稳 的三角形了。那么,如何画出斜着的三角形呢?这时候,transform: rotate() 就派上了用场。当然,除了 transform,我们还需要 transform-origin 来确定旋转中心。如下图,我们想将绿色三角形旋转至红色三角形的位置,首先,我们取绿色三角形斜边的中心点作为参考点 (图中的黑色圆点),我们的旋转中心位于此参考点的右上方 ,因此,我们要设置 transform-origin: top right。同时,旋转角度为正时,图形按顺时针方向旋转 ,对于下图,我们设置的是transform: rotate(10deg)

于是,我们可以写出以下代码:

html 复制代码
<div id="rotate"></div>
</div>

<style>
    #rotate {
        width: 0;
        height: 0;
        border-bottom: 80px solid greenyellow;
        border-left: 200px solid transparent;
        transform: rotate(10deg);
        transform-origin: top right;
    }
</style>

结果如下

对于直角三角形,我们可以从三个顶点中任选一个作为旋转中心,但如果是非直角三角形 ,为了方便和确定性,旋转中心最好选取位于底边上的两个顶点。比如:

利用 transform-origin: bottom right 选择右下方的顶点作为旋转中心:

显然要比利用 transform-origin: top right 选择右上方的顶点作为旋转中心:

容易控制得多。

实际上,我们的旋转中心仍然是正方形/长方形盒子的顶点,只是有些顶点刚好跟三角形顶点重合了:

最终代码

html 复制代码
<div id="triangle"></div>
</div>

<style>
    #triangle {
        width: 0;
        height: 0;
        border-bottom: 80px solid greenyellow;
        border-left: 200px solid transparent;
        border-right: 20px solid transparent;
        transform: rotate(10deg);
        transform-origin: bottom right;
    }
</style>

大功告成!

参考资料

border-width (MDN)

transform (MDN)

rotate() (MDN)

transform-origin (MDN)

相关推荐
测试19985 小时前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
马剑威(威哥爱编程)5 小时前
MongoDB面试专题33道解析
数据库·mongodb·面试
独行soc8 小时前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
理想不理想v8 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
sszmvb12349 小时前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展
测试杂货铺9 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
王佑辉9 小时前
【redis】redis缓存和数据库保证一致性的方案
redis·面试
真忒修斯之船9 小时前
大模型分布式训练并行技术(三)流水线并行
面试·llm·aigc
ZL不懂前端9 小时前
Content Security Policy (CSP)
前端·javascript·面试
测试界萧萧10 小时前
外包干了4年,技术退步太明显了。。。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展