For example if we have:
<style>
.child {display:none;}
</style>
<script>
$('.parent:contains("Invisible")').addClass('newparent');
</script>
<div class="parent">
<div class="child">Invisible</div>
</div>
This code works! Parent div will receive new class newparent. This has no logic to me because I always believed if I put display:none that this is it, element is gone. You can't find it in inspect element, view source, etc.
But obviously this is not the case if javascript can find it. That means that this element is rendered somehow. So I'm wondering if element with display:none is still out there is it affecting performance?
For example if we have right sidebar and we decide to hide it on mobile with display:none.
From experience I know that the site will load faster if sidebar has display:none, but question is still the same, what happens to the element with display:none, is it rendered somehow, if yes how and where?
You seem to have some misconceptions about display:none. It is a css property which causes the element to take up no room on the page. The element is still rendered and still exists all the same.
MDN display
I always believed if I put display:none that this is it, element is gone. You can't find it in inspect element, view source, etc.
Your assumption is incorrect. The element is still part of the DOM. It's just styled to not be rendered visibly on the screen.
So I'm wondering if element with display:none is still out there is it affecting performance?
No more than any other element would. If you have so many elements as to affect performance, then you'd certainly want to address that. But it has little to do with the styling.
what happens to the element with display:none, is it rendered somehow, if yes how and where?
It's part of the structure of the DOM in memory. Everything about it is still there. It's just not visibly shown in the viewport.
CSS styling doesn't change the structure of the HTML. It just governs how that structure is visibly displayed on the screen. (Or in some other medium.) JavaScript, on the other hand, can be used to modify the DOM in-memory, and those changes are also reflected in the display. (As your test demonstrates.)
Related
I am providing a widget to my users. They include my JS api in a script tag. Once they have a <div class="PutWidgetHere" /> in their body tag, I aim to render an image and a text box inside the div.
My JS api finds the div with class=PutWidgetHere. It appends an image element and then an input type=text element. The input must be placed right at the center of the image so I use absolute positioning relative to the div, z-index and a couple other css properties.
All in all, I am able to accomplish this fine on a blank page. However, if I integrate my widget on a populated page, say the homepage of StackOverflow, things get ugly. It still works but looks ugly. Mostly because my input text inherits CSS properties from the page such as padding, margin, hover etc.
How can I prevent the page from messing with my widget?
Upon research, I found out that you can't disable inheriting of CSS properties for an element. For padding and margin, I could overwrite them using !important but I cannot do this for all possible CSS properties my input could inherit?
I thought of placing an iframe inside the div. But then this makes it impossible for my image and input elements to talk with the host page. Plus, an iframe (borderless) that hosts an image and a button might mess with the parent page?
Any suggestions on how to isolate my input text from parent CSS is welcome :)
Get all styles that makes everything ugly and insert them into style property of element, with has highest priority then id and class styles.
Update:
You can also add some unique ID to your element and create custom stylesheet. You can either add <style> with html, or load <style> with javascript, or add to tag later after page load.
Update 2
Here is example of styles override http://jsfiddle.net/zhhxC/
I want to simplify things in my jQuery Backbone.js web application. One such simplification is the behavior of my menu and dialog widgets.
Previously I created the div boxes of my menus at start and hid them using display: none; opacity:0;. When I needed a menu, I changed its style to display:block then used the jQuery ui position utility to position the div box (since elements with display:none cannot be positioned) and when it was done, finally changed its style to opacity:1.
Now I want to just hide them with visibility:hidden, and when I need one, I use the position utility and then change the style to visibility:visible. When I begin using this new approach, I will have around 10 div boxes throughout the web application session that are hidden but occupy space, in contrast to the previous div boxes hidden with display:none.
What are the implications of my new approach? Does it effect browser performance in any regard?
display:none; elements are not in the render tree all, so they will perform better at face value.
I doubt you will have any real visible performance problems from this though. If you need opacity: 0 or visibility: hidden because of their functionality, then just use them. If you don't need the functionality, then use display: none;
If you are toggling between visible and invisible states via javascript then visibility:hidden should be the better performer. Seeing as it always takes up the same amount of space in both visible and hidden states it won't cause a reflow of the elements below it every time you make it appear of disappear. For display:none you are removing it from the flow of the document and then when you set it to display:block you are rerendering it and pushing everything below that element down, essentially laying all that stuff out again.
But if you are doing something like toggling visible states on button presses then you really should be using what suits your needs rather than what performs better, as the performance differences are negligible in such cases. When you are animating with the dom at around 20 times per second THEN you can worry about the performance of visibility:hidden vs display:none.
visibility: hidden does not cause a re-flow on the document, while display: none does.
display: none: The HTML engine will completely ignore the element and its children. The engine will not ignore elements marked with visibility: hidden, it will do all the calculations to the element and its children, the exception is that the element will not be rendered to the viewport.
If the values for position and dimensions properties are needed then visibility: hidden have to be used and you have to handle the white space in the viewport, usually by wrapping that element inside another one with 0 width and height and 'overflow: hidden'.
display:none will remove the element from the document's normal flow and set the values for position/height/width to 0 on the element and its children. When the elements display property is changed to other value than none, it triggers a complete document re-flow, which can be a problem for big documents - and sometimes not-so-big documents being rendered on hardware with limited capabilities.
display: none is the natural and logical solution to use when hiding elements on the viewport, visibility: hidden should be used as a fallback, where/when needed.
EDIT:
As pointed by #Juan, display: none is the choice to go when what you need is to add many elements to the DOM tree. visibility: hidden will trigger a re-flow for each element added to the tree, while display: none will not.
I'm not aware of any performance difference between display:none and visibility:hidden - even if there is, for as little as 10 elements it will be completely negligible. Your main concern should be, as you say, whether you want the elements to remain within the document flow, in which case visibility is a better option as it maintains the box model of the element.
Well, the main performance difference between display: block and visibility: hidden is that if you have a list of, say, 100000 elements, the visibility: hidden won't save you from DOM hanging because it doesn't remove elements from DOM.
visibility: hidden acts like opacity: 0 + pointer-events: none. display: none acts like Element.remove().
Live example: https://jsfiddle.net/u2dou58r/10/
From personal experience having just tried both on a simple static page with a form located beneath a "hidden" button, visibility: hidden performs flawlessly whereas display: none causes clickable buttons to slightly jump upon clicking, as if it tries to show the hidden button for a millisecond.
Well, visibility:none still uses the space of the div.
So you could maybe skip the positioning part because its place is already allocated (and by that get a better performance).
But I somehow guess that you need your display:none approach to allocate space correctly when the "show" event is triggered.
I think this could be somehow related to this question: CSS Properties: Display vs. Visibility
I'll just quote the interesting part:
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.
So there should be no real difference in regard to browser performance, because both versions are still in the DOM hierarchy. These properties only affect how an element is displayed in regards to the DOM.
The usual way to show\hide block in html is switching it's display property. But in case of performance of rendering, wouldn't it be better to play with z-indexes?
http://jsfiddle.net/WawVH/
Matter of preference really. Display:none removes the element completely, which I think it then is no longer a node in the DOM structure, thus saving memory. Someone correct me if I am wrong.
You could run into a problem with your implementation though if you have overflowing content.
http://jsfiddle.net/yeQfC/
But you could always just turn off overflow with
overflow:hidden;
in your .content CSS definition
http://jsfiddle.net/gF3JC/
I have a widget which is injecting a popup into different web sites, as an absolute positioned div.
I want the popup to look the same on all. however, the paragraphs and other html elements inside the div are effected by the hosting site CSS.
Is there a way to reset all the properties of elements in the div in an efficient way without a css file which will have to consider all the options and element types?
Note: I need a clean javascript/css/html solution, Cant assume jQUery is available.
The best you can do is using an iframe for the widget content. There is no way to reset all the inherited CSS styles using only CSS.
Short anwer: To my knowledge, no.
Long answer: Since you don't want the current document's style to apply to the elements inside your absolutely positioned <div>, maybe the best would be to use an <iframe> element instead of a <div>.
That way, the popup elements would be isolated in their own document and would be independent from the current document's style. The document in your <iframe> may even have a different doctype, in case you require that.
Well you can arbitrarily set some style attributes with JS but it'll be a long list, it won't be pretty or efficient, and CSS is designed to achieve the exact opposite. You could also add an inline style block with some ID specific CSS selectors and I guess !important tags, but again it's not pretty - for one thing guaranteeing that ID is hard/impossible.
Basically if it's not your page, your control of it is (rightly) illusionary.
A requirement for a current project of mine involves "highlighting" an HTML element in the context of a page. That is, I need to provide some sort of visual effect that decreases the brightness of the surrounding page while leaving the element at full brightness.
To achieve this, I'm trying the following approach:
Determining the highest z-index value of any element on the page (using JavaScript).
Creating an element to function as a "backdrop" on top of the page. This is just a <div> with a translucent gray background image, sized to 100% of the width and height of the <body> element, with position: fixed. I set its z-index to 1 greater than the highest z-index I've found on the page, with the intent that it will overlay every other element on the page.
Change the z-index of the "highlighted" element to 1 greater than the backdrop. The intent is to allow it to sit on top of the backdrop, which in turn sits on top of the rest of the page.
I got it working on a quick test page:
http://troy.onespot.com/static/stack_overflow/z_index_test.html
but when I tried to set it up on a few actual Web pages, it didn't work in all cases. For example:
http://troy.onespot.com/static/stack_overflow/z_index.html
Here, I've inserted two "dummy" elements on a copy of a Jacksonville.com article page, both with a class of test (if you're looking at the page source, they're at lines 169 & 859).
I also added some JavaScript (using jQuery) at the very end of the page that functions as I've described above.
The first <div class="test"> does function as I'd expect it to. However, the second one does not - it seems to still be stuck beneath the "backdrop" element, despite having a higher z-index.
I think this may have something to do with stacking contexts, but after reading through the relevant W3C docs (http://www.w3.org/TR/CSS21/visuren.html#z-index & http://www.w3.org/TR/CSS21/zindex.html), I still can't fathom why this is happening. I'd appreciate anyone more familiar with z-index and stacking order than I to take a look at my examples and let me know if anything looks suspicious.
Please note that I've only tested these examples in Firefox v3.6.
Thanks very much for any help!
The problem is that the second test div is inside a bunch of other HTML elements, one of which must be creating a new stacking context (it may be the #wl-wrapper-tier-1 div). Basically, a new stacking context is created whenever an element is positioned and has a z-index other than auto, see this MDC article for more info on stacking contexts.
Ultimately this means you can't achieve your desired effect reliably with this method. I think you're probably better off composing 4 divs to surround the target element.
If the element that you're highlighting is inside a different element (stacking context) with a z-index lower than the backdrop, it will not appear higher than the backdrop, since the element's z-index only controls stacking order within that parent.
The only good solution is to clone the highlighted element and add the clone to the <body> tag.
Beware of inherited CSS styles, which would be lost.