bootstrap 4 list items that have d-flex class do n

2020-08-09 08:39发布

问题:

When I add class d-flex my Bootstrap 4 <ul> list items do not respond to .hide() anymore, even though style="display: none;" is added to the DOM.

The d-flex is used for the Bootstrap 4 list badges.

Suggestions?

// test 1: regular list, no issue
$("#myList li:even").addClass("disabled").hide()
// <li class="list-group-item" style="display: none;">First item</li>


// test 2: list with badges, no response to hide (class "disabled" still works)
// just adding class "d-flex" is sufficient to reproduce issue
//$("#myList2 li").addClass("d-flex")

$("#myList2 li").addClass("d-flex justify-content-between align-items-center")
$("#myList2 li").append("<span class='badge badge-primary'>test</span>")

$("#myList2 li:even").addClass("disabled").hide()

// <li class="list-group-item d-flex justify-content-between align-items-center" style="display: none;">First item<span class="badge badge-primary">test</span></li>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>

<h3>regular list</h3>
<ul class="list-group" id="myList">
	<li class="list-group-item">First item</li>
	<li class="list-group-item">Second item</li>
	<li class="list-group-item">Third item</li>
	<li class="list-group-item">Fourth item</li>
</ul>


<h3>with d-flex class (used for badge)</h3>
<ul class="list-group" id="myList2">
	<li class="list-group-item">First item</li>
	<li class="list-group-item">Second item</li>
	<li class="list-group-item">Third item</li>
	<li class="list-group-item">Fourth item</li>
</ul>

回答1:

.d-flex uses !important which overrides the display: none which hide() puts on the element.

You could put containers within your li (I've used divs in example fiddle) and add .d-flex onto them so display: none on the li won't be overridden.

Fiddle here



回答2:

.hide() sets display to block, and you are using flex, use addClass() and removeClass() to show hide the flex container.

EDIT:

Apart from all you are using the scripts outside document ready or in the code snippet you added them outside the $(document).ready() function and you are using jquery.slim so features would be minimal and add display:none to your lis which will be the real thing

EDIT2

this could be done in 2 ways one is including a class and adding display:none property, OR the second one which I prefer too, is to call .hide() before you call the .toggleClass() which means the onclick event will be converted to

$("#hide").on('click', function() {
    $("#myList2 li:even").hide().toggleClass('d-flex');
  });

Now you can remove the class #myList2 li from the CSS that i used in the demo.

See the demo below

$(document).ready(function() {
  // test 1: regular list, no issue
  $("#myList li:even").addClass("disabled").hide()
  // <li class="list-group-item" style="display: none;">First item</li>


  // test 2: list with badges, no response to hide (class "disabled" still works)
  // just adding class "d-flex" is sufficient to reproduce issue
  //$("#myList2 li").addClass("d-flex")

  $("#myList2 li").addClass("d-flex justify-content-between align-items-center")
  $("#myList2 li").append("<span class='badge badge-primary'>test</span>")
  $("#myList2 li:even").addClass("disabled");


  // <li class="list-group-item d-flex justify-content-between align-items-center" style="display: none;">First item<span class="badge badge-primary">test</span></li>
  $("#hide").on('click', function() {
    $("#myList2 li:even").toggleClass('d-flex');
  });
});
#myList2 li {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet" />

<h3>regular list</h3>
<ul class="list-group" id="myList">
  <li class="list-group-item">First item</li>
  <li class="list-group-item">Second item</li>
  <li class="list-group-item">Third item</li>
  <li class="list-group-item">Fourth item</li>
</ul>

<button id="hide">HIDE /SHOW NOW</button>
<h3>with d-flex class (used for badge)</h3>
<ul class="list-group" id="myList2">
  <li class="list-group-item">First item</li>
  <li class="list-group-item">Second item</li>
  <li class="list-group-item">Third item</li>
  <li class="list-group-item">Fourth item</li>
</ul>



回答3:

Since you intend to hide the element, I don't think removing d-flex will be a problem.

$('hide').click(function(){
  $(".my-flex").removeClass("d-flex").addClass("d-none");
});

So when you intend to show the element again you can use

$('show').click(function(){
  $(".my-flex").addClass("d-flex").removeClass("d-none");
});

Alternatively, you can add a parent element which you can then hide and show at any time



回答4:

How I resolved was to not use class="d-flex" and instead use style="display:flex;".

This negates the !important from Bootstrap's d-flex class. The result is display:none; will work when using the JQuery hide() function. When using JQuery show() function, the display:flex; is re-added.



回答5:

in general terms I agree with the solution by @Matthew Allen, but, in case you already have your project working and don't want to rework all your HTMLs, consider using a single CSS rule like this:

.d-flex[style*="display:none"], .d-flex[style*="display: none"] {
    display:none !important;
}

To my understanding, Bootstrap CSS code adds 'display:flex !important' in order to make d-flex prevalent to other display classes, but I don't think it has to override inlined display:none.



回答6:

As already explained by previous answer, bootstrap's d-flex class is defined as display: flex !important;

In my case (active tab panes still showing div's from inactive panes if those divs are marked d-flex), I solved it with a custom rule:

div.tab-pane:not(.show).d-flex,
div.tab-pane:not(.show) .d-flex {
  display: none !important;
}