In class we are teached to avoid creating ID's in your HTML so you can use them to identify that element in your CSS file. Instead we must use selector specifity as much as possible.
Take for example this simple HTML:
<body>
<div>
<div>
<div>
The div you want to style.
</div>
</div>
</div>
</body>
Is it better to use this:
body > div > div > div{
color: blue;
}
or give the element an id (let's take 'middle') and use this:
#middle{
color: blue;
}
What are the differences (if any at all) performance and usability wise?
The difference in speed between IDs and Classes in modern browsers is so negligible in real world situations it is really not an issue. Therefore current main-line thinking is to use classes where extra clarity and specifity is needed. This way you avoid specifity wars and balances maintainability with code purity.
<body>
<div>
<div class="more-specific-if-needed">
<div class="middle">
The div you want to style.
</div>
</div>
</div>
</body>
.make-more-specific-if-needed .middle {
/* cool styles */
}
Or even use chained selectors to gain extra specifity. You could then split styles in to separate structure based build styles and appearance based theme styles.
<body>
<div>
<div>
<div class="semantic-role theme">
The div you want to style.
</div>
</div>
</div>
</body>
.semantic-role.theme {
/* cool styles */
}
For further reading:
http://csswizardry.com/2011/09/writing-efficient-css-selectors/
Why do browsers match CSS selectors from right to left?
Performance wise it's fastest to get an element by its id than it is to traverse the dom.
From a usability point of view I would be careful using too many id's since they can be only used once for an element.
So it's a question of what you think is more important and how many items we are talking about. Is the speed gain worth the losing of re-usability
Much better to use ID. Performance difference is minimal, and not the important point. I think code readability / maintainability is more important.
One advantage of using ID, is that you could move your element to a different part of the page, and it would retain it's style rules - without counting the containing elements.
Related
I have a web code generated by an aplication (built in angular). It is a menu choice where I need to hide some of them. It looks e.g. like this:
<div class=first>
<div class=second>
<a href=href1>
</div>
<div class=second>
<a href=href2>
</div>
<div class=second>
<a href=href3>
</div>
</div>
Now what I need is to hide the div which contains a element with href2.
I can hide the a element:
.first .second a[href="href2"] {display:none}
But I need to hide the whole div element. I thought:
.first .second < a[href="href2"] {display:none}
that doesn't work.
I KNOW THE JQUERY SOLUTION with has function. The problem is I can only adapt css files of the application. If i'm right I cannot use jquery in css file.
Please...any Idea how to do this ?
thanks a lot for help
best regards
Marek
At the moment there is (sadly) no way to adress the parent element with CSS.
I don't know your layout or CSS Code but maybe you can just structure your HTML-Code in a different way.
Edit
And now I understand your question...
To hide (for example) the 3th .second div you don't need to adress it from the child element but from the parent element.
What you are probably looking for are the nth selectors,
for instance: nth-child() or nth-of-type().
You can find more info here.
Also, you should probably take a look at the basics of HTML and CSS.
In your code you have not closed the <a> tags or wrapped the values of the attributes in quotation marks.
Wrong:
<div class=first></div>
Right:
<div class="first"></div>
To hide (for instance) the first element you could use the :first-child selector or the :nth-child() selector. Since you will probably use the nth-child() selector this would be:
.first > .second:nth-child(1) {
display: none;
}
I'm trying to dive into the BEM methodology. Even though it seems to be the 'must have' methodology for all project sizes, I'm kind of unhappy with it or am I just trying to use it the wrong way?
Using BEM the CSS gets divided into something like this.
.block {
/* Block code goes here */
}
.block--is-hidden {
/* Block modifier code goes here */
}
.block__element {
/* Element code goes here */
}
This seems to be pretty fine for me, as long as you do not reuse some code. Let's assume I'm using Bootstrap or any other CSS Framework/Library. Doing so I just want to use the grid. That being said my markup could look somehow like that.
<div class="container">
<div class="row">
<div class="col-xs-12">
...
</div>
</div>
</div>
According to BEM this would be a no go. Instead all the grid classes should be wrapper up in our corresponding block and element classes. A possible way to achieve this would be through SASS and it's #include. For me this basically results in redundant code.
So my question right now is. Am I missing something? I mean, using BEM while for e.g. loading Bootstraps .container code into every single of my own block styling would just result in an massive output CSS file. Is my approach correct? And if so - would I really sacrifice initial loading time just for the idea of better organized CSS and better readable markup?
Is there a reason your blocks have to begin at the container level? I'm not sure if it's a violation of BEM methodology exactly, but I personally "begin" my blocks more at the html>body>.container level. So:
<html>
<body>
<div class="container">
<div class="cheesecake">
<h1 class="cheesecake__heading"></h1>
</div>
</div>
</body>
</html
With SCSS looking something like:
.cheesecake {
&__heading {}
}
And so on.
Here is an HTML fragment:
<div class="wrapper">
<div class="ebook">
<div class="page"></div>
</div>
<div class="book">
<div class="page"></div>
</div>
<div class="document">
<div class="page"></div>
</div>
</div>
I want to match all divs with the page class with parents divs having ebook or book classes only. This selector can be used:
div.ebook div.page, div.book div.page
However is there a CSS engine suporting the following syntax ?
(div.ebook, div.book) div.page
or better
div.?book div.page
I'm not interested with a solution like this: div:not(.document) > div.page.
The proposed syntax takes the form of a functional pseudo-class called :matches():
/* As this is a pseudo-class, you can make it a little DRYer by saying
div:matches(.ebook, .book) div.page instead */
:matches(div.ebook, div.book) div.page
If you really want to get technical, Firefox implements it as :-moz-any():
:-moz-any(div.ebook, div.book) div.page
and Chrome implements it as :-webkit-any():
:-webkit-any(div.ebook, div.book) div.page
(and these actually came first prior to the selector being specced as :matches())
But if you're using them in CSS you will have to duplicate your rulesets because of certain CSS parsing rules, which is as good as not using them at all (in fact, worse). These selectors are meant for internal use only, not for production.
What you currently have is the only viable option for now.
If you want to cheat a little, you could use a substring attribute selector, but that assumes each of those elements will have exactly one class only, and no other class names will match by this particular substring (this is similar to the div.?book example you have, but it comes with the limitations of an attribute selector that are not present in a class selector):
div[class$="book"] div.page
Personally, I'd just stick with the verbose option because it's more robust.
Check out this Fiddle that should do what you're looking for:
http://jsfiddle.net/Delorian/L44u0p8r/
div[class$="book"] {
background-color: yellow;
}
Further details: https://stackoverflow.com/a/9836182/3264286
There is no such thing as an OR selector in CSS, except for as in the example you gave, where a comma (,) can be used to separate multiple selectors e.g;
div.ebook div.page,
div.book div.page{
// CSS properties
}
I am trying to define styling for second sibling's child element based of first sibling's class.
Here is an example of what I am trying to achieve
<div >
<div class="one">
<div class="find edit">
Find me
</div>
</div>
<div class="two">
<div class="change">
Change me
</div>
</div>
</div>
In this example, I want "Change me" to be green if "edit" class is found. Is it possible to achieve this purely based on css?
Help much appreciated.
Thanks,
Medha
As far as I know, it's not possible to access the parent selector (I wish it was). If you could consider this structure, it'll be no problem at all:
HTML
<div>
<div class="one edit">
<div class="find">
Find me
</div>
</div>
<div class="two">
<div class="change">
Change me
</div>
</div>
</div>
CSS
.one.edit + .two .change { color: green; }
If not, you could easily accomplish what you're after with a little JavaScript.
Here You can find answer:
Complex CSS selector for parent of active child
Short answer copied from link:
Selectors are unable to ascend
CSS offers no way to select a parent or ancestor of element that
satisfies certain criteria. A more advanced selector scheme (such as
XPath) would enable more sophisticated stylesheets. However, the major
reasons for the CSS Working Group rejecting proposals for parent
selectors are related to browser performance and incremental rendering
issues.
Update:
Now I notice the edit class required in the child. You cannot.
simply you need something like a parent selector, and this doesn't exist in CSS 3, it's suggested in CSS 4 though, but that's far from happening any time soon.
More here:
CSS selector for "foo that contains bar"?
.
Original:
Depending on which browsers you care about, this may work:
div.one + div.two > div.change {
color: green;
}
Reference:
http://www.w3.org/TR/CSS21/selector.html#adjacent-selectors
Live Example:
http://jsfiddle.net/Meligy/NVjq6/
According to new article from css-tricks there is a big difference between how you select your elements because they are selected from right to left.
The article can be found here.
http://css-tricks.com/efficiently-rendering-css/
I am about to create a page that have different documents on the same page:
My question is, how should i go about the HTML for CSS efficiency or vise versa?
<div class="document-type-1">
<h1>Some heading</h1>
<p>Some paragraph</p>
</div>
<div class="document-type-2">
<h1>Some heading</h1>
<p>Some paragraph</p>
</div>
There can be multiple of the same document type, i can therefore not use an ID.
.document-type-1 h1 {
}
.document-type-1 p {
}
.document-type-2 h1 {
}
.document-type-2 p {
}
This will be "inefficient" since all p tags are found first...
How would you go about it if this should be done faster and you should be able to move the same article to a new document type?
As far as I can see, if I understand the article correctly, the most efficient way to do this - if you don't use a custom ID for each element - would be:
// YUCK!
<div class="document-type-1">
<h1 class="document-type-1-h1">Some heading</h1>
<p class="document-type-1-p">Some paragraph</p>
</div>
.document-type-1-h1 {
}
.document-type-1-p {
}
But this is disgusting. It is a dilemma that writing perfectly efficient CSS goes against all rules of writing good CSS.
Unless there are real, actual rendering speed problems caused by CSS rules, I would tend to obey some common-sense rules (e.g. not being wasteful with global selectors > * style, not using "overly qualified selectors" like form#UserLogin {...}, not using too many rules in general....), but otherwise focus on clean, well structured CSS. As the article itself states:
I think the lesson here is not to sacrifice semantics or maintainability for efficient CSS.
The Google Page Speed tips linked to by #gulbrandr in his answer give some good real-world advice.
Google's Page Speed recommendations explain how to write efficient CSS selectors: http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
There are many things to consider when optimizing your rendering page speed. CSS selectors and HTML markup are just a few to consider.
Here's how to do it based upon best practices outlined in the article you read and others.
1. Markup your content
Use basic html elements unless you need additional specificity.
<h1>Some heading</h1>
<p>Some paragraph</p>
<h1>Some heading</h1>
<p>Some paragraph</p>
<div class="module">
<h1 class="title">Some heading</h1>
<p>Some paragraph</p>
</div>
<div class="module featured-module">
<h1 class="title">Some heading</h1>
<p class="content">Some paragraph</p>
</div>
2. Base Element Styles
These selectors are fast because they do not have any ancestors which need to be matched. Ideally these work for most styling needs of the page.
h1 { font-size: 20px }
p { font-size: 14px }
.title { font-family: Georgia }
.module { color: orange }
It's important to learn about which properties are inherited by child elements of element being styled. For example, when the color property is defined for the .module class, the color will be used for all child elements (unless more specific rules exist).
3. Overriding Base Element Styles
If you have many <p> tags on a page and you only want to override the styles of a few, then give those few <p> tags a class and use a class to target styles to those few <p> tags.
.module .title { color: red }
.featured-module .title { color: blue }
Note: If the selector string matches the specificity and comes after the rule being overridden then it is applied without requiring any additional specificity.
Using a class allows you to reuse the styles on other elements in your html document. You can also use an ID as ancestor selector to conditionally apply styles, but then you lose the speed benefit of ID. ID's should be typically used as the only element in a sector string:
#login-module { color: tan }
If you have many <p> tags and you want to override half of them (or many different groups of them) you have to make a decision to either A. add classes to them, or B. sacrifice page speed (slightly?) and use descendent selectors:
.featured-module p { }
.category-module p { }
Do your own testing to determine if the decrease in page rendering time is significant enough to not use this solution. If it's not much (or imperceptible) then this solution may simplify your code and development time.
Summary
There are many ways to markup and style content. Choose the strategy that works best for your project's needs and adapt it as necessary based upon changes to your project. Using best practices is always wise, but knowing why they are a "best practice" is also important in order to know when you should break the rules.
Note: The speed of selectors for JavaScript is not the same as in CSS. Check out these tests: http://mootools.net/slickspeed/