纯 css 实现一个级联连线效果
1、前言
今天在css学习群里看到一个下图的效果,看到群中讨论如何实现时, 正好之前其实也做过类似的, 就想写个demo在回顾一下
2、思路
看到类似的其实首先就是想到用伪元素去实现左侧的引导线,目的是利用元素自身的两个隐藏的元素, ::before 和 ::after , 来简化dom, 元素能省则省。 所以大致思路就是, 每个子节点(图中片区)通过伪元素的边框设置横向的引导条。 父节点(图中区域)的竖线可以通过盒子的伪元素利用盒子的高度填充
3、实现细节
第一步: 先了解伪元素的用法
其实工作中伪元素的使用非常常见, 就类似这种,前面有个填充线,或者背景图,或者一个定位了一个小icon 都是用这种方式实现
一般我们的伪元素都是相对于元素进行定位的,其实伪元素可以理解为元素的子节点。 元素使用相对定位后, 子元素就可以通过绝对定位,自由的设置相对于该元素的定位位置
第二个重点是,伪元素一定要设置 content 属性, 才会展示出来, 如果不需要值。一般设置为空即可, 设置content的值可以理解为给伪元素增加文字
下面是使用伪元素的demo,先给每个元素通过伪元素在前面增加一个 背景块
<style>
.box {
position: relative;
left: 20%;
top: 100px;
}
.box .ul {
list-style: none;
position: relative;
}
ul li {
position: relative;
}
.box li {
position: relative;
}
.box li::before {
content: "";
position: absolute;
width: 10px;
height: 10px;
background: #f00;
top: 50%;
transform: translateY(-50%);
left: -15px;
}
</style>
<body>
<div class="box">
<div class="ul">
<li>四川区域</li>
<li>四川一区</li>
<li>四川二区</li>
<li>四川三区</li>
</div>
</div>
</body>
效果如下:
这样就轻松使用::before 伪元素实现了每个li 前面增加一个元素背景块
用 浏览器的元素审查工具就是这样的,很明显可以看出来,::before 元素貌似就是li的子元素。 可以选中这个伪元素,在右下所示区域输入样式实时进行调整,调到理想效果后, 然后在复制到代码中保存
第二步: 设置子节点的横向分割线
在设置子节点横向分割线之前, 我们先通过class类对父节点和子节点进行一下区分, 在第一个dom上添加.parent类,下面三个dom节点添加.child类, 然后通过给child 设置margin-left 进行区分
<style>
.box .child {
margin-left: 30px;
}
</style>
<body>
<div class="box">
<div class="ul">
<li class="parent">四川区域</li>
<li class="child">四川一区</li>
<li class="child">四川二区</li>
<li class="child">四川三区</li>
</div>
</div>
</body>
因为li的 ::before 伪元素已经被用成红色的背景块了, 所以设置横线的任务要用::after 来实现了, 有了上面的基础,实现起来就比较简单了, 只需要给 li上 child 类的元素,添加横线
.box li.child::after {
content: "";
position: absolute;
width: 24px;
height: 1px;
background: #000;
top: 50%;
transform: translateY(-50%);
left: -39px;
top: 12px;
}
效果如下:
此时案例的效果就完成了一半
实现最后一步: 左侧的竖线
实现左侧的竖线,两种思路, 一种是继续用伪元素, 给li.parent增加::after 来设置父元素的竖线, 但是这种情况下,是需要通过js动态计算,子元素的高度,再赋值,其实也有更简单的方式, 直接利用外面的大盒子设置伪元素来设置左侧的竖线, 这样就能利用盒子的高度,不再需要依赖js或者css的计算属性进行计算了
核心代码,给ul设置相对定位, 再给ul设置一个伪元素, 并且设置伪元素的样式
.box .ul {
list-style: none;
position: relative;
}
.box .ul::before {
content: "";
position: absolute;
width: 1px;
background: #000;
left: -10px;
height: calc(100% - 20px);
top: 10px;
}
效果如下:
这样就完成了上面的案例
最后的动态增删效果如下
4、总结
在工作中实现元素前面有一些额外附加物,比如一些icon、背景区块、 或者背景图、指引线,或者上浮的小文字的时候, 我们经常是通过伪元素进行设置,核心就是先对元素自身增加相对定位, 之后就可以大胆的使用元素自身隐藏的两个伪元素进行设置, 通过都是对伪元素进行绝对定位, 这样伪元素是相对于元素本身进行定位的。 然后设置伪元素的content属性, 有值代表伪元素自身文字,如果不需要文字可以设置为空字符串,这个是必填项
通过伪元素进行设置,可以避免引入更多的dom,产生更多的样式设置。 使用伪元素可以大大减少我们的代码量, 也可以将元素进行集中处理, 类似代码封装一样, 和其他元素进行结偶, 更有利于复用和封装