We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
通常情况下,用 CSS 来实现一些简单的图形会比使用图片更有优势,譬如:
接下来介绍如何用 CSS 精确绘制三角形及其衍生图形。
所有元素都可以被描述为一个个矩形的盒子,盒子由 4 个部分组成:内容区域(content area)、内边距区域(padding area)、边框区域(border area)、外边距区域(margin area)。
一个边框宽度不为零的矩形元素是这样的:
<style> .box { width: 50px; height: 50px; border-width: 30px; border-style: solid; border-color: #07C160 #FA5151 #409eff #e6a23c; } </style> <div class="box"></div>
如果把 内容区域 的宽高都置为 0
<style> .box { /* ... */ width: 0; height: 0; } </style>
此时内容、内外边距区域都为空,盒模型相当于被等宽的边框区域瓜分成四个等腰直角三角形。那么,只需要将其他三个三角形都透明化,我们要的三角形就呼之欲出了。
<style> .triangle { width: 0; height: 0; border-width: 0 50px 50px 50px; border-style: solid; border-color: transparent transparent #409eff transparent; } </style> <div class="triangle"></div>
PS:假如我们只需要下方的三角形,那么上边框是没有起任何作用的,不妨也将其置为 0。
我们可以通过 调整各边框的宽度,来控制三角形的形状。
在实心三角形的基础上,把两个大小不一的三角形叠在一起,就绘制出空心三角形了。
但这里其实是有讲究的,我们通常期望空心三角形的三边宽度是相等的,那么为了符合要求我们需要如何调整两个三角形的位置?偏移量又是多少呢?
这里利用伪元素来绘制第二个三角形:
<style> .hollow { position: relative; width: 0; height: 0; border-width: 0 50px 50px 50px; border-style: solid; border-color: transparent transparent #409eff transparent; } .hollow:before { content: ''; display: block; position: absolute; top: 0; left: 0; border-width: 40px; border-style: solid; border-color: transparent transparent #e6a23c transparent; } </style> <div class="hollow"></div>
对应的模型如下图所示,其中 内三角形 的坐标轴原点位于 外三角形 的顶点处(位于父元素的内容区域)。我们先挪动内三角形使两者的顶点重合,那么内三角形需要左移和上移各$H_{2}$像素。
然后调整内三角形在纵坐标轴上的位置。我们期望的最终效果是这样的
$A_{1}A_{2}$是待求的纵坐标偏移值
$$A_{1}A_{2} = \frac{x}{\sin ∠O} $$
由于内外三角形的三边都是分别平行的,我们可以建立等式
$$H_{1} = A_{1}A_{2} + H_{2} + x =\frac {\sin ∠O + 1}{\sin ∠O}x + H_{2} $$
求出$x$
$$x = \frac{\sin ∠O(H_{1} - H_{2})}{\sin ∠O + 1} $$
所以纵坐标轴上的总偏移量$S$为
$$S = 0 - H_{2} + A_{1}A_{2} = \frac{(H_{1} - H_{2})}{\sin ∠O + 1} - H_{2}$$
假设内外三角形都是等腰直角三角形,则$\sin ∠O = \frac {\sqrt 2}{2}$,那么总偏移量$S$为
$$S = \frac{\frac {\sqrt 2}{2} (H_{1} - H_{2})}{\frac {\sqrt 2}{2} + 1} - H_{2} = (2 - \sqrt 2)(H_{1} - H_{2}) - H_{2}$$
将 demo 中的参数$H_{1} = 50$,$H_{2} = 40$代入方程式,求得
$$S = (2 - \sqrt 2)\times 10-40 \approx -34$$
所以横坐标偏移量为 -40px,纵坐标偏移量为 -34px。
-40px
-34px
箭头的实现原理和空心三角形如出一辙,只是得顺便把外三角形的下边给覆盖住,因此这里 把 内三角形 的边框宽度调整为与 外三角形 的相等(或者与 外三角形 的边框宽度相近即可)。
我们期望的最终模型是这样的
我们最终需要关心的是$x$的值,它代表着箭头的宽度。假设我们需要绘制 1px 宽的箭头
$$x = A_{1}A_{2}\sin ∠O = 1$$
参考对空心三角形纵轴偏移值的计算,纵轴上的总偏移量$S$为
$$S = 0 - H_{2} + A_{1}A_{2} = \frac {1}{\sin ∠O} - H_{2}$$
$$S = \sqrt 2 - H_{2}$$
将 demo 中的参数$H_{2} = 40$代入方程式,求得
$$S = \sqrt 2 - 40 \approx -39$$
所以横坐标偏移量为 -50px,纵坐标偏移量为 -49px。
-50px
-49px
<style> .arrow { position: relative; width: 0; height: 0; border-width: 0 50px 50px 50px; border-style: solid; border-color: transparent transparent #409eff transparent; } .arrow:before { content: ''; display: block; position: absolute; top: -49px; left: -50px; border-width: 50px; border-style: solid; border-color: transparent transparent #fff transparent; } </style> <div class="arrow"></div>
等腰直角箭头 无非就是正方形的两条邻边,我们只需要将另外两条邻边透明化,同时按需求旋转图形指向就可以了。
这里继续利用伪元素实现。为了优化元素的可用性,我们使伪元素的宽高百分比于父元素,建立以下模型
那么,伪元素的宽度和父元素宽度的关系为
$$W_{伪} = \frac{\sqrt 2}{2}W \approx 0.7W$$
<style> .arrow { position: relative; width: 50px; height: 50px; } .arrow:before { content: ''; display: block; position: absolute; top: 0; left: 50%; width: 70%; height: 70%; border-width: 1px; border-style: solid; border-color: #409eff transparent transparent #409eff; transform: rotate(45deg); transform-origin: 0 0; } </style> <div class="arrow"></div>
所有 demo 详见:https://codepen.io/JunreyCen/pen/LovdaM
PS: 文章首发于 简书 ,欢迎大家关注。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
通常情况下,用 CSS 来实现一些简单的图形会比使用图片更有优势,譬如:
...
接下来介绍如何用 CSS 精确绘制三角形及其衍生图形。
盒模型
所有元素都可以被描述为一个个矩形的盒子,盒子由 4 个部分组成:内容区域(content area)、内边距区域(padding area)、边框区域(border area)、外边距区域(margin area)。
一个边框宽度不为零的矩形元素是这样的:
如果把 内容区域 的宽高都置为 0
此时内容、内外边距区域都为空,盒模型相当于被等宽的边框区域瓜分成四个等腰直角三角形。那么,只需要将其他三个三角形都透明化,我们要的三角形就呼之欲出了。
实心三角形
我们可以通过 调整各边框的宽度,来控制三角形的形状。
空心三角形
在实心三角形的基础上,把两个大小不一的三角形叠在一起,就绘制出空心三角形了。
但这里其实是有讲究的,我们通常期望空心三角形的三边宽度是相等的,那么为了符合要求我们需要如何调整两个三角形的位置?偏移量又是多少呢?
这里利用伪元素来绘制第二个三角形:
对应的模型如下图所示,其中 内三角形 的坐标轴原点位于 外三角形 的顶点处(位于父元素的内容区域)。我们先挪动内三角形使两者的顶点重合,那么内三角形需要左移和上移各$H_{2}$像素。
然后调整内三角形在纵坐标轴上的位置。我们期望的最终效果是这样的
由于内外三角形的三边都是分别平行的,我们可以建立等式
求出$x$
所以纵坐标轴上的总偏移量$S$为
假设内外三角形都是等腰直角三角形,则$\sin ∠O = \frac {\sqrt 2}{2}$,那么总偏移量$S$为
将 demo 中的参数$H_{1} = 50$,$H_{2} = 40$代入方程式,求得
所以横坐标偏移量为
-40px
,纵坐标偏移量为-34px
。箭头
箭头的实现原理和空心三角形如出一辙,只是得顺便把外三角形的下边给覆盖住,因此这里 把 内三角形 的边框宽度调整为与 外三角形 的相等(或者与 外三角形 的边框宽度相近即可)。
我们期望的最终模型是这样的
我们最终需要关心的是$x$的值,它代表着箭头的宽度。假设我们需要绘制 1px 宽的箭头
参考对空心三角形纵轴偏移值的计算,纵轴上的总偏移量$S$为
假设内外三角形都是等腰直角三角形,则$\sin ∠O = \frac {\sqrt 2}{2}$,那么总偏移量$S$为
将 demo 中的参数$H_{2} = 40$代入方程式,求得
所以横坐标偏移量为
-50px
,纵坐标偏移量为-49px
。实现等腰直角箭头的另一种方式
等腰直角箭头 无非就是正方形的两条邻边,我们只需要将另外两条邻边透明化,同时按需求旋转图形指向就可以了。
这里继续利用伪元素实现。为了优化元素的可用性,我们使伪元素的宽高百分比于父元素,建立以下模型
那么,伪元素的宽度和父元素宽度的关系为
所有 demo 详见:https://codepen.io/JunreyCen/pen/LovdaM
Reference
PS: 文章首发于 简书 ,欢迎大家关注。
The text was updated successfully, but these errors were encountered: