为了提高码农的开发效率,现在在线上有很多在线小工具,这些小工具可以帮助大家快速实现自己需要的效果,并且可以生成可用代码。前几天看到一个制作三角的小工具,尝试着使用Sass来将其转换成可用的混合宏。尝试成功,来说说怎么实现的。其实只要你有时间,很多小工具都可以用类似的方法来实现。
Caret是Lugo Labs分享的一个制作三角形的在线小工具,在这个小工具中,你只要修改几个参数,就能生成你需要的三角形,如图:
来简单的看一个示例,我们调整几个小参数:
自动就会生成所需的三角形代码:
.caret {
position: relative;
}
.caret:before {
content: '';
position: absolute;
top: 0;
left: 0;
border-top: 50px solid #9a1b1b;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
}
.caret:after {
content: '';
position: absolute;
left: 5px;
top: 0;
border-top: 45px solid #ece6e1;
border-left: 45px solid transparent;
border-right: 45px solid transparent;
}
实现原理这里就不多说了,就是使用border
和伪类:after
、:before
来实现。
从Caret小工具中可以非常明显的得知,制作三角形只需要五个参数:
top
、right
、bottom
和left
四个方向文章开头的图中,可以获悉,三角形分为两种,一种是实心三角形,另一种是空心三角形。当边框大小和Caret宽度相等时三角形呈一个实心三角形,另外当背景颜色和边框颜色相同时,也会呈实心三角形。只有这两种情形都不具备之时,才会是一个空心三角形。
如果要实现一个类似于caret工具的混合宏,也需要给这个混合宏传相同的参数。假设定义的混合宏名caret
,给混合宏传递的参数有:
$caret-width
:用来设置三角形的大小$border-width
:设置边框的大小$direction
:设置三角形方向$border-color
:设置边框的颜色$background-color
:设置背景颜色除此之外,在工具的基础我们添加另一个参数$position
用来控制三角形的定位形式。
如此一来,caret
的混合宏所传的参数就有六个:
@mixin caret($position, $caret-width, $border-width, $direction, $border-color, $background-color){
...
}
三角形在Web使用中常见的地方,主要会有:
制作三角形都是依赖于元素的伪类:before
和:after
来实现,而且都是通过绝对定位来控制三角形。
@mixin caret($position,$caret-width,$border-width,$direction,$border-color,$background-color){
position: $position;
&:before,
&:after {
content:"";
position: absolute;
}
}
注:由于我们三角形同时需要实现空心和实心两种三角形风格,因此在这个混合宏中同时使用了:before
和:after
。
三角形方向有四种方向,因此使用Sass的@if{}@else if{}
根据$direction
参数传的值来判断三角形的方向。而且每个方向的不同时,对应的CSS属性top
、left
、border
值不一样。共中最为关键的是border
中的border-width
和border-color
。
由于三角形有空心和实心之分,所以在计算boder-width
的值时,是通过混合宏中$caret-width
和$border-width
差值来决定。
$caret-width - $border-width
当其值为0
时,生成的三角形是实现三角形,反之将是空心三角形。
对于空心三角表,则通过:before
和:after
层叠造成的一个假像来实现,如下图:
上图演示的是向下三角形,那么根据$direction
传递的参数,根据同样的原理,可以得到:
@mixin caret($position,$caret-width,$border-width,$direction,$border-color,$background-color){
position: $position;
&:before,
&:after {
content:"";
position: absolute;
}
@if $direction == top {
&:before {
top:0;
left: 0;
border-bottom: $caret-width solid $border-color;
border-left: $caret-width solid transparent;
border-right: $caret-width solid transparent;
}
&:after {
left: $border-width;
top: $border-width;
border-bottom: ($caret-width - $border-width) solid $background-color;
border-left: ($caret-width - $border-width) solid transparent;
border-right: ($caret-width - $border-width) solid transparent;
}
}
@else if $direction == right {
&:before {
top:0;
left: 0;
border-left: $caret-width solid $border-color;
border-top: $caret-width solid transparent;
border-bottom: $caret-width solid transparent;
}
&:after {
left: 0;
top: $border-width;
border-left: ($caret-width - $border-width) solid $background-color;
border-top: ($caret-width - $border-width) solid transparent;
border-bottom: ($caret-width - $border-width) solid transparent;
}
}
@else if $direction == bottom {
&:before {
top:0;
left: 0;
border-top: $caret-width solid $border-color;
border-left: $caret-width solid transparent;
border-right: $caret-width solid transparent;
}
&:after {
left: $border-width;
top: 0;
border-top: ($caret-width - $border-width) solid $background-color;
border-left: ($caret-width - $border-width) solid transparent;
border-right: ($caret-width - $border-width) solid transparent;
}
}
@else if $direction == left {
&:before {
top:0;
left: 0;
border-right: $caret-width solid $border-color;
border-top: $caret-width solid transparent;
border-bottom: $caret-width solid transparent;
}
&:after {
left: $border-width;
top: $border-width;
border-right: ($caret-width - $border-width) solid $background-color;
border-top: ($caret-width - $border-width) solid transparent;
border-bottom: ($caret-width - $border-width) solid transparent;
}
}
}
混合宏完成了,实战一回。
假设你需要制作一个tips,可以简单的像这样使用:
HTML
<div class="tips">
<span class="caret"></span>
我是一个tooltip
</div>
SCSS
.tips {
width: 200px;
height: 50px;
line-height: 50px;
text-align: center;
position: relative;
margin: 20px auto;
border: 1px solid orange;
border-radius: 3px;
.caret {
top: -10px;
left: 10px;
@include caret(absolute,10px,1px,top,orange,#fff);
}
}
效果
下面的示例中,演示了其他几种三种形式:
使用Sass实现三角形的方案多种,但这篇文章仅仅是想向大家介绍的是如何使用Sass这样的预处理器,将在线的小工具转换成实用的混合宏。如果您对此感兴趣,可以自己动手试试别的小工具。欢迎在下面的评论中与我们一起分享你定义的混合宏。