能否在:not选择器内链式组合伪类?2列Grid边框优化咨询
更优的网格线实现方案 & 你的选择器问题解析
嗨Jerome!很高兴帮你解决这个2列Grid的边框问题,先给你两个更简洁的实现方案,再解释你那个:not选择器为什么不生效。
一、更优方案:容器级背景渐变法(推荐)
这个方法不用给每个子元素写复杂的边框规则,只靠容器的背景渐变就能自动生成元素间的网格线,不管子元素数量是奇数还是偶数都能完美适配:
.parent { display: grid; grid-template-columns: repeat(2, 1fr); /* 先设置子元素之间的间隙为0,让渐变线刚好在元素之间 */ gap: 0; /* 定义两个渐变:一个画水平行线,一个画垂直线 */ background-image: /* 水平行线:每行底部画1px线,其余透明 */ linear-gradient(rgba(255, 255, 255, 0.3) 1px, transparent 1px), /* 垂直线:每列右侧画1px线,其余透明 */ linear-gradient(90deg, rgba(255, 255, 255, 0.3) 1px, transparent 1px); /* 水平渐变的大小:宽度100%,高度为容器高度除以总行数(总行数=向上取整(元素数/2)) */ /* 这里用CSS变量传递元素数量,你可以在JS里动态设置--item-count的值 */ background-size: 100% calc(100% / max(1, ceil(var(--item-count)/2))), calc(100% / 2) 100%; /* 调整渐变位置,让线刚好落在元素之间,不会露出容器外部 */ background-position: 0 100%, 100% 0; } /* 给子元素设置和容器相同的背景色,盖住容器边缘的渐变线 */ .parent > * { padding: 1.2rem 0; background-color: inherit; /* 继承容器背景色,根据你的实际场景替换成具体颜色 */ }
如果不想用JS传递元素数量,也可以用另一种纯CSS的元素边框方案:
二、简化的元素边框方案
不用判断倒数第二个元素的奇偶,直接针对最后一列和最后一行的元素去掉多余边框:
.parent { display: grid; grid-template-columns: repeat(2, 1fr); } .parent > * { padding: 1.2rem 0; /* 给所有元素默认加右侧和底部边框 */ border-right: 1px solid rgba(255, 255, 255, 0.3); border-bottom: 1px solid rgba(255, 255, 255, 0.3); } /* 最后一列(偶数位)的元素去掉右侧边框 */ .parent > *:nth-child(2n) { border-right: none; } /* 最后一行的所有元素去掉底部边框 */ /* 这里用:nth-last-child(-n+2)选中最后2个元素,再排除掉"总元素数为奇数时的倒数第二个元素"(也就是最后一行只有1个元素的情况) */ .parent > *:nth-last-child(-n+2):not(:nth-child(odd):nth-last-child(2)) { border-bottom: none; }
这个方案比你原来的写法更直观,不需要单独重置某个元素的边框。
三、你的:not选择器失效原因
你写的这个选择器:
&:not(:last-child):not(:nth-last-child(2):nth-child(odd)){ border-bottom: 1px solid rgba(255, 255, 255, 0.3); }
逻辑上是对的,但优先级和你原来的两个规则不一致:
- 你原来的写法是:先给所有非最后一个元素加边框(
&:not(:last-child),优先级是1个伪类),再给特定元素重置边框(&:nth-last-child(2):nth-child(odd),优先级是2个伪类),后者优先级更高,所以能覆盖前者。 - 而合并后的选择器是两个
:not(优先级也是2个伪类),和重置规则的优先级相同。如果你的合并规则写在重置规则的前面,就会被重置规则覆盖;如果写在后面,才能生效。
另外,还有一个场景:当总元素数为奇数时,倒数第二个元素是偶数位(比如总3个元素,倒数第二个是第2个),这个元素不在:not的排除范围内,所以会被加上下边框,这是正确的(因为它在第一行,需要和第二行的元素分隔)。
如果一定要用合并后的写法,只需要保证它的优先级不低于重置规则,或者直接去掉重置规则,用这个合并规则即可。
内容的提问来源于stack exchange,提问作者Jerome De Wulf
相关产品推荐
相关产品推荐

