【问题标题】:CSS : get last HTML tag with a given class, in a list where not every HTML tag has this classCSS:获取给定类的最后一个 HTML 标记,在不是每个 HTML 标记都有这个类的列表中
【发布时间】:2023-04-02 21:22:02
【问题描述】:

这是我的CLOSED QUESTION 的副本,但副本无关紧要

First "duplicate"

但它不看类,只看类型,所以如果你碰巧有非同一个类的文章,你会得到意想不到的结果

Second "duplicate" 完全是另外一回事。

Third "duplicate" 解释了为什么我的尝试不起作用。

Fourth "duplicate" 给出了第一个元素的解决方法,而不是最后一个元素。

我知道没有 CSS 选择器,我只是想要一个解决方案。在结束我的问题之前请注意这一点!


我有 5 个按钮。正如您将在 sn-p 中看到的那样,它们有一个底层,使它们看起来很活跃。

每个按钮都可以有一个活动状态,但只能从 1 开始,到 5 为止。

它们都有一个分隔线,在 sn-p 中显示为红色。

我想将分隔线保留在底层中,在底层之外,但我想让它在底层的末端消失(在 sn-p 中,在按钮 #2 之后)。

在我的第一个问题之后,我了解到没有 CSS 选择器可以做到这一点。那么解决这个问题的最佳方法是什么?

.container {
  display: flex;
  align-items: stretch;
  justify-content: start
  margin: 12px;
  position: relative;
}

button:after {
  content: '';
  height: 100%;
  position: absolute;
  background: red;
  left: calc(100% + 12px);
  width: 1px;
  top: 0;
}

button.active:last-child:after {
  content: none;
}

button {
  flex: 0 0 calc(20% - 24px);
  border: 0;
  height: 32px;
  color: black;
  text-transform: uppercase;
  text-align: center;
  margin-right: 24px;
  background: transparent;
  position: relative;
}

button.active {
  color: white;
}

.active-pill {
  background: teal;
  position: absolute;
  height: 32px;
  border-radius: 16px;
  background: teal;
  width: calc(40% - 12px);
  z-index: -1;
}
<div class="container">

  <div class="active-pill"></div>
  
  <button class="active">Step 1</button>
  <button class="active">Step 2</button>
  <button>Step 3</button>
  <button>Step 4</button>
  <button>Step 5</button>
</div>

<h3>
  Which selector to use to remove the content after button #2 ?
</h3>

【问题讨论】:

标签: css css-selectors pseudo-element


【解决方案1】:

在这种特殊情况下:只需将分隔线放在按钮的左侧,而不是右侧?

然后不需要的那个,成为活跃的之后的第一个非活跃的,所以可以很容易地使用button.active + button:not(.active):after选择它

从技术上讲,这里的第一个按钮在左侧也有一个分隔线,当 sn-p 无论如何都被渲染时,它会在此处被切断。但是在您需要明确“消除”它的情况下,您仍然可以在这里使用简单明了的:first-child(我假设如果有活动按钮,它总是从第一个开始,对吧?)

这与 Hao 在他们的回答中建议的有点相似,但在他们的版本中,分隔线放在某些按钮的右侧,其他按钮的左侧......我更喜欢简单地让所有按钮都一样.

.container {
  display: flex;
  align-items: stretch;
  justify-content: start
  margin: 12px;
  position: relative;
}

button:after {
  content: '';
  height: 100%;
  position: absolute;
  background: red;
  right: calc(100% + 12px);
  width: 1px;
  top: 0;
}

button.active + button:not(.active):after {
  content: none;
}

button {
  flex: 0 0 calc(20% - 24px);
  border: 0;
  height: 32px;
  color: black;
  text-transform: uppercase;
  text-align: center;
  margin-right: 24px;
  background: transparent;
  position: relative;
}

button.active {
  color: white;
}

.active-pill {
  background: teal;
  position: absolute;
  height: 32px;
  border-radius: 16px;
  background: teal;
  width: calc(40% - 12px);
  z-index: -1;
}
<div class="container">

  <div class="active-pill"></div>
  
  <button class="active">Step 1</button>
  <button class="active">Step 2</button>
  <button>Step 3</button>
  <button>Step 4</button>
  <button>Step 5</button>
</div>

<h3>
  Which selector to use to remove the content after button #2 ?
</h3>

【讨论】:

  • 这个确实更好
  • 确实,这只是 CSS,满足我的要求!谢谢你,我什至没有考虑过。
【解决方案2】:

不幸的是,在纯 css 中没有办法选择具有特定类的最后一个元素。

但是,您的问题有很多可能的解决方案。仅举几例:

  1. 由于您可以在 HTML5 中定义自己的标记名称,因此您可以将活动类的 button 元素重命名为 activebutton。这样您就可以使用:last-of-type 选择器来定位它们。这可能与您在这里尝试的最接近。你也可以去掉底层......
  2. 您可以在其父元素中指明活动元素。在这种情况下,容器,并以第 n 个孩子为目标。
  3. 您可以在 html 中的最后一个活动元素中添加一个额外的类
  4. 你可以走javascript路线...

.container {
  display: flex;
  align-items: stretch;
  justify-content: start
  position: relative;
  margin-bottom: 12px;
}

button ,
buttona,
span{
  padding: 0 50px;
  border: 0;
  height: 32px;
  font-family: 'system-ui';
  font-size: 11px;
  line-height: 32px;
  color: black;
  text-transform: uppercase;
  text-align: center;
  background: transparent;
  position: relative;
}

buttona,
span{
  background: teal;
  color: white;
}

button:after,
buttona:after,
span:after{
  content: '';
  height: 100%;
  position: absolute;
  background: red;
  right: 0;
  width: 1px;
  top: 0;
}

buttona:first-of-type,
span:first-of-type{
  border-top-left-radius: 16px;
  border-bottom-left-radius: 16px;
}

buttona:last-of-type,
span:last-of-type{
  border-top-right-radius: 16px;
  border-bottom-right-radius: 16px;
}

buttona:last-of-type:after,
span:last-of-type:after{
  display: none;
}
<div class="container">
  <buttona>1</buttona>
  <buttona>2</buttona>
  <button>3</button>
  <button>4</button>
  <button>5</button>
</div>

<div class="container">
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <button>4</button>
  <button>5</button>
</div>

【讨论】:

  • 1) 我正在使用 Angular,这意味着我必须为此创建自定义组件 --- 2) 因为它是动态的,这意味着我必须动态添加 :after 规则在每一步更改的样式表中,这不是那么方便--- 3)这是我的实际解决方案(用 4 完成))但我希望能够只用 CSS 来做......我想我现在会坚持这个当前的解决方案,谢谢您对此事的意见! (更重要的是,理解问题,不像上一个问题......)
  • @temp_user 如果您不希望 Angular 尝试解析您的自定义标签,您可以使用该容器中的任何现有标签。为什么不使用跨度,并在您的 css 样式中使用 .container span
  • “但我希望能够只使用 CSS 来做到这一点” - 为什么要坚持这一点,即使你的底层“药丸”元素实际上也没有这样做首先? width: calc(40% - 12px); 无论如何都需要修改,如果你想让它覆盖不同数量的活动步骤......
  • @04FS 这是minimal reproducible example,不是我的实际实现。如果您没有注意到,它也不包含 Angular。
  • @JasperZelf #3 和 #4 解决方案的组合似乎比你的评论更容易,我不得不说(我已经在使用它),实现你的评论只会意味着更复杂我的代码
猜你喜欢
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
相关资源
最近更新 更多