How to Generate All Possible CSS 2 Selector Combinations?

Tags: javascript,jquery,dom,css-selectors

Problem :

What would be the best way to generate all possible CSS 2 Selector Combinations for a DOM element in context with the current state of the document?

Eg: For the following MarkUp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="" xml:lang="en">
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  <div id="content">
      <li class="last-li">c</li> <!--ARGUMENT ELEMENT-->

A JS/jQuery Method such that the <!--ARGUMENT ELEMENT--> in the above markup is given as an argument to the method it returns all possible CSS 2 Selector combinations for the Argument in form of an array. An optional parameter can be added to the method which will define the maximum depth of CSS 2 Selector Nesting. If this parameter is set to false it should return all possible combinations (Will be a performance hogger if set to false)

Example Output:

 "ul .last-li",
 "ul li.last-li",
 "div ul .last-li",
 "div ul li.last-li",
 "#content ul .last-li",
 "#content ul li.last-li",
 "div#content ul .last-li",
 "div#content ul li.last-li",
 "body div ul li.last-li",
 "body div ul .last-li",
 "body #content ul li.last-li",
 "body div#content ul .last-li",
 "body div#content ul li.last-li",

Any pointers in this regard will be extremely helpful.

Solution :

First, let's stick to a narrow class of selectors involving tag names, class names and IDs, nothing fancy like E > F or E + F. Let's also disallow combinations of class names (.class1.class2.class3), otherwise a single element with 10 class names would generate 4 million selectors alone.

Each of our full selectors consists of simple selectors separated by spaces. Every simple selector is a combination of tag{0,1}id{0,1}class{0,n} - i.e. each element has exactly one tag, at most one ID, and it can have an arbitrary number of class names. That gives us the upper limit of 2 * 2 * (n + 1) simple selectors for a single element.

Given a reference to a DOM element grab it's tag name, ID and class names. Calculate all possible simple selectors as described above. Lets call this set A1. Move one step up the hierarchy to it's parent, calculate all simple selectors for that parent element - that'll be the set A2. Continue until you reach the html element - the set Am. Now you'll have a list, consisting of m items, each item is a set of simple selectors.

Now pick some of these sets and find their cartesian product. Say, m = 5. How many sets can you pick? The set A1 is always present, but others are optional. For each one of them you either pick it or not. That's like binary numbers:

0000 // 0, A1
0001 // 1, A1 x A2
0010 // 2, A1 x A3
0011 // 3, A1 x A2 x A3
0100 // 4, A1 x A4

That means you'll have 2^(m-1) cartesian products. You can now convert them to strings. The last step is to remove duplicates, consider this example:


Our calculations will yield this list:

  div span // inner div
  div span // outer div
  div div span

Those two divs yield duplicate selectors. Remove those and the job is done. All the steps are very simple algorithmically. I'm sure you can figure them out, but if you get stuck somewhere or need further clarification feel free to ask me in the comments.


So, I decided to play with it a bit more and wrote the program, here's the list of selectors your example generates:

    CSS Howto..

    How to set a css class to an array of tags on mouse hover in Javascript?

    How to make DIVs flow to the left in a x-scrollable pane with CSS?

    how to cope with text to element alignment issues

    How to style a SVG using CSS in javaFX FXML

    How to make Block Container with Inline-Block Child in CSS

    How to create a CSS3 animation that resembles an image fill up effect?

    How to only deregister Wordpress stylesheet for non-logged in users?

    How to change the style of horizontal menu

    How to define the css :focus state in a jQuery selector?

    How to override the height of parent node using CSS?

    how to select css class attributes from mootools,getStyle()?

    How to locate the element within CSS using javascript

    How to get jQuery to recognize mouse over image once per hover

    How to change an image on click using CSS alone?

    css how to force to ul,ol to show numbers or disc, after reset the list style.?

    How to add and remove div's (input)

    How to adjust 100% height to include height of added element

    How to change the media attribute of a css file with plain JS

    How to change the font-size of the part of textarea text in HTML,CSS?

    image carousel showing all images

    How to rotate element to left and right based on mouse movement using jQuery & CSS

    CSS - How to avoid element content to be displayed on 2 lines

    How to style Select2 input tags with css and how to limit them

    how do responsive recaptcha images

    How do you get a css box to extend the entire width of the browser window?

    How do I stop the text from moving when hovered? (background-image is involved)

    How to make hover buttons?

    How to automatically style HTML output of kramdown converter?

    How to accomplish this layout with CSS and HTML?

    How to add text to different parts of chart made from css, html, and javascript?