天天看點

【LESS系列】三角形Mixins

又是一篇自 W3CPLUS 中轉化而來的文章。

和 W3CPLUS 上的做法,在設計上最大的不同就在于,這裡我用的是多個 Mixins 函數來實作。

先總結這種做法的特點:

需要額外的标簽來實作,是以可以在同一容器中插入多個三角,并且支援低版本浏覽器

使用 Mixins 函數名來區分不同的三角,每個 Mixins 函數固定包含4個參數,規律已經在代碼注釋中說明,還是很好掌握的

P 字首開頭的是名義私有 Mixins ,供庫本身調用。雖然也能外部調用,但實際意義不大。

因為我不想用太多的參數來區分不同的三角,覺得用  Mixins 函數名來區分更為直覺、好記,是以也沒有用的名義私有 Mixins,而不是通過控制作用域來實作真正的私有 Mixins。

多個 Mixins 函數的實作方式還有個好處,就是每個 Mixins 函數的實作都很簡單直覺,沒有很複雜的邏輯,是以閱讀起來感覺也是相對輕松點。

功能不算特别豐富,但基本能滿足日常對與三角的使用。如果想要 just mobile ,且不需要同一容器中插入多個三角,可以改造成僞元素版,相信這對 LESS Developer 來說并不是難事。

/* LESS triangle Mixins 代碼,命名為triangle.less */
/*
triangle 系列 Mixins
Mixins 名稱中的 left ,right ,top ,bottom 描述的是三角形中90度的那個角的指向
凡是帶 P 字首的 Mixins 函數,都是名義私有 Mixins 函數,雖然也能調用,但單獨調用它并無實質意義...

參數說明:
@size【必傳】
三角的大小

@color【必傳】
三角的顔色

@offsetSide【必傳】
調整位置的比對模式
如果 Mixins 名稱是以 top 或者 bottom 為結尾,那此參數就調整水準位置,對應取值分别為 left 或者 right
如果 Mixins 名稱是以 left 或者 right 為結尾,那此參數就調整垂直位置,對應取值分别為 top 或者 bottom

@offset
三角的位置,根據 @offsetSide 參數的取值,以對應的 CSS 屬性調整三角形的所在位置
*/
.P-triangle-el-simple(){
  display: block;
  width: 0;
  height: 0;
  position: absolute;
}

.P-triangle(@size){
  border: (@size / 2) solid transparent;
}

.P-triangle-border(left){
  border-color: transparent @color transparent transparent;
  border-left-width: 0;
}

.P-triangle-border(right){
  border-color: transparent transparent transparent @color;
  border-right-width: 0;
}

.P-triangle-border(top){
  border-color: transparent transparent @color transparent;
  border-top-width: 0;
}

.P-triangle-border(bottom){
  border-color: @color transparent transparent transparent;
  border-bottom-width: 0;
}

.P-triangle-border(leftTop){
  border-top: @size solid @color;
  border-left: 0 solid transparent;
}

.P-triangle-border(rightTop){
  border-top: @size solid @color;
  border-right: 0 solid transparent;
}

.P-triangle-border(leftBottom){
  border-bottom: @size solid @color;
  border-left: 0 solid transparent;
}

.P-triangle-border(rightBottom){
  border-bottom: @size solid @color;
  border-right: 0 solid transparent;
}



.triangle-left(@size, @color, top, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(left);
  right: 100%;
  top: @offset;
}

.triangle-left(@size, @color, bottom, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(left);
  right: 100%;
  bottom: @offset;
}

.triangle-inner-left(@size, @color, top, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(left);
  right: 0;
  top: @offset;
}

.triangle-inner-left(@size, @color, bottom, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(left);
  right: 0;
  bottom: @offset;
}

.triangle-right(@size, @color, top, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(right);
  left: 100%;
  top: @offset;
}

.triangle-right(@size, @color, bottom, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(right);
  left: 100%;
  bottom: @offset;
}

.triangle-inner-right(@size, @color, top, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(right);
  left: 0;
  top: @offset;
}

.triangle-inner-right(@size, @color, bottom, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(right);
  left: 0;
  bottom: @offset;
}

.triangle-top(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(top);
  bottom: 100%;
  left: @offset;
}

.triangle-top(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(top);
  bottom: 100%;
  right: @offset;
}

.triangle-inner-top(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(top);
  bottom: 0;
  left: @offset;
}

.triangle-inner-top(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(top);
  bottom: 0;
  right: @offset;
}

.triangle-bottom(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(bottom);
  top: 100%;
  left: @offset;
}

.triangle-bottom(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(bottom);
  top: 100%;
  right: @offset;
}

.triangle-inner-bottom(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(bottom);
  top: 0;
  left: @offset;
}

.triangle-inner-bottom(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size);
  .P-triangle-border(bottom);
  top: 0;
  right: @offset;
}

.triangle-left-top(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftTop);
  top: 100%;
  left: @offset;
}

.triangle-left-top(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftTop);
  top: 100%;
  right: @offset;
}

.triangle-inner-left-top(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftTop);
  top: 0;
  left: @offset;
}

.triangle-inner-left-top(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftTop);
  top: 0;
  right: @offset;
}

.triangle-right-top(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightTop);
  top: 100%;
  left: @offset;
}

.triangle-right-top(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightTop);
  top: 100%;
  right: @offset;
}

.triangle-inner-right-top(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightTop);
  top: 0;
  left: @offset;
}

.triangle-inner-right-top(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightTop);
  top: 0;
  right: @offset;
}

.triangle-left-bottom(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftBottom);
  bottom: 100%;
  left: @offset;
}

.triangle-left-bottom(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftBottom);
  bottom: 100%;
  right: @offset;
}

