CSS Selectors are parsed right to left, and then displayed.
With this in mind, based on this code:
<a href="#" class="myImage">
<img>
</a>
Which is more performant?:
.myImage img
or
.myImage img:only-child
Does :only-child help specificity in selector selection? So instead of initially matching all <img> in the document then looking for the parent class, does it only match <img>'s that are the only child (thereby reducing the pool of selections)?
reference read: http://csswizardry.com/2011/09/writing-efficient-css-selectors/
EDIT
Found further reading:
The sad truth about CSS3 selectors is that they really shouldn’t be
used at all if you care about page performance. Decorating your markup
with classes and ids and matching purely on those while avoiding all
uses of sibling, descendant and child selectors will actually make a
page perform significantly better in all browsers.
-David Hyatt (architect for Safari and WebKit, also worked on Mozilla, Camino, and Firefox)
Source: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/
Alright, so this depends completely on the use case. What I'm going to do is handle cases.
Point 1 - Concerning given example
Case A
Say your code is simply:
<a href="#" class="myImage">
<img>
</a>
In this case .myImage img and .myImage img:only-child will have essentially identical performance hits. Reason being is as follows:
CSS performance hits are derived from having to style or re-style boxes. What CSS does is affect your graphics processor, not the CPU, so we only care about visual updates. And styling things again with duplicate properties DOES cause a redraw (By this I mean duplicate properties that are applied at a later time, which selectors generally cause).
Usually, .myImage img would style ALL <img>s in .myImage. While using the only-child selector may not style all (obviously).
But in this example, both .myImage img and .myImage img:only-child would do identical things, since they would both cause 1 draw/redraw on the same box.
Case B
But suppose we have:
<a href="#" class="myImage">
<img>
<img>
</a>
Here though, we have a different story.
In this example, only-child wouldn't work at all, since <img> is not the only child.
Case C
Finally, suppose you have this, but you only want to style the under the :
<a href="#" class="myImage">
<img>
</a>
<div class="myImage>
<img>
<img>
</div>
In this case, using the only-child selector would be significantly better performance-wise, since you only will style one element, instead of three.
Conclusion and Takeaway
Basically, remember a few things.
CSS selectors help you with writing code because you get to add less IDs and Classes, however, they are almost always less efficient than using all IDs and Classes, because using selectors will causes extra redraws. (Since you'll inevitably style multiple elements with some selector, and then re-style other things with IDs or classes, causing unnecessary redraws)
only-child is NOT faster than .class child if that .class only has one child.
Technically what you are comparing are two completely different things, used for different purposes.
Conclusion
In final answer to your question. In your shown example, neither is more efficient than the other since they cause identical redraws.
However, as
"Does :only-child help specificity in selector selection?"
goes: Yes, that's the point of the selector. See: http://www.w3schools.com/cssref/sel_only-child.asp
Sources:
I am a significant volunteer developer for Mozilla Thunderbird and the Mozilla project and work in the CSS area.
FYI
There are of course weird exceptions to this, but I won't go over them here since I think your exact question doesn't give a brilliant example.
Point 2 - Concerning speed of find selectors
I am purposely trying to drive home the point that it is the drawing the causes the CSS perf hit, not finding the selectors. However, the reason I say this is not because finding selectors takes no time, but instead because it's time is miniscule to the time caused by drawing. That said, if you did have 5,000 <div>s or something, and attempted to style a few using pseudo selectors, it would definitely a little longer than using CSS classes and IDs.
Again though, in your example it would make no difference, since it would look through each element anyway. Why only-child is helpful perf-wise is because it would stop searching for some element after it finds more than one child, whereas simply doing class child would not.
The problem with pseudo selectors is that they usually require a lot of extra searching AND it happens after IDs, classes, and such.
The links you provided are actually very helpful and I'm surprised they didn't answer your question.
One thing I should point out is that many selectors believed to be slow may be vastly improved now. See: http://calendar.perfplanet.com/2011/css-selector-performance-has-changed-for-the-better/
Remember selector performance is only important on very large websites.
Related
If h1 is considered a block, then does that make the spans elements of the h1 block? I guess, they are elements of the h1 block. What I want to know is, which one of the two codes is accurate? In the first one, I used underscores, and in the second one, I used dashes. Which one is accurate?
<h1 class="heading">
<span class="heading__main">physics</span>
<span class="heading__sub">the mother of all sciences</span>
</h1>
<h1 class="heading">
<span class="heading--main">physics</span>
<span class="heading--sub">the mother of all sciences</span>
</h1>
NOTE: Do not answer if you don't know BEM. I am telling this because the above terminology resembles very much with basic HTML and CSS.
Up front:
From a BEM point of view it is irrelevant whether an html element in a block has semantic meaning (like H[1...6], P, ARTICLE, SECTION etc.) or is meaningless like SPAN or DIV. BEM is concerned with organizing the presentation not with organizing html structure. BTW, you could make SPAN a block element or DIV an inline element with the respective display-definition in your BEM-class. None of this matters when it comes to BEM.
Let's get to the core of your question.
I challenge the answer of Himanshu Saxena.
If you have a block class named
heading
then if you are using a modifier on that very class like
heading--main
the BEM semantic expresses that you are modifying that very block, which in your case is the h1 tag.
If you apply the block's class modifier on a tag other than the tag to which the block class is applied, it's a contradictory information you send to the reader of your code.
So, your first code example is accurate because it clearly states, that
heading
is your block. All potential modifiers on heading should be applied to the tag which contains the heading block class. That's the only location that that class' modifier belongs to.
If you indeed had a modifier like
heading--main
you'd have to to apply it to your h1 tag, because your bem expression semantically reads: "I am modifying the rendering of heading by applying the class heading--main".
You can't (of course you can, but then it's not BEM anymore) apply the heading's modifier to another tag, which does not bear the heading tag.
The classes
heading__main
heading__sub
clearly express that there is structural relationship between heading and main and that heading__main refers to an element somewhat below heading.
Bear in mind, that the BEM structure does not need to reflect the HTML structure.
Another important aspect of BEM is that the block should be in control of the location and the size of its enclosed elements.
In order to allow this you need to have an element class.
The only modifiers BEM allows on elements are the elements' modifiers but never ever its surrounding block's modifiers.
I hope, it wasn't too confusing. In any case stick with your first example, it's definitely the right one.
From the above example you shared the Modifier looks appropriate.
Since its still debatable to be an element or a modifier. Below are my observation.
Since both the span are coming under same h1 tag they can be considered as element of H1 since as per the name's main and sub these are two different types and, when we talk about types of a block which means we are changing the state.
When there is a state change, it should be considered as a modifier.
Hence for me modifier looks more suitable than an element.
Lets say I have an HTML div containing numerous form elements that are all watching model values, if I use ng-show, ng-if, or ng-switch on the div to hide it, will this stop angular JS from doing dirty checking on the form elements and thus improve the performance of my app?
I figure that if the bound elements are not visible then there's no need for angular to be checking the values bound to them.
ng-show and ng-hide will only set a CSS display style, and will still process the bindings. ng-switch, however, will completely comment out the cases that do not apply, which in turn means bindings in those are not processed. I agree, however, with Edmondo1984's reply, that I doubt you should base your choices on this. Do not rewrite your ng-shows as ng-switches because of this!
You can verify this with the Chrome extension Batarang, the performance tab shows which watches are active.
some browser plugin, like readability can extract the 'article' from a webpage. Does anyone has idea about how to do it? What's the difference between the real articles and ads or comments?
Well, it depends how you want to define "real articles"...
Taking HTML5 into consideration, a webpage is constructed of semantic tags. Pages no longer have to be built with elements like <div> that have exactly no semantic meaning. In HTML5 you may use <section>, <article>, <header> and so on. Those elements can give an application pretty good sense of what is the main content of a webpage (e.g. print <article>s and skip <nav>s...)
Of course, not many pages use those tags yet. Furthermore, the tags might get abused and lose their meaning. In that case I'd stick to some statistics, e.g. selecting the largest elements in a HTML document. Moreover, if you have to scrape a webpage, you could use a modification of some pattern-matching algorithm, DIPRE for instance.
In the past, I created some divs to act like articles. Now I am thinking about changing it to HTML5 tag article...
Is there an important diference (in terms of efficiency) between using HTML elements or using equivalent divs created by the user?
For example: Will the browser load the pages faster if they are built only with HTML elements?
Short answer: No.
Long answer: maybe, if it will decrease the amount of markup you use. But not likely.
The benefit of using semantic tags is to add more meaning to the markup, not improve performance.
May be. When you cretae a div and add styling to it, the browser needs to first interpret the element and then process the style over it and render it. If you use the appropriate HTML element, it would put less burden on the rendering engine.
I'm trying to use CKEditor for a project and I found the need for bookmarks. The documentation says that the intrusive way to create bookmarks add span elements in the source. This is just fine with me and that is exactly what I would want it to do.
However, I can see in the source that the span elements are wrapped in p elements.
<p><span id="cke_bm_147S" style="display: none;"> </span> </p>
This creates problems for me with the way the text is displayed and mainly when trying to navigate the document.
I didn't find anything that even mentions the creation of these p elements. Could I have set something wrong? Is there a way to prevent these to be created?
Thank you
The span bookmark is an inline element so it cannot be the root element of the content. It is wrapped in a block element (which is by default a paragraph).
This behaviour depends on editor enterMode. If it is a default one - ENTER_P - you will have a p element as a wrapper. For ENTER_DIV you will have a div element. And for ENTER_BR there will be no wrapper which means it is the effect you would like to achieve.
Check this codepen for demo.
Please keep in mind that enterMode other that ENTER_P is not recommended due to some caveats. So maybe in your case it will be better to reconsider some different solutions instead of changing enterMode.