What's the difference between visibility: hidden and visibility: collapse in flexbox?
Note on browser support: As of July 2017, Chrome (59) does not support visibility: collapse
. The code samples below with collapse
work in Firefox and Edge, but fail in Chrome (they behave just like hidden
). UPDATE: As of July 2020, this is note is still valid. Chrome and Safari treat visibility: collapse
like hidden
. caniuse.com
Flex items are laid out in a row or column, depending on flex-direction
.
Each row / column is considered a flex line.
In the examples below, a flex container has four flex items in row-direction. The fourth item wraps, creating a second flex line:
.container {
display: flex;
flex-wrap: wrap;
width: 200px;
border: 1px dashed black;
}
.box {
height: 50px;
flex: 0 0 50px;
margin: 5px;
background-color: lightgreen;
display: flex;
justify-content: center;
align-items: center;
}
<div class="container">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
<div class="box box4">4</div>
</div>
Difference between Visibility.Collapsed and Visibility.Hidden
The difference is that Visibility.Hidden
hides the control, but reserves the space it occupies in the layout. So it renders whitespace instead of the control.Visibilty.Collapsed
does not render the control and does not reserve the whitespace. The space the control would take is 'collapsed', hence the name.
The exact text from the MSDN:
Collapsed: Do not display the element, and do not reserve space for it in layout.
Hidden: Do not display the element, but reserve space for the element in layout.
Visible: Display the element.
See: http://msdn.microsoft.com/en-us/library/system.windows.visibility.aspx
What is the difference between visibility:hidden and display:none?
display:none
means that the tag in question will not appear on the page at all (although you can still interact with it through the dom). There will be no space allocated for it between the other tags.
visibility:hidden
means that unlike display:none
, the tag is not visible, but space is allocated for it on the page. The tag is rendered, it just isn't seen on the page.
For example:
test | <span style="[style-tag-value]">Appropriate style in this tag</span> | test
Replacing [style-tag-value]
with display:none
results in:
test | | test
Replacing [style-tag-value]
with visibility:hidden
results in:
test | | test
Visibility:collapse is rendered as visibility:hidden
It won't work as intended on all browsers, only Firefox and IE (I can't confirm IE right now). The MDN docs on visibility
say:
The support for
visibility:collapse
is missing or partially incorrect in some modern browsers. In many cases it may not be correctly treated likevisibility:hidden
on elements other than table rows and columns.
You can test it with this jsFiddle: http://jsfiddle.net/meT7k/. In Chrome, the first row is rendered as visibility: hidden
. In Firefox, collapse
is applied correctly.
In Chrome, you get the desired results when applying display: none
to the row instead. However, that will probably force a re-layout of the whole table (e.g., column widths may change after the display
property is changed).
CSS Properties: Display vs. Visibility
The visibility
property only tells the browser whether to show an element or not. It's either visible (visible
- you can see it), or invisible (hidden
- you can't see it).
The display
property tells the browser how to draw and show an element, if at all - whether it should be displayed as an inline
element (i.e. it flows with text and other inline elements) or a block
-level element (i.e. it has height and width properties that you can set, it's floatable, etc), or an inline-block
(i.e. it acts like a block box but is laid inline instead) and some others (list-item
, table
, table-row
, table-cell
, flex
, etc).
When you set an element to display: block
but also set visibility: hidden
, the browser still treats it as a block element, except you just don't see it. Kind of like how you stack a red box on top of an invisible box: the red box looks like it's floating in mid-air when in reality it's sitting on top of a physical box that you can't see.
In other words, this means elements with display
that isn't none
will still affect the flow of elements in a page, regardless of whether they are visible or not. Boxes surrounding an element with display: none
will behave as if that element was never there (although it remains in the DOM).
Chrome Visibility: Collapse
Chrome and Safari treat visibility: collapse
as visibility: hidden
.
This will only work in Firefox/IE.
You can change it to display: none
to make sure it works the same in all browsers, however this way you will miss the general idea of the collapse
value, where all the width/height of the table's elements are calculated and take into account while affecting other elements in the table:
.collapse { display: none;}
<table> <caption>This is a Table</caption> <thead> <tr> <th>Column 1</th> <th>Column 2</th> </tr> </thead> <tbody class='collapse'> <tr> <td>Row 1, Cell 1</td> <td>Row 1, Cell 2</td> </tr> <tr> <td>Row 2, Cell 1</td> <td>Row 2, Cell 2</td> </tr> </tbody> <tfoot> <tr> <td>TOTAL 1</td> <td>TOTAL 2</td> </tr> </tfoot></table>
Elements not appearing when setting visibility to visible and using :checked pseudo-class
Move checkboxes above.
.cardsContainer{
display: flex;
justify-content: space-between;
}
#f1, #f2, #f3{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
visibility: collapse;
}
.backgroundHistory, .backgroundHistory2, .backgroundHistory3{
margin: 1em 0em 0em 0em;
padding: 1.5em;
background: #eceddd;
border-style: solid;
border-color: black;
text-align: justify;
margin-top: 0px;
visibility: visible;
}
.buttonPicture{
display: inline-block;
width: 32px;
height: 32px;
background: url('https://cdn.icon-icons.com/icons2/1904/PNG/512/downarrow_121316.png') no-repeat;
}
.buttonSpace{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.card{
background-color: #e7edb4;
margin: 0px;
border-style: groove;
border-color: white;
padding-bottom: 0px;
margin-left: .5em;
margin-right: .5em;
}
#expand-toggle, #expand-toggle2, #expand-toggle3{
display: none;
}
/*monaLisa*/
#expand-toggle:checked ~ * #f1{
visibility: visible;
}
#expand-toggle:checked ~ * .backgroundHistory{
visibility: visible;
}
/*Artemisia*/
#expand-toggle2:checked ~ * #f2{
visibility: visible;
}
#expand-toggle2:checked ~ * .backgroundHistory2{
visibility: visible;
}
/*the persistence of memory*/
#expand-toggle3:checked ~ * #f3{
visibility: visible;
}
#expand-toggle3:checked ~ * .backgroundHistory3{
visibility: visible;
}
<div class="cardsContainer">
<input type="checkbox" id="expand-toggle">
<input type="checkbox" id="expand-toggle2">
<input type="checkbox" id="expand-toggle3">
<div class="card">
<div class="buttonSpace">
<label for="expand-toggle"> <span class="buttonPicture"> "icon"</span> </label>
</div>
<figure id="f1">
<img src="https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554__340.jpg" alt="Mona Lisa" class="pictureAdjustment">
<figcaption class="imageHistory">
<i>Leonardo da Vinci</i> (1503) <br>
</figcaption>
</figure>
<p class="backgroundHistory">
It was painted between 1,503 and 1,519, when Leonardo da Vinci lived in Florence, Italy.
Currently, it's not known who the woman in the painting was; there's doubt about if she was
really a woman.
</p>
</div>
<div class="card">
<div class="buttonSpace">
<label for="expand-toggle2"> <span class="buttonPicture"> "icon" </span> </label>
</div>
<figure id="f2">
<img src="https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554__340.jpg" alt="Artemisia" class="pictureAdjustment">
<figcaption class="imageHistory">
<i>Artemisia Gentileschi</i> (1620) <br>
</figcaption>
</figure>
<p class="backgroundHistory2">
This is an artwork by Artemisia Gentileschi, it's an oil painting. This painting is inspired on an Old Statement Bible story.
This painting is a second attempt from the same Bible story, which was done previously. This is the most recognizable painting made
by Artemisia Gentileschi.
</p>
</div>
<div class="card">
<div class="buttonSpace">
<label for="expand-toggle3"> <span class="buttonPicture"> "icon" </span> </label>
</div>
<figure id="f3">
<img src="https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554__340.jpg" alt="Salvador Dalí" class="pictureAdjustment">
<figcaption class="imageHistory">
<i>Salvador Dalí</i> (1931)<br>
</figcaption>
</figure>
<p class="backgroundHistory3">
It was painted by spanish painter Salvador Dalí. Dalí painted this artwork when he was 28 years old and
the surrealism movement was at its peak. By this time, he was officially joined with surrealist artists and
developed his "Paranoiac Critical method"
</p>
</div>
</div>
Hide flexbox child and make visible again
Just reset it back to display:block
.container { margin: 40px;}
.flexbox-container { display: flex;}
.flexbox-item { flex: 1 0 0; height: 40px; background-color: aqua;}
.flexbox-item:not(:first-child) { margin-left: 20px;}
input:checked+.flexbox-container>.hide-item { display: block;}
.hide-item { display: none;}
<div class="container"> <label>Toggle This</label> <input type="checkbox"> <div class="flexbox-container"> <div class="flexbox-item">child</div> <div class="flexbox-item hide-item">child</div> <div class="flexbox-item">child</div> </div></div>
Related Topics
CSS - First Child Without Certain Class
CSS Specificity or Inheritance
How to Fix Unexpected Column Order in Bootstrap 4
Shorten Verbose CSS That Repeats Combinations of Elements and Pseudo-Classes
Apply CSS Style to Child Elements
How to Keep CSS Floats in One Line
How to Center a Bootstrap Div with a 'Spanx' Class
How to Add a Margin to a Table Row <Tr>
How to Have a Position: Fixed; Behaviour for a Flexbox Sized Element
Shrinking Navigation Bar When Scrolling Down (Bootstrap3)
Where Do CSS and JavaScript Files Go in a Maven Web App Project
CSS Flexbox: Difference Between Align-Items and Align-Content
Select Specific Element Before Other Element
Disable CSS Animation on Pseudo Element Inherited from Parent
CSS Variables Defaults: Set If Not Already Set
How to Find Out When I Can Safely Drop Vendor Prefixes for a CSS3 Property