CSS Properties: Display vs. Visibility - css

What is difference between Display vs. Visibility properties?

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).

visibility: hidden;
the element won't be painted AND don't recieve click/touch events, but the space it takes is still occupied
because it's still there for layout purposes, you can measure it without it being visible
changing content will still cost time reflow/layouting the page
visibility is inherited, so this means you can make subchildren visible by giving them visibility: visible;
display: none;
will make the element not participate in the flow/layout
can (depending on the used browser) kill Flash movies and iframes (which will restart/reload upon showing again), although you can prevent this from happening with iframes
the element won't take up any space. for layout purposes it's like it does not exist
will make some browsers/devices (like the iPad) directly take back memory used by that element, causing small hickups if you switch between none and an other value during animations
extra notes:
images in hidden content: in all popular browsers images are still loaded, even though they are within any element with visibility: hidden; or display: none;
fonts in hidden content: webkit browsers (Chrome/Safari) may delay loading custom fonts which is only used in hidden elements, including through visibility or display. This may cause you to measure elements which are still using a fallback font until the custom font is loaded.

display: none removes the element out of the flow of the html whereas visibility:hidden does not.

display:none; will remove the DOM elements visual style / physical space from the DOM, whereas visibility:hidden; will not remove the element, but simply hide it. So a div occupying 300px of vertical space in your DOM will STILL occupy 300px of vertical width when set to visibility:hidden; but when set to display:none; it's visual styles and the space it occupies are hidden and the space is then "freed" up for lack of a better word.
[EDIT] - It was a while back that I wrote the above, and whether I was not knowledgeable enough or having a bad day, I don't know, but the reality is, the element is NEVER removed from the DOM hierarchy. All block level display 'styles' are completely 'hidden' when using display:none, whereas with visibility:hidden; the element itself is hidden but it still occupies a visual space in the DOM. I hope this clears things up

Related

Move a child element positioned absolutely outside of its parent container

