192

I'm trying to figure out why one of my css classes seems to override the other (and not the other way around)

Here I have two css classes

.smallbox { 
    background-color: white;
    height: 75px;
    width: 150px;
    font-size:20px;
    box-shadow: 0 0 10px #ccc;
    font-family: inherit;
}

.smallbox-paysummary {
    @extend .smallbox; 
    font-size:10px;
}

and in my view I call

<pre class = "span12 pre-scrollable smallbox-paysummary smallbox "> 

The font (The overlapping element) shows up as 10px instead of 20 - could someone explain why this is the case?

falsarella
  • 12,217
  • 9
  • 69
  • 115
Stephen
  • 2,360
  • 2
  • 18
  • 23
  • 2
    Are you using a CSS pre-processor? I see you have that `@extend .smallbox;`, which looks like non-standard cSS. – Jared Farrish Aug 03 '14 at 14:41
  • You really shouldn't combine `@extend` - if it does what I think it does - and using both selectors on the same element. – millimoose Feb 13 '16 at 19:18
  • [SMACSS seems to recommend](https://smacss.com/book/type-module#subclassing) to only include the changed properties in a "subclass" (i.e. `.smallbox-paysummary`), and optionally make the CSS declaration more clearly specific (without relying on the order of appearance in the CSS file) by using `.smallbox.smallbox-paysummary { font-size: 10px; }` – millimoose Feb 13 '16 at 19:22
  • 1
    And if you do NOT want the `.smallbox-paysummary` to have a smaller font, why are you making it smaller in the first place? – millimoose Feb 13 '16 at 19:22
  • Now I'm wondering why if both rules have the same specificity the one declared later on the *element's class attribute* doesn't take precedence, regardless of the order of the CSS rules. – Andy May 06 '17 at 04:54
  • Something similar [here](http://stackoverflow.com/q/9459062/465053). – RBT May 09 '17 at 22:41

9 Answers9

298

There are several rules ( applied in this order ) :

  1. inline css ( html style attribute ) overrides css rules in style tag and css file
  2. a more specific selector takes precedence over a less specific one
  3. rules that appear later in the code override earlier rules if both have the same specificity.
  4. A css rule with !important always takes precedence.

In your case its rule 3 that applies.

Specificity for single selectors from highest to lowest:

  • ids (example: #main selects <div id="main">)
  • classes (ex.: .myclass), attribute selectors (ex.: [href=^https:]) and pseudo-classes (ex.: :hover)
  • elements (ex.: div) and pseudo-elements (ex.: ::before)

To compare the specificity of two combined selectors, compare the number of occurences of single selectors of each of the specificity groups above.

Example: compare #nav ul li a:hover to #nav ul li.active a::after

  • count the number of id selectors: there is one for each (#nav)
  • count the number of class selectors: there is one for each (:hover and .active)
  • count the number of element selectors: there are 3 (ul li a) for the first and 4 for the second (ul li a ::after), thus the second combined selector is more specific.

A good article about css selector specificity.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Lorenz Meyer
  • 19,166
  • 22
  • 75
  • 121
73

Here's a compilation of CSS styling order in a diagram, on which CSS rules has higher priority and take precedence over the rest: CSS styling order

Disclaimer: My team and I worked this piece out together with a blog post (https://vecta.io/blog/definitive-guide-to-css-styling-order) which I think will come in handy to all front-end developers.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Qin
  • 881
  • 7
  • 10
  • 11
    That diagram needs a special mindset. For me it is way more difficult to understand that diagram than style inheritance itself. – Lorenz Meyer Dec 16 '19 at 07:30
  • 2
    What does "left to right" and "top to bottom" ordering mean? Actually, later rules take precedence over earlier rules with the same specificity. So shouldn't it be bottom (highest) to top (lowest), since bottom takes precedence over top? – AlexPi Feb 07 '22 at 01:02
  • Why there are 2 "inline" items (inline attribute & inline style) in the graph? What do they refer to? What are the differences? – Grace Nov 11 '22 at 04:30
32

What we are looking at here is called specificity as stated by Mozilla:

Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied. Specificity is based on the matching rules which are composed of different sorts of CSS selectors.

Specificity is a weight that is applied to a given CSS declaration, determined by the number of each selector type in the matching selector. When multiple declarations have equal specificity, the last declaration found in the CSS is applied to the element. Specificity only applies when the same element is targeted by multiple declarations. As per CSS rules, directly targeted elements will always take precedence over rules which an element inherits from its ancestor.

I like the 0-0-0 explanation at https://specifishity.com:

enter image description here

Quite descriptive the picture of the !important directive! But sometimes it's the only way to override the inline style attribute. So it's a best practice trying to avoid both.

AMS777
  • 4,609
  • 1
  • 18
  • 21
11

The order in which the classes appear in the html element does not matter, what counts is the order in which the blocks appear in the style sheet.

In your case .smallbox-paysummary is defined after .smallbox hence the 10px precedence.

LifeQuery
  • 3,202
  • 1
  • 26
  • 35
8

First of all, based on your @extend directive, it seems you're not using pure CSS, but a preprocessor such as SASS os Stylus.

Now, when we talk about "order of precedence" in CSS, there is a general rule involved: whatever rules set after other rules (in a top-down fashion) are applied. In your case, just by specifying .smallbox after .smallbox-paysummary you would be able to change the precedence of your rules.

However, if you wanna go a bit further, I suggest this reading: CSS cascade W3C specification. You will find that the precedence of a rule is based on:

  1. The current media type;
  2. Importance;
  3. Origin;
  4. Specificity of the selector, and finally our well-known rule:
  5. Which one is latter specified.
Renato
  • 993
  • 13
  • 23
7

Also important to note is that when you have two styles on an HTML element with equal precedence, the browser will give precedence to the styles that were written to the DOM last ... so if in the DOM:

<html>
<head>
<style>.container-ext { width: 100%; }</style>
<style>.container { width: 50px; }</style>
</head>
<body>
<div class="container container-ext">Hello World</div>
</body>

...the width of the div will be 50px

P. Avery
  • 779
  • 1
  • 16
  • 34
  • 2
    This is not really precedence, this is the Cascading part of Cascading Style Sheets. – TylerH Oct 15 '19 at 18:29
  • @TylerH, technically true, but I believe this answer has a place here because people arriving at this question might be conflating the difference. – Sablefoste Dec 21 '22 at 13:05
5

AS is state in W3: W3 Cascade CSS

the orden that different style sheet are applied is the following (quote from W3 cascading section):

  1. user agent declarations

  2. user normal declarations

  3. author normal declarations

  4. author important declarations

  5. user important declarations

More information about this in the referred W3 document

freedeveloper
  • 3,670
  • 34
  • 39
4
Element, Pseudo Element: d = 1 – (0,0,0,1)
Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
Id: b = 1 – (0,1,0,0)
Inline Style: a = 1 – (1,0,0,0)

Inline css ( html style attribute ) overrides css rules in style tag and css file

A more specific selector takes precedence over a less specific one.

Rules that appear later in the code override earlier rules if both have the same specificity.

Siguza
  • 21,155
  • 6
  • 52
  • 89
  • Here's a good explanation: http://vanseodesign.com/css/css-specificity-inheritance-cascaade/ – akostadinov Aug 11 '16 at 17:02
  • 1
    @Mahi I waved your suggested edit through this time, but in the future, please do not add garbage to an edit just to make it long enough. Having a second edit that "undoes" the damage of a first one is very bad practice, very unintuitive to reviewers, and creates more work than necessary. Instead, just look for other things that could be improved (such as spelling or grammar). – Siguza Feb 02 '17 at 19:33
1

In a simple and short way, one should keep in mind the two things below:

  1. Inline CSS has a higher priority than embedded and external CSS.
  2. So final Order is: Value defined as Important > Inline > id nesting > id > class nesting > class > tag nesting > tag
pizzaisdavid
  • 455
  • 3
  • 13
Safin Ghoghabori
  • 516
  • 1
  • 6
  • 17