最近在设计页面的时候,用到了css布局中的一个Ribbon布局,样子如下图所示:

刚开始打算用这个样式作为文章的标题,后来暂时没有使用,但是在学习这个布局的时候,积累了很多css的知识,今天在此记录一下,方便以后查找温习。
首先,我贴出这部分代码的dom结构:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Ribbons设计 - 实例</title>
<link rel="stylesheet" type="text/css" href="./ribbon.css" />
</head>
<body>
<div class="ribbon">
<!-- The left side -->
<div class="ribbon__side ribbon__side--l"></div>
<!-- The left triangle displayed below the content -->
<div class="ribbon__triangle ribbon__triangle--l"></div>
<!-- The right triangle displayed below the content -->
<div class="ribbon__triangle ribbon__triangle--r"></div>
<!-- The right side -->
<div class="ribbon__side ribbon__side--r"></div>
<!-- The content -->
<div class="ribbon__content"></div>
</div>
</body>
</html>
然后再贴出对应的ribbon.css的代码
.ribbon {
/* Center the content */
align-items: center;
display: flex;
justify-content: center;
/* Size */
height: 2rem;
/* Use to position the corners */
position: relative;
width: 6rem;
margin : 6rem auto;
}
.ribbon__content {
/* Background color */
background-color: #9ca3af;
z-index: 1;
height: 100%;
width: 100%;
}
.ribbon__side {
bottom: -0.5rem;
position: absolute;
/* Displayed under the ribbon */
z-index: 1;
/* Background */
border: 1rem solid #d1d5db;
}
.ribbon__side--l {
/* Position */
left: -1.5rem;
border-color: #d1d5db #d1d5db #d1d5db transparent;
}
.ribbon__side--r {
/* Position */
right: -1.5rem;
border-color: #d1d5db transparent #d1d5db #d1d5db;
}
.ribbon__triangle {
position: absolute;
top: 100%;
border: 0.5rem solid transparent;
border-bottom-width: 0;
border-top-color: #1c1919;
z-index:2;
}
.ribbon__triangle--l {
border-right-width: 0;
left: 0;
}
.ribbon__triangle--r {
border-left-width: 0;
right: 0;
}
注释部分解释了各部分代码在实现这个样式的时候起到的作用。我们来具体分析和研究一下:
从这个ribbon的dom结构可以看出,它有最外部的容易.ribbony以及内部的五个部分组成,分别是左右的支出去的两部分结构,内容区下面的三角形以及具体的内容区组成。
首先看看这两个支出去的部分是怎么实现的呢?
它们的代码如下:
.ribbon__side {
bottom: -0.5rem;
position: absolute;
/* Displayed under the ribbon */
z-index: 1;
/* Background */
border: 1rem solid #d1d5db;
}
.ribbon__side--l {
/* Position */
left: -1.5rem;
border-color: #d1d5db #d1d5db #d1d5db transparent;
}
.ribbon__side--r {
/* Position */
right: -1.5rem;
border-color: #d1d5db transparent #d1d5db #d1d5db;
}
我们知道父元素是相对定位(position:relative)
,而这里的两个元素采用了绝对定位,而共同点是bottom:0.5rem
;然后一个向左,一个向右,分别都是-1.5rem;最后都设置border为1rem;并且border有三个方向有颜色,而一个方向透明,显然,如果是左边支出的那部分,显然是左边的border-color为透明的颜色,按照上右下左的原理,border-color: #d1d5db #d1d5db #d1d5db transparent;
的最左边的颜色为透明。同样的到来,右边支出的部分应该是右方的颜色为透明,同理按照上右下左的原理,border-color: #d1d5db transparent #d1d5db #d1d5db;
最右边的颜色为透明。
至于这里为什么这样设置border就会出现这样的形状呢?可以参考这篇文章(css绘制三角形原理-border)
简单说明一下:
.t2 {
width: 50px;
height: 50px;
border: 2px solid orange;
}

我们使用border的时候一般只是小小的一段,大家可能会觉得border是有四个小矩形拼接而成;然而实际上呢?请看下面的例子:
.t2 {
width: 100px;
height: 100px;
border: 40px solid;
border-color: orange blue red green;
}

我们可以看到明显的border的四条边不是长方形,而是梯形,很像相框的四条边。
我们再思考一下极端的情况,我将这个dom的width和height都设置为0;
.t2 {
width: 0;
height: 0;
border: 40px solid;
border-color: orange blue red green;
}

大家看到了没,实际上是不是就是四个不同颜色的小三角形拼接而成的,如果你想实现其他的效果,是不是只需要让其中的某些三角形的颜色透明就OK啦。
好啦,我上面的例子实际上是不是就是让左边的三角形透明就达到效果啦。
这里有个问题,为什么在ribbon的css中没有设置宽度和高度;其实是这样的,没有设置宽度和高度的时候,默认是auto,并且这个dom中也没有文字其他的,它的实际宽度和高度其实就是0;
如果大家感兴趣的话,可以在<div class="ribbon__side ribbon__side--l"></div>
这个dom中添加一些内容,此时这个dom结构会变大,而图形也将不再是原来的结构,如图所示:

这时,如果将此dom结构的宽度和高度设置为0;
.ribbon__side {
bottom: -0.5rem;
position: absolute;
/* Displayed under the ribbon */
z-index: 1;
/* Background */
border: 1rem solid #d1d5db;
width: 0;
height:0;
}

此时图形恢复原样,但是内容溢出;因此如果你想在这个里面显示一些内容,最好将容器设置大一点,这样内容才不会溢出。
有了这个使用border来构建三角形的基础知识,那么在这个ribbon结构中最下面的两个黑色的三角形,不用我解释您也能轻松理解啦。
如果有不理解的地方,可以参考这篇文章,也可以留言讨论学习。