Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS selector best practice [closed]

I'm wasting time on the little things again. The question I'm asking myself - and now YOU - is: what is the "best way" to do CSS selectors/HTML markup?

Do I avoid classes at all cost, leaving the HTML pure and beautiful, or do I add classes whereever I want to style something?

Example, if I want to style the various form buttons of my website, do I go

input[type="submit"] { /* styles */ }

or do I add a class "form-button" to all of them and do

.form-button { /*styles */ }

In this trivial example, one might not think too much of it, but if I want to style the third link out of a - semantic, not presentational - list differently, I could make it

.navigation ul:nth-of-type(2) a:nth-of-type(3) { /* styles */ }

versus just giving that one link a class of "different-link" and use

.different-link { /* styles */ }

I understand that in 2013, all computing devices and the browsers they run should be quick enough that the technically suboptimal CSS selectors should not make any kind of difference to the end user.

So in the end, it really seems to be a question of 'Do I clutter the HTML (with classes) or do I clutter the CSS (with long-winded selectors)?'

Any opinions on that?

like image 400
Marcos Avatar asked Oct 12 '13 20:10

Marcos


People also ask

Which is the correct order of specificity for CSS rules selectors?

Specificity Hierarchy :Every element selector has a position in the Hierarchy. Inline style: Inline style has highest priority. Identifiers(ID): ID have the second highest priority. Classes, pseudo-classes and attributes: Classes, pseudo-classes and attributes are come next.

Which selector is faster ID or class?

ID's used correctly are faster, but with such a minimal difference vs classes - it's not worth any consideration.

Which CSS selector has the highest priority?

Values defined as Important will have the highest priority. Inline CSS has a higher priority than embedded and external CSS. So the final order is: Value defined as Important > Inline >id nesting > id > class nesting > class > tag nesting > tag.

How do I know if a CSS selector is correct?

You can use a library to verify if the selector is valid, and probably get more details from parsing. Check the css selector parser. There's already a library, it's the CSS selector parser built into the browser. That "library" reports errors by throwing.


2 Answers

Separation of concerns between HTML and CSS

Even though externalised from HTML CSS should be considered separate it's actually not in cases where you insert HTML element-specific selectors. In your case where your selectors relate to actual HTML elements and their hierarchy makes your CSS closely bound to your HTML source. This makes your CSS inflexible and likely larger than it should be.

Hence CSS classes. Whenever you use classes those definitions can be attached to any HTML element as long as they define enough properties. It is true though that your HTML becomes larger due to additional attributes, but semantics doesn't change.

Why is .form-button better than input[type=submit] then?

Because you may change your <input type=submit /> to <button type=submit> that is a container and gives much more design freedom to UI designers. If you used CSS classes then you likely wouldn't change too much about its properties, but if you used tag names, you'd have to overhaul your CSS file and amend it.

Another example would be with other types of inputs i.e. Cancel button. In case it was visually identical to submit button, designers may say that Submit is primary action, and Cancel is secondary so it should be displayed as a mere link. Using classes would result in less maintenance again.

Why classes-only CSS isn't magic bullet either?

Some elements may have specific CSS properties that others don't. Take for example (un)ordered lists. In such cases it does make sense to write tag-based selectors to define CSS style that applies to particular HTML elements. But to avoid selecting all elements of the same type on your page it's suggested to define CSS selector as a combination of tag-based and class-based selector. This makes a so to say CSS class selector constraint which makes sense in such cases.

Be advised to separate common style properties with class based selector only and add specific styles to tag+class based selector with constraint as (LESS/SCSS syntax):

/* generic */
.navigation {
    background-color: #999;
    margin: 0;

    .item {
        display: inline-block;
        padding: 10px;
    }
}

/* specific to UL */
ul.navigation {
    list-style: none;
}

This gives you the most freedom and improves maintainability to the max.

Conclusion: Class based selectors are preferred hint: OOCSS

Yes. Most of the time. This way you'll be able to write object-oriented CSS (article on SmashingMag, GitHub repo) with less code duplication and exceptions. It will improve your CSS maintainability.

Important note: As with any code you shouldn't over-engineer your CSS either. I've showed you how you can provide flexible style definitions, but you shouldn't always follow these rules. You should provide just enough flexibility at the beginning and refactor as needed while you go. But keep yourself on the classes side most of the time.

like image 66
Robert Koritnik Avatar answered Sep 17 '22 02:09

Robert Koritnik


I generally think about coupling.

If you style only using tag names and complex selectors you are tightly coupling you CSS with you HTML. So that if you change just a tiny bit of the markup you'll certainly end up changing also the CSS. This might be okay for simpler sites, where you have just one or two pages.

For "complex" sites using classes is in my opinion mandatory. Using classes you can decouple the CSS from the HTML. What I mean is that if you add classes to the main elements of a "thing" (which then becomes a module) you are free to alter the markup, as long as you keep the same classes (obviously, if you change a lot the markup you might need to change a lot also the CSS. For simpler changes like wrapping an element in a div or changing an h1 to an h2 you won't need to change the CSS).

Also, you CSS becomes easier to read, because when you read this:

.blog-posts > .blog-post > .blog-post-title

You know you're talking about the style of a title of a blog post, which is way better than

div > div > h1

(or any other similarly anonymous selector).

So if you style smartly with classes, you end up creating modules, which can have simpler selectors, because you don't need to target elements from the HTML root element, but from the module root element:

.blog-post-title {}
.blog-post-subtitle {}
.blog-post-body {}
.blog-post-tags {}

and so on.

SMACSS is in my opinion a great way to organise the stylesheets, I suggest you to read about that. As I wrote before, if you are developing a "simple" site, you don't need all this fuss. But for complex sites, having reusable modules is a big plus.

like image 20
Alessandro Vendruscolo Avatar answered Sep 18 '22 02:09

Alessandro Vendruscolo