I'm trying to move the green box 10px outside of the top of its container. However, since .cover has an overflow of hidden, the top of the green box isn't showing. How can I show the green box without switching around elements in the DOM?
Sorry for the confusion and the lack of info. Also, if I take off overflow: hidden or switch it to visible, the container reduces to 0 height which then hides a vertical border (on the site I'm working on) that spans the height of the content.
https://jsfiddle.net/Lxbf45y0/1/
if I take off overflow: hidden or switch it to visible, the container reduces to 0 height which then hides a vertical border
Sounds like you're using overflow:hidden; to create a new block formatting context. Obviously the side effect is that you can't easily have any overflow. That MDN page I linked includes a list of ways to force a new block formatting context. One thing you can do is replace overflow:hidden; with display:inline-block; width:100%;. This demo uses that method: https://jsfiddle.net/sb40ha0n/
As pointed out by Roko C. Buljan, Clearfix methods might also be available to correct this issue.

font-size 0 still shows up in IE7

For some odd reason, when I set a font-size:0px; in my style-sheet for an anchor link, IE7 still shows a tiny-tiny version of the text. Is there anything I should consider doing to completely hide the text, without using text-indent?
The anchor itself is using a background image in the css. And I simply want to hide the text that in the anchor link, on the HTML page.
visibility: hidden and display: none are the standards in hiding elements.
The difference between the two is that visibility acts like opacity, in which the element is hidden but it still affects the layout of the page (e.g. a 200px high element will still make the element below it 200px lower than if it were not there).
display acts as if the element were not there at all - a 200px high element would not make an element below it 200px lower that it would be if the first element were not there.
Summary:
Thus, if you want to hide the text and leave a blank space in its place, use visibility: hidden. If you want to hide the text and have it act as if it were not there at all, use display: none
I would recommend you to create a separate class for the text and set
visibility:hidden;
for that class.

Floated elements inherit top margin when the containing element has a clear property

I've stumbled across a bug with floated elements within a container when that container uses clear: both; (or left/right). In Chrome (not Safari), the first floated element is positioned correctly, but all subsequent elements appear to inherit the top margin of the parent element, shifting them out of line.
Here's the problematic code: http://jsfiddle.net/peterjmag/3zJey/1/
Try the toggle link to see the difference. Also, try various values for margin-top on #product-listing.
For those of you using other browsers, here's what the fiddle looks like for me (in Chrome 25.0.1364.160 for Mac):
Why does clear: both; cause this behavior in Chrome? According to the CSS 2.1 spec, the clear property should only affect floated elements that appear earlier in the document, not within the targeted element.
(Of course, I know there are other more optimal ways to clear previous elements in the document which would not require a clear property on the container div—I'm simply trying to understand why this happens.)
It appears that this is indeed a Chrome bug: Issue 178134: Floated elements render incorrectly when parent element has a clear property + a top margin. According to that report, Chrome 27 and above are not affected.

Div Wrapping In IE6 Only

You can see the issue here: http://jsfiddle.net/6WuVz/7/
This works in all other browser (image top) but when viewed in ie6 (image bottom) it wraps incorrectly:
Note: You can see this in later versions of IE by using compatibility view and selecting IE5 Quirks.
From what I can tell, the div that holds your title doesn't have a set width. Therefore, IE is telling it to expand, and as it expands, it shifts downward, where there's space. Try setting a width for IE6 only and see if that fixes it.
Additionally, IE6 has some issues with overflow: hidden. Though it's usually in combination with position: relative, you may be running into something similar. If the previous solution doesn't work, you could try this.
Edit - Since you don't want to set an explicit width, I've thought of a few other options left to you:
Explicitly set clear: none on the non-floated element
Use a span element instead of div for the text in question (span is inline, while div is block, so it shouldn't expand to the parent width; given what you're doing, it probably makes more semantic sense to use span, anyway).
Use JavaScript to determine the width of the floated div for IE6, and set a size on the non-floated div accordingly (again, you can use conditional comments in your HTML to target IE6 exclusively)
Seriously consider whether it's worth supporting IE6 (ie - if this is on a site where the audience is fairly tech-savvy, you can probably forego IE6 support entirely, or at the very least, fixing this problem will cost your project more than the returns you get; but if you're dealing with healthcare providers, you probably have to still deal with IE6).
IE6 has a non-standard box model, which tells block-level elements to expand the full width of their container, instead of "shrink-wrapping" to their content. Their content is larger than the width they're allowing, and the float property takes the floated elements out of the document flow (which is why your overflow: hidden, when turned to overflow: visible, runs over top the floated content). The newer browsers have basically an "updated definition" (so to speak) of the float property, which tells sibling content to flow around the floated element, in addition to taking it out of the normal document flow. CSS-tricks has a good article on float, as does A List Apart, if you need more information.

webkit browsers hide LI A (display:block) elements. sometimes

I'm building (kinda experimental) menu which is built on classic 'ul li' base except 'a' elements are set to display:block to enable precise positioning and sizing. some transform:rotate also appears, but this does't influence following behaviour:
All browsers except webkit ones display all menu items here the same way (correctly). But webkit hides child items ('item 2a', 'item 2b', 'item 3a', ...). The links are apparently present as cursor changes while hovering over the area where they should appear, but they are not visible. Oddly enough, when I set size of these invisible elements to slightly overlap their designated space (height of their parent LI) they appear visible (here)
Do you know what's happening here?
Thanks.
Personally, I think negative margins and css rotation combined can be a bit of a pain.
If I was you I'd
Set the a.rotate links to absolute positioning, so they don't upset the flow.
Dump the negative margins
Play with it a bit
I made this example here: http://jsfiddle.net/958qQ/
The rest should be easy.
I don't like your method using margins, it's complicated. think it will better to style with positioning. absolute position for child elements

Resources