如果兄弟元素不为空,则显示按钮

3
我想实现一个列表,可以通过按钮添加新项目。列表顶部有一个按钮用于在前面添加新项目,底部有另一个按钮用于在后面添加新项目。
HTML:
<div>
    <div id="list">
      <button class="addbtn">prepend item</button>
      <ul id="items"></ul>
      <button class="addbtn">append item</button>
    </div>
</div>

当鼠标悬停在包含列表的 div 上时(通过 css :hover 选择器),按钮才可见。

CSS:

.addbtn {
  display: none;
}

#list:hover .addbtn {
  display: block;
}

有没有一种方法(不使用JS,只使用CSS)在列表为空时仅显示追加按钮而不显示前置按钮?如果列表至少包含一个项目,则应显示两个按钮。

JSFiddle: https://jsfiddle.net/uLmzom18/

编辑:这是具有可行解决方案的JSFiddle:https://jsfiddle.net/khu7bahm/


不存在父级选择器和前置兄弟选择器。所以,不行。 - Oriol
2
@Oriol 可能可以使用巧妙的方法,但需要更改HTML结构。 - Praveen Kumar Purushothaman
3个回答

7

如果一个元素在DOM流中比另一个元素高,那么CSS就无法对其进行影响。

但是你可以采用一些技巧:倒序排列HTML中的元素,并使用flex重新排列它们。

ul:empty ~ .addbtn {
  background-color: lightgreen;
}

#list, #list2 {
  display: inline-flex;
  flex-direction: column-reverse;
}
<div>
    <div id="list">
      <button class="addbtn">prepend item</button>
      <ul id="items"></ul>
      <button class="addbtn">append item</button>
    </div>
</div>
<div>
    <div id="list2">
      <button class="addbtn">prepend item</button>
      <ul id="items">
      <li>1</li>
      <li>2</li>
      </ul>
      <button class="addbtn">append item</button>
    </div>
</div>


3

如果你的 #list 使用了 display:flex,你可以倒转按钮的顺序并使用 css兄弟选择器+

请参见这个fiddle:https://jsfiddle.net/sb7zewp6/1/

如果需要更多关于此的信息,我可以扩展这个答案,但我认为只有在 display:flex 是一种选项时才需要。

有关 display:flex 的更多用法信息,请参见caniuse.com

$(".addbtn").click(function() {
  if($(this).hasClass("prepend"))
   $("#items").prepend($("<li>").text("prepended item " + $("#items").children().length));
 else
  $("#items").append($("<li>").text("appended item " + $("#items").children().length));
});
#list {
  width: 300px;
  min-height: 10em;
  background-color: #fff;
  display:flex;
}
.addbtn {
  display: none;
}

#items:empty+.addbtn {
  display:none !important;
}

#list:hover .addbtn {
  display: block;
}


.addbtn.append {
  order:3;
}
#items {
  order:2;
  outline:1px solid red;
}
.addbtn.prepend {
  order:1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <div id="list">
      <button class="addbtn append">append item</button>
      <ul id="items"></ul>
      <button class="addbtn prepend">prepend item</button>
    </div>
</div>


哇,但为什么它会以那种方式出现?我还是很困惑,这是如何工作的...哇,所以:empty真的是CSS选择器? - Praveen Kumar Purushothaman
是的,:empty 是一个有效的 CSS3 选择器:http://caniuse.com/#search=empty。 - z00l
1
好的回答!!! 你在我之前发布了你的回答 :-) 我会保留我的回答,因为重新排列 flex 元素的方式略有不同,可能会有用。而且最好使用 inline-flex,显示会更标准。 - vals
@vals 是的,我在更新我的回答并添加了 caniuse 链接后看到了你的回答;-) 我也会给你点赞,因为你提供了不同的重新排序方式。我认为这取决于情况。 - z00l

0

使用CSS无法测试元素是否为空,因为它没有向上遍历的可能性。如果您使用jQuery,则可以实现。

如果您想要基于纯CSS的解决方案来处理当前的HTML,则不行!

但是,如果您使用了一些无效的HTML,则可能会起作用:

#items .addbtn:last-child {
  display: none;
}
<div>
  <div id="list">
    <ul id="items">
      <button class="addbtn">prepend item</button>
    </ul>
    <button class="addbtn">append item</button>
  </div>
</div>

这里,我直接将addbtn放在了<ul>标签内部,这是错误的。但是如果你决心这么做,我们可以改进它:

#items .btnAdd {
  margin-left: -40px;
  margin-bottom: 20px;
}
#items .btnAdd:last-child {
  display: none;
}
<p>No Prepend Button</p>
<div>
  <div id="list">
    <ul id="items">
      <li class="btnAdd"><button class="addbtn">prepend item</button></li>
    </ul>
    <button class="addbtn">append item</button>
  </div>
</div>
<hr />
<p>Prepend Button Shown</p>
<div>
  <div id="list">
    <ul id="items">
      <li class="btnAdd"><button class="addbtn">prepend item</button></li>
      <li>One item</li>
    </ul>
    <button class="addbtn">append item</button>
  </div>
</div>

最终的代码片段是一个基于纯CSS的解决方案。

谢谢。使用JS的解决方案似乎更加简洁。 - megagrump
@DarkMark 是的,既然您已经在使用JS进行插入和追加操作,那么您是否愿意将此作为解决方案接受呢? - Praveen Kumar Purushothaman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接