Keep HTML and CSS Markup Flexible with CSS Selectors

With CSS, we can completely transform the look of a website without changing its source code and markup. The key of that process is CSS selectors. But despite this, CSS selectors are one of the more neglected parts of the specification and CSS selectors are still not used to their full potential. You may sometimes spend too much time trying to solve a problem that you could more easily solve by using CSS selectors.
Today, I’m listing the list of CSS Selectors you Must Memorize if your want to keep your code (include HTML markup) and your style sheets flexible.
Note: I am not going to explain the basics of how CSS selectors in general work here.

The CSS Selectors

Selectors are one of the most important aspects of CSS as they are used to “select” elements on an HTML page so that they can be styled. There are several different types of selectors:

  • type selectors—matching a specific element
  • class selectors—matching elements with a specific class
  • ID selectors—matching the element with a specific ID
  • descendant selectors—matching elements that are descendants of a specific element
  • child selectors—matching elements that are a child of the specific element
  • universal selectors—matching any element
  • adjacent sibling selectors—matching elements immediately preceded by a specific element
  • attribute selectors—matching elements with a specific attribute or attribute value
  • pseudo-class selectors—matching elements with a specific pseudo class

Type/Class/ID/Descendant selectors

Type/Class/ID/Descendant selectors are most common and easy to understand which was used by everyone. It’s easy to learn and unforgettable. I’ll not talking about it too much.

Child > Selector

The difference between A child selector and Descendant selectors is used to select an element that is a direct child of another element (parent). It only focus direct on children, not select all descendants.

Universal selectors

Universal selectors are used to select any element. Many developers will use this trick to zero out the margins and padding. The universal selector can be used to represent any element at all, and is specified using an asterisk or star symbol *.
Note: The * can also be used with child selectors.

Adjacent sibling + selectors

A selector that uses the adjacent sibling combinator uses the plus symbol (+), and is almost the same as the general sibling selector. Adjacent sibling selectors will select the sibling immediately following an element, not just a general sibling. These selectors can help you apply styling in a contextual way.

Attribute selectors

Attribute selectors select an element using the presence of a given attribute or attribute value.

There are 6 different types of attribute selectors:

  • [att=value]: The attribute has to have the exact value specified.
  • [att~=value]: The attribute’s value needs to be a whitespace separated list of words (for example, class=”title featured home”), and one of the words is exactly the specified value.
  • [att|=value]: The attribute’s value is exactly “value” or starts with the word “value” and is immediately followed by “-”, so it would be “value-”.
  • [att^=value]: The attribute’s value starts with the specified value.
  • [att$=value]: The attribute’s value ends with the specified value.
  • [att*=value]: The attribute’s value contains the specified value.

For example, if you want to change the background color of all the URL, all text color of spans, … we can use CSS Attribute selectors:

CSS Attribute selectors Tips

To start, we take a look on HTML5 markup:

<h2 id="title" class="magic" rel="blog">NARGA</h2>

This single element has three attributes: ID, class, and rel. Did you know you can select it based on that rel attribute as well? That is what is known as an attribute selector:

