How to Use CSS Selector for Identifying Web Elements

CSS Selector In Selenium WebDriver: As an automation test engineer, you know the importance of the Locators in the Selenium WebDriver testing tool. In our previous post, we discussed locating an element using ID, Name, Class Name, Tag Name, Link Text, and Partial Link Text. Those are very common attributes. By using those, you can easily identify a static element. Still, for handling or locating dynamic elements of a webpage, you can use two powerful location strategies: XPath and CSS Selector.

For a better understanding of XPath in detail, we have tried to cover all possible scenarios in a separate post, and you can check that by following this link. But in this post, we will detail how to locate an element using the CSS Selector with real-time examples.

What is CSS?

The full form of CSS is Cascading Style Sheets, a simple design language mainly developed to make the webpage presentable because CSS handles the looks and feels part of a web page.

Difference Between CSS Selector VS XPath

Xpath and CSS selectors are the most used location strategies to locate the element on the webpage. However, there is strong competition in the discussion about which is more powerful, XPath or CSS Selector. However, those who favor the CSS selector mention that it is more acceptable for the following reasons.

  • CSS is more readable (Simpler)
  • CSS is faster (Especially IN IE)

Some mention that using XPath can traverse all webpage elements, whereas, with CSS Selectors, you can traverse only down to the DOM.

But in our view, it is better to master both CSS selector and XPath.

CSS Selectors in Selenium

Let us discuss the different ways of identifying the elements using the CSS selector. A few basic keywords are used to locate elements like:

  • ID
  • Class
  • Attribute
  • Sub-String
  • Inner String

A dot (.) Operator Select the Class Selector

The Dot operator (.) represents a class in selenium, so by using the dot operator, you can identify web elements that are specified with the class attribute. For Example

<p class= “pages-sub-title”> SoftwareTestingo Test blog post on validating CSS Selectors </p>

If you remember, in Xpath, for locating this element, we can write the XPath like this //p[@class = ’value’], but in CSS, we can identify the same element by the following syntax:

.[“Class Value”]
“.pages-subtitle”

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_Class 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector(".pages-sub-title"));
      String elementText=text.getText();
      System.out.println("Element Text: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

Output:

Element Text: SoftwareTestingo Test blog post on validating CSS Selectors

ID Selector

Here, “#” represents ID, which is used to locate the element specified with the ID attribute. Let’s take an example for a better understanding.

CSS Selector - ID Syntax
CSS Selector – ID Syntax
<li id="menu-item-143" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-143">
<a href="https://softwaretestingo.blogspot.com/2020/08/css-selector.html">Product Updates</a>
</li>

If you can see the above example, then to locate in XPath, we can write this by //li[@id=’menu-item-143′], but for the same web element, we can write like this #menu-item-143.

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_ID 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector("#menu-item-143"));
      String elementText=text.getText();
      System.out.println("Element Text: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

Output:

Element Text: Product Updates

Attribute Selector

When we see the page source of some web pages, we can see the following:

<div class="modal fade" id="whitepaper-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<span class="close" data-dismiss="modal" style="top: 4px; position: absolute; right: 10px;">
<span aria-hidden="true">×</span>
</span>

Where you can see the above source code, you can find some attributes like key-value pairs, for example, ‘role = dialog,’ ‘data-dismiss = modal,’ etc. We are writing the syntax like this tag name [@attribute key = ‘attribute value’ ] for locating such web elements in XPath.

We can write in CSS Selector like this

div[role=’dialog’] or [role=’dialog’]

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_Attribute 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector("div[role='dialog']"));
      String elementText=text.getText();
      System.out.println("Element Text: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

Output:

Element Text: SoftwareTestingo

SubString Match

As of now, we are discussing the simple ways to locate web elements; let us go a little bit deeper and try to understand how we can more efficiently locate elements with the help of powerful querying techniques such as:

  • ^ indicated a prefix
  • $ indicating suffix
  • * indicating substring

If you observe, these are very similar to the Xpath functions like starts-with, contains, and ends with. Let us start to understand by taking some real-world examples

<div id=”123_randomId”>
<div id=”randomId_456″>
<div id=”123_pattern_randomId”>

^ indicated prefix

If the attribute value of an element is frequently changing, but the value starting a few characters is constant. Still, the rest of the characters are changing, and then, in that case, you can use the wild prefix character (^) to identify the element uniquely. the syntax is like this:

CSS Selector - Prefix Syntax
CSS Selector – Prefix Syntax

tag[attribute^=’starting text’]

Example:

input[id^=’user’]

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_Prefix 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector("div[id^='123_ra']"));
      String elementText=text.getText();
      System.out.println("Get Element Text Using Prefix Locator: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

$ indicating suffix

Similarly, if the last characters are constant, but the starting characters change, we can use the wild suffix character ($) to locate such an element. the syntax looks like this:

tag[attribute$=’ending text’]

input[id$=’message’]

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_Suffix 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector("div[id$='456']"));
      String elementText=text.getText();
      System.out.println("Get Element Text Using Suffix Locator: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

* Indicating a substring match

Suppose you don’t have complete attribute details or you have partial attribute value details. In that case, when using XPath, we are using the contains() functions. Similarly, when we are using a CSS selector at that time, we can use an asterisk (*), and the syntax looks like the below:

CSS Selector - Substring Syntax
CSS Selector – Substring Syntax

tag[attribute*=’containing text’]

Example:

input[id*=’er-messa’]

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_Substring 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector("div[id*='pattern']"));
      String elementText=text.getText();
      System.out.println("Get Element Text Using Substring Locator: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

How to Navigate to Child Elements

When discussing Xpath, we discussed how we can access the child elements with the help of the Axes concept. Similarly, some advanced techniques are present here to deal with the child and grandchild elements. That is:

  • Direct Child
  • Grand Child
  • Nth Child

Direct Child

For locating an Immediate child of a node in Xpath, we use ‘/,’ but in CSS, we can use the ‘>’ to identify the immediate child element.

Path: //div/a
CSS: div > a

package com.selenium.practice.locator;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_DirectChild 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      List<WebElement> list=driver.findElements(By.cssSelector("ul[id*='browsers']>li"));
      System.out.println("Printing All Elements Text In Console");
      for(int i=0;i<list.size();i++)
      {
         System.out.println(list.get(i).getText());
      }
      Thread.sleep(5000);
      
      driver.close();
   }
}

