Are DOM nodes synchronous? - html

I was wondering whether DOM node attributes are synchronous in terms of styling information? I was reading the following article, and I read the following line
Scripts asking for style information, like "offsetHeight" can trigger incremental layout synchronously.
From the article, it seems to indicate that there is a "dirty node" system that will pause script execution until the document has been fully laid out. So, if I had a dirty node n, if n.offsetHeight is called from javascript, the article suggest that n.offsetHeight will not return until the offset height has been fully reified. Is my understanding of this correct? Can I rely on the browser to always give me the current stable version of any attached DOM element.
Put succinctly, if I modify some styling on a node (using the style attribute, class names, dynamic css, whatever else), and then read some property that depends on said styling, can I always be certain that the value I get back will be the value of the node with my previous styling applied? If this is not the case, how can I know when my styling changes have been applied?

When you read information from the DOM elements, you will always get the current value, and properties that rely on other properties or other elements will always be correctly calculated when you read them.
When you change the DOM so that the layout changes, all the elements are not recalculated directly when you make the change. That would just be a waste, if you change something more that would need another recalculation. The layout remains uncalculated as long as there is no need for the recalculation. If you read a property that is depending on that recalculation, it will be done before the value is returned.
So, by planning how you set and read properties, you can avoid unnessecary recalculations.

Related

Extract CSS code related to a specific component

Is there a way to extract a component (e.g., button) from an online website without going over the CSS(in case the CSS is complicated)?
Let's say I want to extract this button and only the CSS related to the component.
)
Could it be converting CSS to inline CSS or something similar?
It's easy to get the window.getComputedStyle() of an element, but it would be cluttered with a lot of properties and values that are probably irrelevant to you, and would still miss some important information about where some values came from (for example, if they are calculated by percents or are inherited).
The "computed" tab of the browser's DevTools would give you more clear and detailed information about the values of most properties, but you would still need some manual work. I don't think there is an equivalent JavaScript API that you can use to automate the process, and even if there was, it seems that there isn't a simple criteria to distinguish between the properties and values that are "relevant" and those who are not.

Using a listener for a tap inside a dom-if

I have a simple button that I want to trigger something when pressed. I gave the button an id and created a listener for id.tap. This works fine, but when I put my button inside a template[is=dom-if] it stops working. Is this meant to work like this? How do I solve this?
Elements inside a dom-if don't exist yet when the element is created, so they're not accessible using this.$. Either give the element an on-tap attribute, or use Polymer.dom(this.root).querySelector to find the element.
FYI, the documentation recommends against the liberal use of dom-if.
Since it is generally much faster to hide and show elements rather than destroy and recreate them, conditional templates are only useful to save initial creation cost when the elements being stamped are relatively heavyweight and the conditional may rarely (or never) be true in given usages. Otherwise, liberal use of conditional templates can actually add significant runtime performance overhead.
Usinghidden$=condition might be the best solution.

Is it better to not render HTML at all, or add display:none?

