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>
.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
.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>
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
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.
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.
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;
}