Child or Grand Child Element Locate

If an element has a child element or there are some grandchild elements present, then to locate those elements, we are using “//” ” For the same operation, you can use the white space like below:

XPath: //div//a
CSS: div a

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_GrandChildElement 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector("ul p"));
      String elementText=text.getText();
      System.out.println("Get Grand Child Element Text Using CSS Selector: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

Nth Child

This concept will be more helpful when dealing with the table or ordered or unordered list. Here, N represents the desired number of elements. Let us take a simple example to understand it:

<ul id=”browsers”>
<li>Chrome</li>
<li>Firefox</li>
<li>Edge</li>
<li>Safari</li>
</ul>

If you see the above code, you can find a list; from that, we require to select the 2nd element. We Can achieve that by following the below CSS Selector syntax:

#browsers li:nth-child(2)

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_SelectNthChildEx1 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      //Select 2nd Child Element
      WebElement text=driver.findElement(By.cssSelector("#browsers li:nth-child(2)"));
      String elementText=text.getText();
      System.out.println("Get 2nd Child Element Text Using CSS Selector: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

There is another way to locate the second element, and that is

ul#browsers li:nth-of-type(2)

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_SelectNthChildEx2 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      //Select 2nd Child Element
      WebElement text=driver.findElement(By.cssSelector("#browsers li:nth-of-type(2)"));
      String elementText=text.getText();
      System.out.println("Get 2nd Child Element Text Using CSS Selector: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

Similarly, we can easily select the last element in the list by using this

ul#browsers li:last-child

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_SelectLastChild 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      //Select Last Child Element
      WebElement text=driver.findElement(By.cssSelector("#browsers li:last-child"));
      String elementText=text.getText();
      System.out.println("Get Last Child Element Text Using CSS Selector: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}
<div id="123_randomId">123</div>
<div id="randomId_456">456</div>
<div id="123_pattern_randomId">789</div>

From the above list, if we want to select the 123 elements, then for that element, the CSS value is
div[id^=’123_rand’]

Locate Immediate Element Using CSS Selector

But based on the 123 elements, how you can select the immediate element, then you can use this

div[id^=’123_rand’] + div

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_ImmediateElement 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector.html");
      Thread.sleep(10000);
      
      WebElement text=driver.findElement(By.cssSelector("div[id*='123_randomId']+div"));
      String elementText=text.getText();
      System.out.println("Get Immediate Element Text Using CSS Selector: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

Multiple Attributes in CSS Selector

When Locating some elements using a CSS selector, sometimes it is very difficult to locate an element using a single attribute. In that case, to locate that specific element, we have to use multiple attributes to be more specific with the selection criteria to locate the correct element as per our requirement.

For example, let’s see the below piece of code:

<div class=”ajax_enabled” style=”display:block”>Sample Ajax</div>

In the above code snippet, the value of the display can be changed to None or Block, and it depends upon the Ajax call. So, to locate such elements, we have to use both class and style.

In the example below, we are trying to explain how to locate such elements by using multiple attributes.

package com.selenium.practice.locator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_MultipleAttributeEx 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector-adv-example.html");
      Thread.sleep(10000);
      
      //Use Of Multiple Attribute
      WebElement text=driver.findElement(By.cssSelector("div[class='ajax_enabled'][style='display:block']"));
      String elementText=text.getText();
      System.out.println("Get The Element Text Using Multiple Attribute: "+elementText);
      Thread.sleep(5000);
      
      driver.close();
   }
}

Attributes do NOT contain a specific value.

During testing, a scenario where you don’t want to select which have some specific values in an attribute. in the above scenarios, we have to understand how you can select the elements based on the values, but now we will understand how not to select by specific attribute value.

<div class="day past calendar-day-2017-02-13 calendar-dow-1 unavailable">123</div>
<div class="day today calendar-day-2017-02-14 calendar-dow-2 unavailable">456</div>
<div class="day calendar-day-2017-02-15 calendar-dow-3">789</div>
<div class="day calendar-day-2017-02-16 calendar-dow-4">111</div>

In the above example, we don’t want to select those elements whose attribute value is unavailable, so that we can achieve that by like below:

div[class*=calendar-day-]:not([class*=’unavailable’])

package com.selenium.practice.locator;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class CSSSelector_NotAttributeEx 
{
   public static void main(String[] args) throws InterruptedException 
   {
      WebDriver driver;
      System.setProperty("webdriver.chrome.driver","Path Of Browser Driver");

      driver=new ChromeDriver();
      driver.manage().window().maximize();
      driver.get("https://softwaretestingo.blogspot.com/2020/08/css-selector-adv-example.html");
      Thread.sleep(10000);
      
      List<WebElement> list=driver.findElements(By.cssSelector("div[class*=calendar-day-]:not([class*='unavailable'])"));
      System.out.println("Printing All Elements Text In Console Which Does Not Have Unavailable");
      for(int i=0;i<list.size();i++)
      {
         System.out.println(list.get(i).getText());
      }
      Thread.sleep(5000);
      
      driver.close();
   }
}

Revision on some CSS Selector concepts before your interview! A few basic XPaths were discussed in Yesterday’s and the day before’s posts.

p[name=”selenium”] Selects all p elements with an attribute called name with value “selenium”.
div.highlight Selects all div elements with class “highlight”.
divhashtag#header Selects div element with id “header”.
div<space>p Selects all p elements within a div.
ul > li Selects all li elements that are immediate children of an ul.
h1 + p Selects the first p element immediately after each h1 element.
h1 ~ p Selects all p elements that are siblings of h1.
a[href=’https://www.example.com’] Selects all elements with an href attribute equal to “https://www.example.com”.
div:first-child Selects the first child of each div element.
p:contains(“text”) Selects all p elements that contain the specified text.
element[attribute^=”value”] Selects all elements with an attribute starting with “value”.
element[attribute$=”value”] Selects all elements with an attribute ending with “value”.
element[attribute*=”value”] Selects all elements with an attribute containing “value”

I love open-source technologies and am very passionate about software development. I like to share my knowledge with others, especially on technology that's why I have given all the examples as simple as possible to understand for beginners. All the code posted on my blog is developed, compiled, and tested in my development environment. If you find any mistakes or bugs, Please drop an email to softwaretestingo.com@gmail.com, or You can join me on Linkedin.

Leave a Comment