As far as I understand, not rendering the HTML for an element at all, or adding display:none, seem to have exactly the same behavior: both make the element disappear and not interact with the HTML.
I am trying to disable and hide a checkbox. So the total amount of HTML is small; I can't imagine performance could be an issue.
As far as writing server code goes, the coding work is about the same.
Given these two options, is one better practice than the other? Or does it not matter which I use at all?
As far as I understand, not rendering the HTML for an element at all, or adding display:none, seem to have exactly the same behavior: both make the element disappear and not interact with the HTML.
No, these two options don’t have "exactly the same behavior".
If you hide an element with CSS (display:none), it will still be rendered for
user agents that don’t support CSS (e.g., text browsers), and
user agents that overwrite your CSS (e.g., user style sheets).
So if you don’t need it, don’t include it.
If, for whatever reason, you have to include the element, but it’s not relevant for your document/users (no matter in which presentation), then use the hidden attribute. By using this attribute, you give the information on the HTML level, hence CSS support is not needed/relevant.
You might want to use display:none in addition (this is what many CSS supporting user agents do anyway, but it’s useful for CSS-capable user agents that don’t support the hidden attribute).
You could also use the aria-hidden state in addition, which could be useful for user agents that support WAI-ARIA but not the hidden attribute.
I mean do you need that checkbox? If not then .hide() is just brushing things under the carpet. You are making your HTML cluttered as well as your CSS. However, if it needs to be there then sure, but if you can do without the checkbox then I would not have it in the HTML.
Keep it simple and readable.
The only positive thing I see in hiding it is in the case where you might want to add it back in later as a result of a button being clicked or something else activating it in the page. Otherwise it is just making your code needlessly longer.
For such a tiny scenario the result would be practically the same. But hiding the controls with CSS is IMO not something that you want to make a habit of.
It is always a good idea to make both the code and its output efficient to the point that is practical. So if it's easy for you to not include some controls in the output by adding a little condition everything can be managed tidily, try to do so. Of course this would not extend to the part of your code that receives input, because there you should always be ready to handle any arbitrary data (at least for a public app).
On the other hand, in some cases the code that produces the output is hard to modify; in particular, giving it the capability to determine what to do could involve doing damage in the form of following bad practices: perhaps add a global variable, or else modify/override several functions so that the condition can be transferred through. It's not unreasonable in that case to just add a little CSS in order to again, achieve the solution in a short and localized manner.
It's also interesting to note that in some cases the decision can turn out to be based on hard external factors. For example, a pretty basic mechanism of detecting spambots is to include a field that appears no different in HTML than the others but is made invisible with CSS. In this situation a spambot might fill in the invisible field and thus give itself away.
The confusion point here is this: Why would you ever use display: none instead of simply not render something?
To which the answer is: because you're doing it client side!
"display: none" is better practice when you're doing client side manipulations where the element might need to disappear or reappear without an additional trip to the server. In that case, it is still part of the logical structure of the page and easier to access and manipulate it than remove (and then store in memory in Javascript) and insert it.
However if you're using a server-side heavy framework and always have the liberty of not rendering it, yes, display:none is rather pointless.
Go with "display:none" if the client has to do the work, and manage its relation to the DOM
Go with not rendering it if every time the rendered/not rendered decision changes, the server is generating fresh (and fairly immutable) HTML each time.
I'm not a fan of adding markup to your HTML that cannot be seen and serves no purpose. You didn't provide a single benefit of doing that in your question and so the simple answer is: If you don't need a checkbox to be part of the page, then don't include it in your markup.
I suspect that a hidden checkbox will not add any noticeable time to the download or work by the server. So I agree it's not really a consideration. However, many pages do have extra content (comments, viewstate, etc.) and it can all add up. So anyone with the attitude that they will go ahead and add content that is not needed and never seen by the user, I would expect them to create pages that are noticeably slower overall.
Now, you haven't provided any information about why you might want to include markup that is not needed. Although you said nothing about client script, the one case where I might leave elements in a page that are hidden is when I'm writing client script to remove them. In this case, I may hide() it and leave in the markup. One reason for that is that I could easily show it again if needed.
That's my answer, but I think you'd get a much better answer if you described what considerations you had for including markup on the page that no one will see. Surely, it must offer some benefit that you haven't disclosed or you would have no reason to do it.

How to navigate accross shadow DOMs recursively

I want to validate a custom polymer element. To do this, I want in javascript to access all my nested polymer elements to see if they are valids.
I can't find an easy way to do this.
this.querySelectorAll does not find my inputs that are nested in other polymer elements. It seems I can't use "/deep/" in these selectors.
Is there an easy way to do this ? Or do I have to do a recursive javascript methods that will call a querySelectorAll in all elements with shadow roots ?? (I guess performances will get ugly...)
Thanks for your help.
If there is no fast solution, I will probably try the other way around (have my inputs register to the parent)
Answer:
element.querySelectorAll() will find some elements when using /deep/, however, it only goes so far (1 shadow dom level). This would indeed necessitate recursive calls from each ElementNode.
Note:
This type of behavior largely goes against the core tenets of HTML (i.e. that the web page works no matter how well-formed the content is). In other words, all elements are valid no matter their placement.
As an example, I have made a custom element that only renders specific child elements and hides all others. This still keeps in line with the above tenet, as an element's base rendering is controlled by the element/agent, but allows for the developer/designer to customize its presentation aside from the standard presentation.

Responsive data tables - alternatives for axis and scope attributes

This page has a solution for responsive data tables that I really like. It basically turns each row into its own table (almost like a list of 'info cards'). My issue with it is that you have to generate CSS with duplicate data. I'd prefer to write styles that would allow the content of the ::before pseudo-element simply reference the appropriate th element.
Such a thing seems to me to be on the edge of what the CSS spec was really designed for, but I'd like to give it a shot.
A comment on the previously mentioned article referenced an 'axis' attribute. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td tells me that axis and scope are both obsoleted and may be unsupported.
Is there an easy (CSS-only) way without doing any extra work on either the server or with js client-side to get the content of the before to be the text in the td's corresponding th?