h2[rel="blog"] {
   color: green;

Note: The value specified in an attribute selector is case sensitive if the attribute value in the markup language is case sensitive. Thus, values for id and class attributes in HTML are case sensitive, while values for lang and type attributes are not.

CSS Attribute selectors is very useful. You can styling specified URL, text with attributed, add icon beside URL that’s targeting to file format … With just a little bit of code, you can achieve remarkably specific targeting with little to no additional markup required.

CSS Pseudo-classes / Pseudo-elements

A CSS pseudo-class / pseudo-elements is a keyword added to selectors that specifies a special state of the element to be selected and allow you to style information that is not available in the document tree.

They include:

  • :active
  • :checked
  • :default
  • :dir()
  • :disabled
  • :empty
  • :enabled
  • :first
  • :first-child
  • :first-of-type
  • :fullscreen
  • :focus
  • :hover
  • :indeterminate
  • :in-range
  • :invalid
  • :lang()
  • :last-child
  • :last-of-type
  • :left
  • :link
  • :not()
  • :nth-child()
  • :nth-last-child()
  • :nth-last-of-type()
  • :nth-of-type()
  • :only-child
  • :only-of-type
  • :optional
  • :out-of-range
  • :read-only
  • :read-write
  • :required
  • :right
  • :root
  • :scope
  • :target
  • :valid
  • :visited

Sixteen new pseudo-classes above which have been introduced as part of the W3C’s CSS Proposed Recommendation, and they are broken down into four groups: structural pseudo-classes, pseudo-classes for the states of UI elements, a target pseudo-class and a negation pseudo-class.

CSS Pseudo-classes syntax

selector:pseudo-class {
  property: value;

Structural Pseudo-Classes

Selectors introduces the concept of structural pseudo-classes to permit selection based on extra information that lies in the document tree but cannot be represented by other simple selectors or combinators. What this means is that we have selectors that have been turbo-charged to dynamically select content based on its position in the document. Let’s start with pseudo-classes by examples.


The :root pseudo-class represents an element that is the root of the document.

:root { background-color: green; }

In HTML 4, this is always the HTML element.

html { background-color: green; }

:nth-child(n) and :nth-last-child(n)

The :nth-child(n) and :nth-last-child(n) pseudo-class targets a child element in relation to its position within the parent element or counting from the last item in the selection.
In the following example, we have six paragraphs inside a <div> and we’re styling the second and fifth paragraph.

Please note that :nth-child accepts an integer as a parameter, however, this is not zero-based. If you use :nth-child(1) we get new pseudo-class called as :first-child and similar with :nth-last-child(1) is :last-child

:nth-of-type(n) and :nth-last-of-type(n)

The :nth-of-type(n) / :nth-last-of-type(n) pseudo-class notation represents an element that has n-1 siblings with the same expanded element name before / after it in the document tree, for any zero or positive integer value of n, and has a parent element.
There will be times when, rather than selecting a child, you instead need to select according to the type of element.

Same as :first-child and :last-child, we got :first-of-type and :last-of-type.

  • The :first-of-type (:nth-of-type(1)) pseudo-class represents an element that is the first sibling of its type in the list of children of its parent element.
  • The :last-of-type (:nth-last-of-type(1)) pseudo-class represents an element that is the last sibling of its type in the list of children of its parent element.

:only-child / :only-of-type pseudo-classes

Represents an element that has a parent element and whose parent element has no other element children. Same as :first-child, :last-child or :first-of-type, :last-of-type, but with a lower specificity.

:empty pseudo-class

The :empty pseudo-class represents an element that has no children at all. In other words, this element has no content or child element, it has nothing, not even a space.


the CSS code:

The UI element states pseudo-classes

The UI element states pseudo-classes are used to select UI elements (form controls such as radio buttons or check boxes) that are in a certain state: enabled, disabled or checked (selected).

:enabled and :disabled

:disabled is used to target elements that do not accept data input and, contrastly :enabled is used to target elements that accept data input. In a typical document most elements will be neither :enabled nor :disabled.
This is a great way to give feedback on what users can and cannot fill in. You’ll often see this dynamic feature enhanced with JavaScript.


While the :checked pseudo-class is dynamic in nature, and can altered by user action, since it can also be based on the presence of semantic attributes in the document, it applies to all media. Again, this is very useful for giving feedback on what users have selected.

Negation Pseudo-Class

The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. This pseudo-class matches elements that aren’t matched by the specified selector.
For example, the selector, input:not([type="submit"]), matches all input elements, except input elements with a type value of "submit" — that is, HTML submit buttons.
Negations may not be nested; :not(:not(...)) is invalid. Note also that since pseudo-elements are not simple selectors, they are not a valid argument to :not().
Default namespace declarations do not affect the argument of the negation pseudo-class unless the argument is a universal selector or a type selector.
Note: the :not() pseudo allows useless selectors to be written. For instance :not(*|*), which represents no element at all, or foo:not(bar), which is equivalent to foo but with a higher specificity.

Dynamic pseudo-classes

Dynamic pseudo-classes classify elements on characteristics other than their name, attributes, or content, in principle characteristics that cannot be deduced from the document tree.
They are:

  • The link pseudo-classes: :link and :visited
  • The user action pseudo-classes :hover, :active, and :focus
  • The target pseudo-class :target

The link and user action pseudo-classes are very easy to understand and use. We’re talking with target and language pseudo-classes.


Some URIs refer to a location within a resource. This kind of URI ends with a number sign # followed by an anchor identifier (called the fragment identifier). If the URL has an identifier (that follows an #), then the :target pseudo-class will style the element that shares the ID with the identifier.

The section with the id summary can now be styled and place an image before it like so:

*:target { background-color: #fcc; }
*:target::before { content : url(target.png) }

::first-line and ::first-letter

The ::first-line / ::first-letter pseudo-elements describes the contents of the first formatted line / first character of an element. The ::first-letter pseudo-element may be used for “initial caps” and “drop caps“, which are common typographical effects, it also applies if the first letter is in fact a digit.

The ::before and ::after pseudo-elements

The ::before and ::after pseudo-elements can be used to describe generated content before or after an element’s content.


Always try to use these native CSS3 selectors over the library’s custom methods/selectors, when possible. It’ll make your code and stylesheets faster, more flexible as the selector engine can use the browser’s native parsing, rather than its own.
If you’re compensating for older browsers, or Internet Explorer, you still need to be careful when using these newer selectors and be sure to refer here for a browser-compatibility list.
And for the last word, we hope that this would be a good reference for you to work with pseudo-classes.