Understanding CSS: Precedence & Specificity

Have you faced a situation where you are trying to apply the CSS style to an element, but it does not apply? It seems the webpage is ignoring your code. This could be caused by conflicts in the cascade order.

Things will discuss here:

  1. Origins of Stylesheets
  2. Specificity
  3. Importance
  4. Cascade Order

Origins of stylesheets:

  1. Author stylesheet (Styles set by the web developers)
  2. User stylesheet (Custom styles set by a user – Browsers give you the option of extending the browser’s default style sheet)
  3. Browser stylesheet / User-agent style sheet (Browser defaults – if the author of a web page didn’t apply any styling, the styling details present in the default stylesheet installed within the browser is applied)

Specificity:

        An HTML element can be targeted by multiple CSS rules. If there are two or more conflicting CSS rules, the browser will apply the rule which is more specifically mentioned. Specificity will only apply when one element has multiple declarations to it. To understand in a better way, the specificity is expressed in the form (a, b, c, d). Lets see in detail,

Specificity Hierarchy (High to Low):

  • Inline style

o   ‘style’ attribute rather than a rule with a selector

o   The position ‘a’ – (a, b, c, d) – (1, 0, 0, 0)

  • ID Selectors

o   Eg. The element with id attribute, id=’example’(#example)

o   The position ‘b’ – (a, b, c, d) – (0, 1, 0, 0)

  • Class Selectors(.example), Attribute selectors([type=radio]) and pseudo-classes(:hover)

o   The position ‘c’ – (a, b, c, d) – (0, 0, 1, 0)

  • Type Selectors(h1) and pseudo-elements (::after)

o   The position ‘d’ – (a, b, c, d) – (0,0,0,1)

Example:

Selectors Specificity
*{ } 0,0,0,0
li{ } 0,0,0,1
li:first-line { }   0,0,0,2
ul li{ }   0,0,0,2
ul ol+li{ } 0,0,0,3
h1 + *[rel=up]{ } 0,0,1,1
ul ol li.red  { } 0,0,1,3
li.red.level  { } 0,0,2,1
#exampleId{ } 0,1,0,0
style=”” 1,0,0,0

No Specificity:

  1. The universal selector (*,+, -,>, ~) has no specificity value.
  2. The pseudo-class :not() adds no specificity. The negation ‘ pseudo-class: not’ is not considered a pseudo-class in the specificity calculation. It counts as normal selectors

Origin Hierarchy:

Below is the priority order from highest to lowest for normal styles when there is equal specificity for the declarations. If it was an important style (! important), it is just the reverse.

  1. Author style sheet
  2. User style sheet
  3. User-agent (browser) stylesheet

Importance:

  1. Normal declaration (p {color: red} )
  2. Important declaration (p {color: red !important} )

!important

The !important value appended in a declaration along with the property value in any of the ruleset/rules will be taken as the most priority even if the rule has less specificity.

Override !important:

Either add Specificity to the declaration or have only one !important declaration, remove others.

Cascade Order:

        The cascading order depends on origin, specificity, importance and source order. Below is the precedence order from low to high,

  1. Declarations in user agent style sheets (e.g. the browser’s default styles, used when no other styling is set).
  2. Normal declarations in user style sheets (custom styles set by a user).
  3. Normal declarations in author style sheets (these are the styles set by the web developers).
  4. Important declarations in author style sheets
  5. Important declarations in user style sheets

Note:

  • Declaration with Same Importance and Same-Origin: More specific selectors will override more general ones
  • Source Order – Declaration with the Same Importance, Same Specificity, and Same-Origin: the later rule takes precedence

Best Practices:

  • Use Class selectors instead of ID selectors.
  • Avoid using multiple CSS rules that target the same HTML elements.
  • Do not use inline styles.
  • Use specificity before even considering !important .
  • Although ‘!important’ works, it is generally bad practice. It can make debugging a difficult process
  • Only use !important on page-specific CSS that overrides foreign CSS (from external libraries, like Bootstrap or normalize.css).

Reference:

1) https://www.w3.org/TR/2011/REC-CSS2-20110607/cascade.html#cascade
2) https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
3) https://css-tricks.com/precedence-css-order-css-matters/
4) https://vanseodesign.com/css/css-specificity-inheritance-cascaade/
5) https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance
6) http://tutorials.jenkov.com/css/precedence.html

