如何为无嵌套ul的li元素设置margin-bottom?CSS问题求助
解决无嵌套子列表的li元素margin-bottom设置问题
首先我发现你代码里有个小细节:CSS里写的是.sub-menu(带横杠),但HTML中子列表的class是submenu(不带横杠),这会导致你用ul:not(.sub-menu)根本过滤不掉子列表,这也是子菜单里的li被误加边距的原因之一,先把这个拼写统一过来!
接下来针对你的需求,分两种场景给你解决方案:
场景1:只想给顶级列表的第一个li设置margin-bottom
如果你的需求是仅顶级无序列表的第一个li有30px底部边距,完全不影响子菜单里的元素,那可以这样写选择器:
ul { list-style-type: none; } ul:not(.submenu) { padding: 0px; } ul li { padding-top: 10px; } /* 精准定位:非submenu类的ul的直接子元素第一个li */ ul:not(.submenu) > li:first-child { margin-bottom: 30px; } .submenu { margin-left: 20px; }
这里用>子选择器确保只选中顶级ul的直接子li,再结合ul:not(.submenu)排除子列表,就不会影响子菜单里的元素了。
场景2:给顶级列表中所有没有嵌套子ul的li设置margin-bottom
如果你的需求是顶级列表里,只要某个li内部没有子列表,就给它加30px底部边距,那可以用:has()伪类(现代浏览器都支持,比如Chrome 101+、Firefox 121+):
ul { list-style-type: none; } ul:not(.submenu) { padding: 0px; } ul li { padding-top: 10px; } /* 选中顶级ul下、内部没有ul的li */ ul:not(.submenu) > li:not(:has(ul)) { margin-bottom: 30px; } .submenu { margin-left: 20px; }
如果需要兼容不支持:has()的旧浏览器,你可以给有子菜单的li手动加个类(比如has-submenu),然后反向排除:
ul { list-style-type: none; } ul:not(.submenu) { padding: 0px; } ul li { padding-top: 10px; } /* 先给所有顶级li加边距 */ ul:not(.submenu) > li { margin-bottom: 30px; } /* 给有子菜单的li去掉边距 */ ul:not(.submenu) > li.has-submenu { margin-bottom: 0; } .submenu { margin-left: 20px; }
为什么你之前的选择器不行?
- 你原来的
ul li:first-child:not(.sub-menu)里,:not(.sub-menu)是筛选li元素是否有这个类,但你的sub-menu类是加在子ul上的,li本身没有这个类,所以这个选择器会匹配所有ul(包括子菜单的ul)下的第一个li,自然会影响子菜单的元素。 - 你尝试的
ul li:first-child:not(.sub-menu li)是无效的,因为CSS3里:not()只能接受简单选择器(比如类、标签、ID),不能用后代选择器这种复合写法,浏览器会直接忽略这个规则。
内容的提问来源于stack exchange,提问作者Freddy
相关产品推荐
相关产品推荐

