css中的子元素设置margin-top或者margin-bottom作用到父元素上的问题

写页面的时候要实现这样一个效果

要求:图标之间有一条线进行连接,最上边和最下边的图标没有线进行连接,数据动态加载图标和线也动态生成

一、第一种实现方法

横着的每条数据是一个父级,然后所有的数据又是一个父级,然后给最外层的父级加border-left,然后每条数据设置一个margin-left的负值,每条数据之间的间距用margin-bottom来设置,具体实现如下

<!doctype html>
<html>
<head>
	<meta charset="utf-8">
	<title>标题</title>
	<meta name="keywords" content="">
	<meta name="description" content="">
	<style>
		ul{
			list-style-type: none;
			border-left:1px solid #ccc;/*左侧连接图标的线*/
			margin:0;
			padding:0;
			margin-left:15px;
		}
		ul li{
			position:relative;
			margin-bottom:20px;/*每条数据之间的间距*/

		}
		
		ul li div{
			height:29px;
			line-height:29px;
			margin-left:30px;
		}
		ul li img{
			width:30px;
			height: 29px;
			background:#fff;
			position:absolute;
			left:-15px;
			top:0;
		}
		#nextDiv{
			background: red
		}
	</style>
</head>
<body>
	<ul id="wrap">
		<li>
			<img src="img.png" alt="">
			<div>111111</div>
		</li>
		<li>
			<img src="img.png" alt="">
			<div>222222</div>
		</li>
		<li>
			<img src="img.png" alt="">
			<div>333333</div>
		</li>
		<li>
			<img src="img.png" alt="">
			<div>444444</div>
		</li>
		<li>
			<img src="img.png" alt="">
			<div>555555</div>
		</li>
	</ul>

	<div id="nextDiv">下一个块的内容</div>
</body>
</html>

运行之后实现的效果如下:


效果可以实现,但是有点问题就是,给每条数据进行了设置margin-bottom,最后一行数据下方也是有margin-bottm的,浏览器解析的时候盒模型进行计算的时候是忽略了最后一行的margin-bottom,所以最后一个图标下方没有竖线。但是最后一行数据的margin-bottom是被忽略掉了么?不是的 。再看红色背景部分就是用来验证最后一行的margin-bottom是不是存在的,可以看到中间我没设置间隔,但是红色背景部分和上边是有间距的,这就是问题的关键所在:子元素设置的margin-bottom作用到了父元素上,使得父元素的下一个兄弟元素也就是红色区域与父元素之间有了间隔

解决办法有很多:

①可以单独给最后一条数据一个样式margin-bottom为0

②给父元素设置margin-bottom:-20px;

③可以不给每条数据也就是li都设置margin-bottom

        可以利用相邻元素选择器li+li,相邻元素选择器

        相邻元素选择器的使用:相邻兄弟选择器(Adjacent sibling selector)可选择紧接在另一元素后的元素,且二者有相同父元素。

    例如:

所以我们使用了相邻元素选择器就不用再,单独设置最后一条数据了。

进行修改之后的css代码如下:

<style>
		ul{
			list-style-type: none;
			border-left:1px solid #ccc;/*左侧连接图标的线*/
			margin:0;
			padding:0;
			margin-left:15px;
		}
		ul li{
			position:relative;

		}
		li+li{
			margin-top: 20px;/*每条数据之间的间距*/
		}
		ul li div{
			height:29px;
			line-height:29px;
			margin-left:30px;
		}
		ul li img{
			width:30px;
			height: 29px;
			background:#fff;
			position:absolute;
			left:-15px;
			top:0;
		}
		#nextDiv{
			background: red
		}
	</style>

这次变成了设置margin-top,因为相邻元素选择器是作用到相邻的下一个元素

实现的效果如下:


可以看到缝隙不见了,为了取消这个间隙没有什么意义,毕竟大多数两个块之间还是有间隙的,这里只是想让大家了解子元素的margin值会作用到父元素上的情况,不光是margin-bottom有这种情况,其实margin-top也有这种情况.

③第①②③种方法为了不作用到父元素直接不设置margin-bottom,其实还有防止不作用到父元素的方法,只是我要实现的效果不适合这种方法,有三种方法可以解决:

        (1)为父元素设置padding。 
        (2)为父元素设置border。 

        (3)为父元素设置 overflow: hidden 。

    具体使用大家参考这篇文章:https://blog.csdn.net/man_tutu/article/details/62224844

        我写的这个效果不适合使用这种方法因为我设置了margin-bottom,并且不让其作用到父元素上之后,那么本身的bottom值就起作用了,那么最后一个图标下边就会出现竖线。

    关于margin的问题推荐大家一篇文章,可以详细了解一下:https://www.cnblogs.com/zhangmingze/articles/4664074.html

二、第二种实现效果的方法,利用伪元素

具体代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style type="text/css">
	.add:before {
 		content: " ";
		float: left;
		/*display: inline-block;*/
		background: url(img.png) 0 0 no-repeat;
		background-size: 100% 100%;
		height: 50px;
		width: 50px;
		margin-right: 20px;
	}
	.add{
		height: 50px;
		line-height: 50px;
		margin-left: -25px;
	}
	.add+.add{
		margin-top: 20px;
	}
	#wrap{
		border-left: 1px solid #ccc;
		margin-left: 30px;
	}

</style>
</head>
<body>
	<div id="wrap">
		<div class="add">11111</div>
		<div class="add">22222</div>
		<div class="add">33333</div>
		<div class="add">44444</div>
		<div class="add">55555</div>
		<div class="add">66666</div>
	</div>
</body>
</html>

实现的效果如下:


同样能实现效果,感觉这种方法更简便一些。

好啦~就说这么多吧,主要是说了两件事,一个是实现这种效果最佳的方案,另一个是在写的过程中遇到的margin值的问题,刚开始写不知道大家能不能看明白,欢迎提供建议~~~一起进步~~~

猜你喜欢

转载自blog.csdn.net/weixin_39855431/article/details/79929135