谈谈如何利用 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)

相关推荐
倔强青铜三28 分钟前
苦练Python第69天:subprocess模块从入门到上瘾,手把手教你驯服系统命令!
人工智能·python·面试
倔强青铜三33 分钟前
苦练 Python 第 68 天:并发狂飙!concurrent 模块让你 CPU 原地起飞
人工智能·python·面试
被制作时长两年半的个人练习生3 小时前
近期的笔试和面试的复盘
算法·面试·职场和发展·算子
爱吃KFC的大肥羊4 小时前
第二次面试:C++qt开发实习生
面试·职场和发展
GL-Yang4 小时前
2025年-集合类面试题
java·面试
黄昏恋慕黎明5 小时前
JVM虚拟机(面试重)
jvm·面试·职场和发展
-睡到自然醒~5 小时前
[go 面试] 并发与数据一致性:事务的保障
数据库·面试·golang
Dolphin_海豚5 小时前
@vue/reactivity
前端·vue.js·面试
怪兽20145 小时前
请谈谈什么是同步屏障?
android·面试
尘世中一位迷途小书童5 小时前
版本管理实战:Changeset 工作流完全指南(含中英文对照)
前端·面试·架构