How to write CSS selectors

Why this post?

Testers need to know multiple ways of locating an element in a webpage as different strategies have to be used based on the context since each has its own advantage. The Cascading Style Sheet(CSS) is defined to structure and style the HTML in the webpage. These CSS patterns can be used to uniquely identify elements in the webpage. This post will help you get started with CSS selectors. I have modeled this post to address the difficulties I faced learning CSS selectors online.


Setup

A couple of difficulties I faced while learning CSS is that most posts are pretty mundane and very abstract. I have made an effort to not do the same. Every example I have used in this post is derived from the Qxf2 tutorial page that will never change. That way you can practice writing CSS selectors to your heart’s content.

Install the CSS and XPath checker plugin for Chrome, open the tutorial page on a new tab and follow along.


Overview

This post has been structured in a way that it:
1. gets you started with the basic patterns
2. introduces you to positional pseudo-classes
3. tabulates a few useful patterns.

1)Basic patterns

Basic patterns include identifying elements by their tag, by their id, by their name attribute and their class. For example, let us try deriving CSS selectors for the Phone No text field in the tutorial page.

To view the html properties of the Phone No field, right click on it and select inspect.

Phone_html
To select the Phone No textfield,
Phone_Css_id_2
or
Phone_Css_id
Phone_no
Although #phone can be used to locate the text field,there can be other CSS locators too for the Phone No text field.You can practice the remaining basic patterns (HTML tag, id, class) by referring to the table below.

Selector Example Example Description
element input This pattern selects all input elements in the web page.
.class div.checkbox (or) .checkbox This pattern selects the element with the class .checkbox
[attribute=’value’] input[type=’phone’] (or) [type=’phone’] This pattern selects the input element whose type attribute value is phone.

Consider the following HTML property for the Example Table,
Example_Table
The CSS selector for the above table can be [name='Example Table'] or to specify that the value starts with a particular word [name^='Example'] or [name$='Table'] if the value ends with word Table. [name*='Example] or [name*='Table'] can be used to specify that the value of the attribute contains the particular word.
name_cont_css


2)Pseudo-class

Sometimes you are lucky and every element in your application has a name or an id or a unique class. However, when you start dealing with tables and dynamic data, it is good to know about Pseudo-classes. Pseudo-classes are used to locate an element based on their state/position. Pseudo-classes are preceded by ‘:’. Let us try writing selectors for the buttons in the example form with pseudo-classes.
Let us try deriving a CSS selector for the Click me! button using a pseudo-class. The HTML snippet for the Click me! button is,
click_me_button
The CSS selector using pseudo-class is,
Click_me_CSS
click_me_example_form
Now the HTML snippet for Gender button is,
gender_button
The CSS selector for the Gender button can be,
first_child_css
Do you notice 2 matches instead of one? Wondering why?? The Click me! button despite being the only child is also taken into consideration for the first-child pseudo class. Hence the pseudo-class has to be used in combination with any other basic patterns. Therefore the CSS selector for the gender button is,
Gender_CSS
Gender_example_form
It is not possible to discuss all the Pseudo-classes(for more pseudo classes click here.) but anyone who wants to learn CSS should start by knowing the difference between the most commonly used position based pseudo-classes – nth-child and nth-of-type classes. Let us try and learn the difference with the following example,
Consider the HTML properties of the Example Form in the tutorial page:

	    <div class="form-group">
	      <label for="name">Name:</label>
	      <input type="name" class="form-control" name="name" id="name" >
	    </div>
	    <div class="form-group">
	      <label for="email">Email:</label>
	      <input type="email" class="form-control" name="email">
	    </div>
	    <div class="form-group">
	      <label for="pwd">Phone No:</label>
	      <input type="phone" class="form-control" name="phone" id="phone">
	    </div>

The CSS selector to select the email text field would be div.form-group:nth-child(2). The nth-child pseudo-class here would select any element that is a div and is the second child. The CSS selector for the above element can also be

div.form-group:nth-of-type(2)

The nth-of-type pseudo-class selects any element that is second of the type
Imagine if developer decides to have a gender button next to the name field, the HTML properties after the new change would look like this,

	    <div class="form-group">
	      <label for="name">Name:</label>
	      <input type="name" class="form-control" name="name" id="name" >
	    </div>
	    <span class="form-group">
	      <button class="btn btn-primary dropdown-toggle status" type="button" data-toggle="dropdown">Gender
	      </button>
            </span>
	    <div class="form-group">
	      <label for="email">Email:</label>
	      <input type="email" class="form-control" name="email">
	    </div>
	    <div class="form-group">
	      <label for="pwd">Phone No:</label>
	      <input type="phone" class="form-control" name="phone" id="phone">
	    </div>

Now,

div.form-group:nth-child(2)

Would not identify any element as the div element is no longer the second child. Whereas,

div.form-group:nth-of-type(2)

Would select the email text field as the second div element corresponds to the email text field


3)Other important patterns:

Sometimes the you need to identify elements relative to another well identified element. This section will show you how. Generally these patterns are used in combination with pseudo-classes(except :not which is already a pseudo-class).
Consider the following HTML snippet,
axes_example
To select the child of any element,
child
And to select the grandchild of any element,
grandchild
The element>child pattern is used to select the child of that element. In order to select the child and grandchild of any element element grandchild pattern can be used. The reason why you see 4 matches is because there are 4 th elements in the Example Table.
Try out the other useful patterns in the following table,

Selector Example Example Description
element+element label+input This pattern is used to select the input element that is immediately next to the label element
element~element label~input This pattern is used to select the input that is after the label element. Unlike the previous example the input element doesn’t necessarily have to be next to label
element,element input#name,input#random This pattern selects both elements or any element that is present
not :not(input) This pattern selects every element that is not an input element

References

1. Flukeout-CSS diner game :flukeout CSS Diner
2. Chris Coyier’s piece on pseudo-class: https://css-tricks.com/pseudo-class-selectors/
3. How to use CSS selectors for identifying webelements post on softwaretestinghelp.com: http://www.softwaretestinghelp.com/css-selector-selenium-locator-selenium-tutorial-6/
4. w3schools.com: http://www.w3schools.com/cssref/css_selectors.asp


A fun practice exercise!

Someone gamified learning to write CSS selectors and we love it!! Checkout flukeout CSS Diner. I know we mentioned this a couple of times, but it is worth repeating again!

If you liked this article, learn more about Qxf2’s testing services for startups.


One thought on “%1$s”

Leave a Reply

Your email address will not be published. Required fields are marked *