Learn RxJS in 1 Blog…(Disclaimer: Javascript basics are highly recommended)

RxJS (stands for Reactive Javascript) is actually a well-known library that is used to handle asynchronous calls with multiple events. There are plenty of other reactive libraries written in other platforms. Some of them are RxJava, Rx.NET, UniRx, RxScala, RxClosure, RxCpp, RxPY, RxDart, RxNetty, RxAndroid, RxCocoa etc.

Sample RxJS Implementation:

const interval = new Observable(observer => {

 let count = 0;

 const interval = setInterval(() => {

   observer.next(count++);

 }, 1000);

 // once we stop listening to values clear the interval

 return () => {

   clearInterval(interval);

 }

});

interval.subscribe(value => console.log(value));

// —-1—-2—-3—->

The functional units of RxJs are,

Observable:

Observables are collections of a stream of values or events. It can hold either synchronous or asynchronous stream of values or events.

Observer:

After fetching the necessary values from observables, callbacks are implemented to perform the required actions based upon the values. These set of collections of callbacks are called observers.

Subscription:

Subscription is the way to return the value when the asynchronous function is completed.

Operators:

RxJs Operators can be considered as Lodash for events. It provides the ease of RxJS implementations through enabling functional programming.

Subject:

A subject is simply a unit that can act as both Observable and Observer simultaneously.

Schedulers:

Schedulers help us to define in what execution way does an observable deliver its values to the observer.

Basically, the RxJs Observables can be compared with Promises in a better way as they have the major similarities.

Reference Links:

A dive into “Vuex” !

Let’s meet our hero – “The Vuex”!

Vuex is a state management library that is used commonly in vue.js. But why do we use it? Vuex is very much useful in passing the data from one component to another component.

We can pass data from the parent component to child component using props, but when the child component has many nested siblings, the data passing between the child components becomes difficult and that’s where “Vuex” comes into play !!

Store :

A store is a global object that keeps track of all the state changes of the app across the components.

But what makes it different from other objects?

  • Vuex stores are reactive – every state changes are updated efficiently in the store
  • Vuex stores are read-only – It is not possible to change the state properties directly in the store. The only way to change a store’s state is by explicitly committing mutations.

We can create a store by creating an instance of vuex like :

const store = new Vuex.Store({ state: {} })

In order to integrate vuex with vue, we have to add the store in the vue instance by :

const App = new Vue({ store })

In order to keep track of the state changes, we have to access the state in the “computed” property in vue component

Now we have created a store, but how do we access the store data?

We access the store by the following methods :

  • Mutations
  • Getters
  • Actions

Mutations :

These are functions used to update the state. They behave like events and we have to use “commit” in order to invoke them.

To be clear, we define the mutation by :

const store = new Vuex.Store({

mutations: {

  yourMutationFunction (state, payload) => {

     }

   }

});

We invoke the above mutation by:

this.$store.commit(MUTATION_NAME, {payloadData});

Getters :

Applicable to a scenario where we have to get a value from the store that is obtained by manipulating the state data, then we use “Getters”. Having these manipulations in the store makes the “Getters” reusable in other components as well.

Getter functions are created by :

const store = new Vuex.Store({getters: { yourGetterFunction : (state) => ( ) } });

And we invoke the getters by,

this.$store.getters.yourGetterFunction

We also have a helper method called “mapGetters” to invoke a getter function in the component.

Example :

import { mapGetters } from ‘vuex’

export default {
 // some code ..
 computed: {
   …mapGetters([   // we use spread operator to append the mapGetters to the computed object
    ‘yourGetter’
   ])
 }
}

But when we have no manipulation in the state, we have to use mapState helper to fetch the data in the store directly from the store.

computed: {

  …mapState([‘yourStateName’]);

}

Actions :

They are generally functions, that is invoked to perform some backend calls or any other asynchronous operations before mutations. Actions keep track of the mutation changes correctly in case of asynchronous operations.

actions: {
 yourActionMethod({ commit }) {
   commit(‘mutationMethod’)
 }
}

Actions are invoked by dispatching them using store object or mapActions helper function

Example :

   this.$store.dispatch(‘actionName’)

Or in components by :

methods: {
   …mapActions([‘actionName’])

}

Thus, the flow for the state from component to store will be like :

Sources :