如何选择第一个相邻的兄弟姐妹?

问题描述 投票:0回答:9

我有一个像这样的 HTML 列表:

<ul>
  <li class="heading">Heading 1</li>
  <li class="heading">Heading 2</li>
  <li>Text Under Heading 2</li>
</ul>

由于标题1下面没有文字,我想用CSS隐藏它。

如果我这样做,

li.heading + li.heading { display: none; }

它隐藏了标题 2 而不是标题 1。

如何隐藏标题 1?有没有办法寻找相邻的兄弟姐妹并选择第一个?

html css css-selectors
9个回答
25
投票

可以使用 CSS 定位第一个兄弟姐妹,但有一些限制。

对于问题中的示例,可以用这样的方式完成

li.heading { display: none; }                   /* apply to all elements */
li.heading + li.heading { display: list-item }  /* override for all but first sibling */

这可行,但要求您可以显式设置兄弟姐妹的样式以覆盖第一个孩子的设置。


19
投票

不可能使用当前定义和实现的 CSS。它需要一个选择器,根据它后面的兄弟元素来选择一个元素。 CSS 选择器可以根据前面或外部元素选择一个元素,但不能根据后面或内部元素。

使用JavaScript可以很直接的达到预期的效果,您可以根据目的来决定是将元素从显示中移除还是从文档树中完全移除。


5
投票

现在可以了

li:first-of-type {
    display: none;
}

这将匹配第一个 li 标签。

li:first-of-type:not(:only-of-type) {
    margin: 10px;
}

如果你想要更多的控制——比如只有当有更多的项目时才在两个项目之间添加空间,上面的方法就可以了。混合伪选择器可以非常强大。 https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes


4
投票

有几种方法可以仅隐藏“标题 1”:

ul li:first-child {display:none;}

或者:

li.parent{ display: none; }
li.parent + li.parent { display: list-item; }

此外,

<li>Child of Heading 2</li>
不是
<li class="parent">Heading 2</li>
的孩子。这是一个兄弟姐妹。


0
投票

使用

:first-of-type

您可以在这里阅读更多内容


0
投票

尝试使用 JS 通过类名获取元素,如果超过 1 个则使用 CSS:

ul li:first-child {display: none;}

0
投票

官方 CSS3 规范目前不支持这样的东西,尽管我确实意识到它会很有用。

我会尝试搜索一些预构建的 JavaScript 或 jQuery 脚本/库来添加 CSS 选择器。虽然我从来没有遇到过任何东西。

如果你没有找到任何东西,你还不如手动做,或者尝试寻找一个完全不同的解决方案。


0
投票

现在可以使用

:has()
伪类adjacent sibling combinator (
+
)
.

函数式

:has()
CSS 伪类表示一个元素,如果作为参数传递的任何相对选择器在锚定到该元素时匹配至少一个元素。 这个伪类提供了一种通过将相对选择器列表作为参数来选择父元素或相对于引用元素的前一个兄弟元素的方法。

/* Selects an h1 heading with a
paragraph element that immediately follows
the h1 and applies the style to h1 */
h1:has(+ p) {
  margin-bottom: 0;
}

对于您的示例,您可以使用:

li.heading:has(+ li.heading) { display: none; }

请注意,这个伪类仍然很新,尚未被所有主要浏览器(例如 Firefox)完全支持。


-1
投票

我知道这个问题已经有一个有效的标记答案,但也许其他人想使用我的纯 css 解决方案:

我想在容器中有一个警报列表(在本例中为引导程序警报),并且它们的边界要折叠。每个警报都有一个边界半径,当它们都在一个容器中时看起来很傻。所以 margin-top: -1px 我让他们的边界崩溃了。作为下一步,我必须修改第一个、中间的每个警报和最后一个警报的样式。这对于单个警报、两个警报和 n 个警报也应该看起来不错。

.alert {
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
    border-bottom-left-radius: 0px;
    border-bottom-right-radius: 0px;
    margin: 0;
}

// set for the first alert that it should have a rounded top border

.alert:last-child {
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
}

// set for the last alert that it should have a rounded bottom border
// if there is only one alert this will also trigger it to have a rounded bottom border aswell

.alert+.alert:last-child {
  margin-top: -1px;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

//for the last border of n alerts we set the top border to be collapsing and remove only the the top rounded borders

.alert+.alert:not(:last-child) {
  margin-top: -1px;
  border-radius: 0;
}

// for each following alert in between we remove the top rounded borders and make their borders collapse

这是一个用于多个警报的角度模板。

<div id="alertscontainer">
    <div data-ng-repeat="alert in data.alerts" class="alert" data-ng-class="'alert-' + alert.class">
        {{alert.body}}
    </div>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.