I am working on asp.net webforms. I am displaying a asp:RegularExpressionValidator in a <td> element which validates entry in a textbox. When the page loads, it is displayed as a <span> element with visibility:hidden. The problem is that in Firefox, it still occupies space, which doesn't happen in IE and Chrome. Because of this the html is not displayed properly in Firefox. Is there any solution for this?
"Visibility: hidden;" renders the element but keeps it invisible.
If you intend not to load the element, you should use
.someElement { display: none; }
This would not even reserve the space for the specified element.
Hope this helps..
You should try display:none instead of visibility:hidden.
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.
I'd recommend a different approach... I know that code depends on asp.net... I presume the thing you don't want is to have a bigger spacing because of those validators, or you don't want the layout to be expanding on error highlight, considering that, I'd suggest:
Make all validator messages having position absolute (I hope you have a container for each field, that one needs to have position: relative)
As each validator have absolute position, won't take more vertical space (it's better to add the code via a css class, which should have something like:
.validatorMessage {
position: absolute;
left:0;
top: 2rem /* should be the height of the field */
}
The only issue is, when those messages fires up, will shorten the available space, but I think is a reasonable tradeoff.
Hope this can help
The HTML below specifies a button and a div that have identical class and contents.
<div class="root"><!--
--><button class="outer"><div class="middle"><div class="inner">label</div></div></button><!--
--><div class="outer"><div class="middle"><div class="inner">label</div></div></div ><!--
--></div>
In this example, I have explicitly set every CSS property1 for the classes outer, middle, and inner2.
This means that both the button.outer and div.outer sub-trees of the DOM should have completely identical CSS settings. Presumably, as well, no CSS properties for these elements are getting their values from anywhere else besides the provided stylesheet.
As the example shows, the side-by-side button and div look quite different. Specifically, in the button, the label appears at the bottom of the element, whereas in the div it is vertically centered. (The label is centered horizontally in both cases. Also, note that all the classes have the setting vertical-align: middle.)
I have observed this difference with all the browsers I've tested so far (Chrome and Firefox).
Since there is no difference in the stylesheet settings for the button.outer and div.outer elements, and their descendants, I figure that the difference in their appearance is due to some CSS property with a value (such as auto or normal) that gets interpreted differently by the browser depending on the whether the context is a button or a div element.
My immediate goal here is to understand sufficiently well why the button and the div are being rendered differently so that I can adjust the CSS intelligently.
My longer term goal is to make CSS coding more predictable. Currently I find that my CSS is completely unstable due to gross inconsistencies like the one shown in the example.
My question is:
how can the difference in appearance between the button and the div be explained?
1 As reported by Chrome's devtool.
2 I took the vast majority of the values for these settings from Chrome's devtool's listings. The point was to ensure that both the button and the div elements had the same setting (whatever it may be) for each CSS property.
This is likely due to different meanings for the value of auto for the position of elements inside of a button. If you expand the size of a div, the content by default will be in the top-left corner. If you do the same for a button, the content will be centered horizontally and vertically.
Since the button's top and left values for auto is to be centered and not in the top left corner, you can reset top and left to always act like a typical div would. These are the properties to change on .middle:
.middle {
top: 0;
left: 0;
}
Here's the forked JSFiddle with those changes to .middle.
Different elements have different default settings. There is an enormous amount of CSS in your demos, and it's largely overkill and very hard to determine where exactly the differences in rendering are coming from.
Have you tried a CSS reset instead? These will resolve most of the discrepancies between elements and browsers, giving you a blank slate to add your own styles.
how can I determine the property (or properties) that account for the difference in appearance between the button and the div?
By clicking through them one by one and toggling them on and off in Dev Tools. If you turn off position:absolute on the middle class, you'll see what you're probably expecting in layout. I found this by clicking through all the properties in the Elements > Styles panel. See:
https://jsfiddle.net/vfdd9p8L/
This is probably a bug that you're encountering. Browsers have lots of them! By layering on so many styles at once, you're probably backing into a weird corner case with respect to the layout algorithms. To isolate the bug for help and/or reporting, try to create a reduced test case, which creates an unexpected discrepancy, but using the minimal number of elements and declarations.
(Also note that your fiddle is including jQuery CSS, which includes Normalize, which is a whole other layer of styling.)
Can anyone explain this behavior in FF?
Fiddle: http://jsfiddle.net/4mrt8wq3/
<style>
.b { display: inline-block; }
#a { display: block; }
</style>
<div class="b">
<label>xxxxxxxxxx</label>
<input type="text" id="a"/>
</div>
<div class="b">
<label>xxxxxxxxxx</label>
<div> / </div>
</div>
Only in firefox, the first div is positioned one line lower than the second. It works correctly in Chrome and IE (at least IE11). It's as if the block element within the inline-block is wrapping below the second element for some reason.
Using overflow: hidden on the first div fixes the problem, but the second div is then positioned slightly oddly with about 4 or 5 pixels of margin above it. Placing overflow-hidden on both causes it to render correctly.
I am not looking for a solution to the problem, as I've already found one, but I'm at a loss of explaining the behavior... Can anyone explain WHY it's doing this?
Yes, interesting question. First we need understand that the default vertical alignment of inline-block elements is baseline, and the baseline of each such element is the baseline of the last line box in them.
In the second div with class "b", the inner div itself contains a line box to hold the '/' character. That then provides the baseline for the second div with class "b".
That baseline must align level with the baseline of the first div with class "b". The question becomes: where is the baseline of the last line box in that div?
By making the input element itself display:block, Firefox¹ takes the view that the input element is "replaced", it's contents are opaque to CSS, therefore no line box is ever created by the input element. So the last line of the first div with class "b" is the one containing the label, and that is aligned level with the line of the '/' character.
Chrome takes a different view. Chrome treats the input element as having an internal structure visible to CSS, so the innards of the element form a line box, whose baseline then becomes the baseline of the first div with class "b", and it is that which aligned level with the '/' character.
When you add `overflow:hidden', it affects the baseline of the inline-blocks such that their baselines cease to be the baseline of their last contained line box, and becomes the bottom margin edge of the element.
Which behaviour is correct is unclear. It depends on history and the somewhat adulterated notion of replaced elements. In the early days of browsers, the rendering of some elements was delegated to external systems, either the underlying operating system or a plug-in. In particular, this was true of the input element, where rendering was done by O/S calls. The O/S had no notion of CSS, so rules had to be defined to allow the effectively black boxes to interact with the rest of the page. Such elements were classified as "replaced" elements.
Note the way this is defined. There is no official list of elements that are replaced elements, an element is a replaced element if the browser chooses to delegate its rendering to a system outside the CSS world, so in theory you could have two browsers, one delegating the rendering of an element and one natively rendering it, and from the CSS rules get quite different interactions.
As browsers progressed, they stopped delegating their rendering of the input element and rendered it themselves, in the process making the renderings CSS aware. This causes a problem because extant web pages, which assume that the input elements will be rendered using the replaced elements' rules, can become unusable. If a browser allowed that to happen, it would lose market share. So for the most part, to avoid this, the browsers implement those elements' layouts to interact with the page as if they were replaced elements, even though in reality they are not.
How far they go in this respect is not well specified. The HTML5 spec does not recognise the form controls as replaced elements, and suggests that they be rendered as inline-block, which would make Chrome's behaviour correct, but there are many ways in which all the browsers including Chrome simply don't behave that way. From a backward compatibility perspective with old web content, the Firefox behaviour is more reliable.
Until the layout of form controls is specified much more tightly than is the case currently, it is impossible to conclusively say which behaviour is correct.
¹For me, IE11 behaves like Firefox. Opera 28 (blink engine like Chrome) behaves like Chrome. Opera 12 (presto engine) behaves like Firefox.
Your problem is that per spec setting overflow:hidden changes the baseline position of an inline-block. Firefox implements what the spec says. Chrome does not.
Solution:
<style>
.b { display: inline-block;
vertical-align: top; /*add this line */
}
#a { display: block; }
</style>
This problem is easier seen than described. See here: jsFiddle
To get a clearer understanding of what is going on, I have updated the fiddle to include a class .ui-sortable-placeholder to be visible and red. This is the class of the jQueryUI (normally) invisible element involved with the sortable. As seen here: http://jsfiddle.net/rLW9m/9/. Thanks to George for pointing that out in his answer. With this answer we can probably consider this resolved as far as the "what" but perhaps the "why" is still TBD.
Of the three scenarios shown, they all apply float:left to the LI elements but the final one behaves poorly; in the last bunch of sorted items, clicking on the first or second item "drops" the rest of the list beneath the row they were just in (and the item clicked).
The scenario is exhibited when the float:left CSS is applied directly to my <li>s using inline styling versus applying the same change via a css file. Is this a jQueryUI bug?
When I apply the CSS to my elements in the identical way to how jQueryUI's documentation shows (the first example in the jsFiddle), then the sorting occurs just fine. However, once the same CSS (as far as I understand it) is applied directly to my list items, then sorting behavior is erratic as described above.
The way to get jQueryUI to sort nicely in a grid is to apply the float only in your CSS file using classes or other mechanisms:
/* Starting from UL descriptor with LI descendants */
.ulClass li {
float:left;
}
/* or directly to LI element but still via CSS file */
.makeTheseLIsSortable {
float:left;
}
/* DOES NOT WORK properly to directly apply CSS
(items to the right are shifted below when items on left selected) */
<ul id='makeSortable'>
<li style='float:left'>test</li>
<li style='float:left'>three</li>
</ul>
Why are these two CSS applications handled so differently by jQueryUI? When it is rendered, it sure seems like the list elements themselves are float:left either way. What is your take? Why can't I apply the CSS directly to the list elements and get the same, expected behavior?
EDIT: Thanks to George, I now have a better understanding of what is going on. There are probably some really good reasons that jQueryUI doesn't copy down the element inline styles to their "placeholder element" but they do pass along class details. If a jQueryUI pro shows up later and considers this a bug then I'm glad to have reported it. Until then, be sure to apply your sortable element's float via a class! Can you explain why the inline styling is not included into the placeholder?
The problem is the place holder that jqueryUI inserts does not have a float left style on it. jQueryUI duplicates the element type and the classes on an item you are sorting for the place holder but it would appear it does not duplicate the inline styles.
The CSS rules visibility:hidden and display:none both result in the element not being visible. Are these synonyms?
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
They are not synonyms.
display:none removes the element from the normal flow of the page, allowing other elements to fill in.
visibility:hidden leaves the element in the normal flow of the page such that is still occupies space.
Imagine you are in line for a ride at an amusement park and someone in the line gets so rowdy that security plucks them from the line. Everyone in line will then move forward one position to fill the now empty slot. This is like display:none.
Contrast this with the similar situation, but that someone in front of you puts on an invisibility cloak. While viewing the line, it will look like there is an empty space, but people can't really fill that empty looking space because someone is still there. This is like visibility:hidden.
One thing worth adding, though it wasn't asked, is that there is a third option of making the object completely transparent. Consider:
1st unseen link.<br />
2nd unseen link.<br />
3rd unseen link.
(Be sure to click "Run code snippet" button above to see the result.)
The difference between 1 and 2 has already been pointed out (namely, 2 still takes up space). However, there is a difference between 2 and 3: in case 3, the mouse will still switch to the hand when hovering over the link, and the user can still click on the link, and Javascript events will still fire on the link. This is usually not the behavior you want (but maybe sometimes it is?).
Another difference is if you select the text, then copy/paste as plain text, you get the following:
1st link.
2nd link.
3rd unseen link.
In case 3 the text does get copied. Maybe this would be useful for some type of watermarking, or if you wanted to hide a copyright notice that would show up if a carelessly user copy/pasted your content?
display:none removes the element from the layout flow.
visibility:hidden hides it but leaves the space.
There is a big difference when it comes to child nodes. For example: If you have a parent div and a nested child div. So if you write like this:
<div id="parent" style="display:none;">
<div id="child" style="display:block;"></div>
</div>
In this case none of the divs will be visible. But if you write like this:
<div id="parent" style="visibility:hidden;">
<div id="child" style="visibility:visible;"></div>
</div>
Then the child div will be visible whereas the parent div will not be shown.
They're not synonyms - display: none removes the element from the flow of the page, and rest of the page flows as if it weren't there.
visibility: hidden hides the element from view but not the page flow, leaving space for it on the page.
display: none removes the element from the page entirely, and the page is built as though the element were not there at all.
Visibility: hidden leaves the space in the document flow even though you can no longer see it.
This may or may not make a big difference depending on what you are doing.
With visibility:hidden the object still takes up vertical height on the page. With display:none it is completely removed. If you have text beneath an image and you do display:none, that text will shift up to fill the space where the image was. If you do visibility:hidden the text will remain in the same location.
display:none will hide the element and collapse the space is was taking up, whereas visibility:hidden will hide the element and preserve the elements space. display:none also effects some of the properties available from javascript in older versions of IE and Safari.
visibility:hidden preserves the space; display:none doesn't.
In addition to all other answers, there's an important difference for IE8: If you use display:none and try to get the element's width or height, IE8 returns 0 (while other browsers will return the actual sizes). IE8 returns correct width or height only for visibility:hidden.
display: none;
It will not be available on the page and does not occupy any space.
visibility: hidden;
it hides an element, but it will still take up the same space as before. The element will be hidden, but still, affect the layout.
visibility: hidden preserve the space, whereas display: none doesn't preserve the space.
Display None Example:https://www.w3schools.com/css/tryit.asp?filename=trycss_display_none
Visibility Hidden Example : https://www.w3schools.com/cssref/tryit.asp?filename=trycss_visibility
visibility:hidden will keep the element in the page and occupies that space but does not show to the user.
display:none will not be available in the page and does not occupy any space.
display: none
It will remove the element from the normal flow of the page, allowing other elements to fill in.
An element will not appear on the page at all but we can still interact with it through the DOM.
There will be no space allocated for it between the other elements.
visibility: hidden
It will leave the element in the normal flow of the page such that is still occupies space.
An element is not visible and Element’s space is allocated for it on the page.
Some other ways to hide elements
Use z-index
#element {
z-index: -11111;
}
Move an element off the page
#element {
position: absolute;
top: -9999em;
left: -9999em;
}
Interesting information about visibility: hidden and display: none properties
visibility: hidden and display: none will be equally performant since they both re-trigger layout, paint and composite. However, opacity: 0 is functionality equivalent to visibility: hidden and does not re-trigger the layout step.
And CSS-transition property is also important thing that we need to take care. Because toggling from visibility: hidden to visibility: visible allow for CSS-transitions to be use, whereas toggling from display: none to display: block does not. visibility: hidden has the additional benefit of not capturing JavaScript events, whereas opacity: 0 captures events
If visibility property set to "hidden", the browser will still take space on the page for the content even though it's invisible.
But when we set an object to "display:none", the browser does not allocate space on the page for its content.
Example:
<div style="display:none">
Content not display on screen and even space not taken.
</div>
<div style="visibility:hidden">
Content not display on screen but it will take space on screen.
</div>
View details
There are a lot of detailed answers here, but I thought I should add this to address accessibility since there are implications.
display: none; and visibility: hidden; may not be read by all screen reader software. Keep in mind what visually-impaired users will experience.
The question also asks about synonyms. text-indent: -9999px; is one other that is roughly equivalent. The important difference with text-indent is that it will often be read by screen readers. It can be a bit of a bad experience as users can still tab to the link.
For accessibility, what I see used today is a combination of styles to hide an element while being visible to screen readers.
{
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
width: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}
A great practice is to create a "Skip to content" link to the anchor of the main body of content. Visually-impaired users probably don't want to listen to your full navigation tree on every single page. Make the link visually hidden. Users can just hit tab to access the link.
For more on accessibility and hidden content, see:
https://webaim.org/techniques/css/invisiblecontent/
https://webaim.org/techniques/skipnav/
Summarizing all the other answers:
visibility
display
element with visibility: hidden, is hidden for all practical purposes (mouse pointers, keyboard focus, screenreaders), but still occupies space in the rendered markup
element with display:none, is hidden for all practical purposes (mouse pointers, keyboard focus, screenreaders), and DOES NOT occupy space in the rendered markup
css transitions can be applied for visibility changes
css transitions can not be applied on display changes
you can make a parent visibility:hidden but a child with visibility: visible would still be shown
when parent is display:none, children can't override and make themselves visible
part of the DOM tree (so you can still target it with DOM queries)
part of the DOM tree (so you can still target it with DOM queries)
part of the render tree
NOT part of the render tree
any reflow / layout in the parent element or child elements, would possibly trigger a reflow in these elements as well, as they are part of the render tree.
any reflow / layout in the parent element, would not impact these elements, as these are not part of the render tree
toggling between visibility: hidden and visible, would possibly not trigger a reflow / layout. (According to this comment it does: What is the difference between visibility:hidden and display:none? and possibly according to this as well https://developers.google.com/speed/docs/insights/browser-reflow)
toggling between display:none to display: (something else), would lead to a layout /reflow as this element would now become part of the render tree
you can measure the element through DOM methods
you can not measure the element or its descendants using DOM methods
If you have a huge number of elements using visibility: none on the page, the browser might hang while rendering, as all these elements require layout, even though they are not shown
If you have a huge number of elements using display:none, they wouldn't impact the rendering as they are not part of the render tree
Resources:
https://developers.google.com/speed/docs/insights/browser-reflow
http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/
Performance differences between visibility:hidden and display:none
Other Info:
There are some browser support idiosyncrancies as well, but they seem to apply to very old browsers, and are available in the other answers, so I have not discussed them here.
There are some other alternatives to hide element, like opacity, or absolute positioning off screen. All of them have been touched upon in some or the other answers, and have some drawbacks.
According to this comment (Performance differences between visibility:hidden and display:none), if you have a lot of elements using display:none and you change to display: (something else), it will cause a single reflow, while if you have multiple visibility: hidden elements and you turn them visible, it will cause reflow for each element. (I don't really understand this)
One other difference is that visibility:hidden works in really, really old browsers, and display:none does not:
https://www.w3schools.com/cssref/pr_class_visibility.asp
https://www.w3schools.com/cssref/pr_class_display.asp
The difference goes beyond style and is reflected in how the elements behave when manipulated with JavaScript.
Effects and side effects of display: none:
the target element is taken out of the document flow (doesn't affect layout of other elements);
all descendants are affected (are not displayed either and cannot “snap out” of this inheritance);
measurements cannot be made for the target element nor for its descendants – they are not rendered at all, thus their clientWidth, clientHeight, offsetWidth, offsetHeight, scrollWidth, scrollHeight, getBoundingClientRect(), getComputedStyle(), all return 0s.
Effects and side-effects of visibility: hidden:
the target element is hidden from view, but is not taken out of the flow and affects layout, occupying its normal space;
innerText (but not innerHTML) of the target element and descendants returns empty string.
As described elsewhere in this stack, the two are not synonymous. visibility:hidden will leave space on the page whereas display:none will hide the element entirely. I think it's important to talk about how this affects the children of a given element. If you were to use visibility:hidden then you could show the children of that element with the right styling. But with display:none you hide the children regardless of whether you use display: block | flex | inline | grid | inline-block or not.
display:none; will neither display the element nor will it allot space for the element on the page whereas visibility:hidden; will not display the element on the page but will allot space on the page.
We can access the element in DOM in both cases.
To understand it in a better way please look at the following code:
display:none vs visibility:hidden