.triangle-inner-left-bottom(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftBottom);
  bottom: 0;
  left: @offset;
}

.triangle-inner-left-bottom(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(leftBottom);
  bottom: 0;
  right: @offset;
}

.triangle-right-bottom(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightBottom);
  bottom: 100%;
  left: @offset;
}

.triangle-right-bottom(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightBottom);
  bottom: 100%;
  right: @offset;
}

.triangle-inner-right-bottom(@size, @color, left, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightBottom);
  bottom: 0;
  left: @offset;
}

.triangle-inner-right-bottom(@size, @color, right, @offset: 0){
  .P-triangle-el-simple();
  .P-triangle(@size * 2);
  .P-triangle-border(rightBottom);
  bottom: 0;
  right: @offset;
}      
/* 執行個體要用到的LESS代碼 */
@import "triangle.less";
body {
  background: #fff;
}
.wrap-a, .wrap-b{
  display: inline-block;
  background: #f36;
  margin: 20px;
  padding: 10px;
  width: 240px;
  height: 45px;
  line-height: 45px;
  color: #fff;
  text-align: center;
  position: relative;
}
.wrap-b{
  background: #ff0;
  color: #f36;
}

.top-l{
  .triangle-top(20px, #f36, left);
}
.left-b{
  .triangle-left(20px, #f36, bottom);
}
.bottom-r{
  .triangle-bottom(20px, #f36, right);
}
.right-t{
  .triangle-right(20px, #f36, top);
}
.top-r{
  .triangle-top(20px, #f36, right);
}
.left-t{
  .triangle-left(20px, #f36, top);
}
.bottom-l{
  .triangle-bottom(20px, #f36, left);
}
.right-b{
  .triangle-right(20px, #f36, bottom);
}

.top-i-l{
  .triangle-inner-top(20px, #f36, left);
}
.left-i-b{
  .triangle-inner-left(20px, #f36, bottom);
}
.bottom-i-r{
  .triangle-inner-bottom(20px, #f36, right);
}
.right-i-t{
  .triangle-inner-right(20px, #f36, top);
}
.top-i-r{
  .triangle-inner-top(20px, #f36, right);
}
.left-i-t{
  .triangle-inner-left(20px, #f36, top);
}
.bottom-i-l{
  .triangle-inner-bottom(20px, #f36, left);
}
.right-i-b{
  .triangle-inner-right(20px, #f36, bottom);
}

.leftTop-r{
  .triangle-left-top(20px, #f36, right);
}
.rightTop-l{
  .triangle-right-top(20px, #f36, left);
}
.leftBottom-r{
  .triangle-left-bottom(20px, #f36, right);
}
.rightBottom-l{
  .triangle-right-bottom(20px, #f36, left);
}
.leftTop-l{
  .triangle-left-top(20px, #f36, left);
}
.rightTop-r{
  .triangle-right-top(20px, #f36, right);
}
.leftBottom-l{
  .triangle-left-bottom(20px, #f36, left);
}
.rightBottom-r{
  .triangle-right-bottom(20px, #f36, right);
}

.leftTop-i-r{
  .triangle-inner-left-top(20px, #f36, right);
}
.rightTop-i-l{
  .triangle-inner-right-top(20px, #f36, left);
}
.leftBottom-i-r{
  .triangle-inner-left-bottom(20px, #f36, right);
}
.rightBottom-i-l{
  .triangle-inner-right-bottom(20px, #f36, left);
}
.leftTop-i-l{
  .triangle-inner-left-top(20px, #f36, left);
}
.rightTop-i-r{
  .triangle-inner-right-top(20px, #f36, right);
}
.leftBottom-i-l{
  .triangle-inner-left-bottom(20px, #f36, left);
}
.rightBottom-i-r{
  .triangle-inner-right-bottom(20px, #f36, right);
}      
<!-- 執行個體要用到的HTML代碼,引入的CSS是上面兩個LESS編譯生成出的CSS檔案 -->
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>test</title>
    <link type="text/css" rel="stylesheet" href="test.css">
</head>
<body>
<div class="wrap-a">
    EL1
    <i class="top-r"></i>
    <i class="left-t"></i>
    <i class="bottom-l"></i>
    <i class="right-b"></i>
</div>

<div class="wrap-a">
    EL2
    <i class="top-l"></i>
    <i class="left-b"></i>
    <i class="bottom-r"></i>
    <i class="right-t"></i>
</div>

<div class="wrap-b">
    EL3
    <i class="top-i-r"></i>
    <i class="left-i-t"></i>
    <i class="bottom-i-l"></i>
    <i class="right-i-b"></i>
</div>

<div class="wrap-b">
    EL4
    <i class="top-i-l"></i>
    <i class="left-i-b"></i>
    <i class="bottom-i-r"></i>
    <i class="right-i-t"></i>
</div>

<div class="wrap-a">
    EL5
    <i class="leftTop-r"></i>
    <i class="rightTop-l"></i>
    <i class="leftBottom-r"></i>
    <i class="rightBottom-l"></i>
</div>

<div class="wrap-a">
    EL6
    <i class="leftTop-l"></i>
    <i class="rightTop-r"></i>
    <i class="leftBottom-l"></i>
    <i class="rightBottom-r"></i>
</div>

<div class="wrap-b">
    EL7
    <i class="leftTop-i-r"></i>
    <i class="rightTop-i-l"></i>
    <i class="leftBottom-i-r"></i>
    <i class="rightBottom-i-l"></i>
</div>

<div class="wrap-b">
    EL8
    <i class="leftTop-i-l"></i>
    <i class="rightTop-i-r"></i>
    <i class="leftBottom-i-l"></i>
    <i class="rightBottom-i-r"></i>
</div>
</body>
</html>      

最後補一發效果圖:

【LESS系列】三角形Mixins