CSS4 parent selector based on jQuery

  • By Kasper Mikiewicz
  • Last update: Oct 6, 2022
  • Comments: 14


What is cssParentSelector

cssParentSelector is a polyfill based on jQuery that allows you to use parent selector in CSS.


Released under MIT and GPL licenses.


Just attach this plugin to your code and that's all.

<script src="jQuery.cssParentSelector.js"></script>


parent! target > child:state

Quick info about parent selector in CSS4

! - determines subject of selector according to CSS4 reference

E > F - selects an F element, child of E

E! > F - selects an E element, parent of F


Any vaild selector is okey, id, class, even like this one: input[type=checkbox]


This is optional, after we've got PARENT of our CHILD selector, we look for this TARGET element within PARENT.


Based on this, we select PARENT element.


As for now plugin supports:

  • changed, selected
  • checked
  • focus
  • hover
  • click
  • dblclick
  • active


  <div id="container">
      <label>Change value and click somewhere</label>
      <input type="text" name="name" placeholder="Value" class="dotted">
      <span class="message">Yay, you've changed value.</span>

    <p class="custom">
      <input type="checkbox" name="name" placeholder="Value" class="dashed">
      <span class="message">Yay, you've checked.</span>

      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua.
      <a href="#" class="hide-parent">&#x2716;</a>
/* Select paragraph parent of input or a*/
p! > input, p! > a { border: 1px solid #ccc; padding: 10px 5px; }

/* Select any parent of input or a*/
*! > input, p! > a { background: #fafafa; }

/* Select any parent with class of input */
*.custom! > input { background: #f5f5f5; }

/* Select any parent with class of input */
#container! > p { background: #eee; }

/* Select any parent of input with class */
*! > input.dotted { border-style: dotted; }
*! > input.dashed { border-style: dashed; }=

/* En empty declaration, just for tests */
*! > p {


/* Hide an message box */
.hide-parent { float: right; }
p! > .hide-parent:click { display: none; /* Comment inside declaration */ }=

/* Select any parent of input which value was changed */
p! > input:changed { background: #EEDC94; }

/* Select label within parent of focused text input */
p! label > input[type=text]:focus{ display: block; }

/* Select element with definied class within parent of changed/checked text/checkbox input */
p! .message > input[type=text]:changed,
p! .message > input[type=checkbox]:checked {
    display: inline;

p! span:first-child> input { display: block; }
p:after! > input {
  display: block;
  width: 100%;
  height: 1px;
  background-color: #111;


  • 1.0.9 - *09.09.2012 *

    • Added support for images in css bacground property (// in image link was interpreted as comment)
    • Minified version
  • 1.0.8 - *07.02.2012 *

    • Added support for pseudo classes (after, before, first-child, last-child, nth-child(), active and anything that jquery filter function can handle)
    • Added !important to all declarations.
  • 1.0.7 - 21.01.2012

    • Now before matchig css for definied regex we strip comments
    • Empty declarations are omitted
    • Better regex
    • Optimized code
  • 1.0.6 - 18.01.2012

    • Changed structure to the one described in CSS4 reference
    • Improved performance




  • 1

    jQuery 1.9 Compatibility

    It seems with the release of jQuery 1.9 the state selectors and attribute selectors no longer function. I've tested this in a working environment and then just replaced the jQuery version. A base selector of

    p! > .maillink

    works just fine, but these do not:

    p! > a[href^="mailto"]

    p! > a:hover

    Is anyone else experiencing this issue with jQuery 1.9?

  • 2

    Sort of an issue

    Ok, so this isn't really an issue, but in your samples you use a :click state, and I'm pretty sure I've never heard of them, is that actually possible?

  • 3

    Why not make it match the CSS4 parent selector syntax

    CSS4 defines

    E! > F an E element parent of an F element

    in http://dev.w3.org/csswg/selectors4/.

    Why not use that syntax, as then it could be used as a polyfill for all those ancient browsers that don't support CSS4 (i.e. all of them right now!)

  • 4

    Doesnt work with child attribute selectores

    Thanks for your polyfill!

    unfortunately it won't work with attribute selectors on child elements. See http://jsbin.com/etiweq/5/edit#html,live The select's color should be blue if the "empty" option is selected.

  • 5

    Doesn't seem to work at all...

    I've included the js file in my html, tried in the footer and in the head (straight after jquery and after my css) but it doesn't have any effect whatsoever :( Any idea what I could be doing wrong?

  • 6

    css.replace is not a function

    Firebug throws me an error when including the script saying that css.replace in not a function on (about) line 55-57.

    Don't know what can be causing this?

    Working on: OSX Lion @ Firefox 11.0

  • 7

    Pseudo selectors should be ignored, such as :before, :after etc

    If you had a style such as #el + a:after > .sel {}

    A class gets written for the :after rules, even though it will never be applied.

    A workaround is to do something like #el +a > .sel {} and then actually style the after with #el + a[class]:after as you've added a .CPS class to the link

  • 8

    Styles with url() break the regex matching

    It appears styles with url(...) will cause the regex to not match. For example:

    /* this will match */
    foo! > bar {
      background-color: blue;
    /* this will NOT match */
    foo! > bar {
      background: url('foo.png');
  • 9

    New notation

    Have you noticed the notation change in the latest working draft of the W3C? I noticed you are still following up on the first notation using the "!" notation.

    Styling a parent now has the following notation: $E > F

    The working draft I am referring to can be found here: http://www.w3.org/TR/2011/WD-selectors4-20110929/

  • 10

    a:focus not quite working

    I cannot seem to get the parent of a focused anchor to style when the anchor is focused. It seems to be styling it on load not when the anchor is focused. Quick example below ...


  • 11

    fixed some bugs

    1. if the dataType of ajax has been set before, the $.get will not work property. fixed by changing it to $.ajax.
    2. if the content of css rules contain brackets, (e.g. background:url(xxx.jpg), the REGEX match will fail.
    3. if child is a checkbox and the checkbox is checked, the status of class is wrong. fixed by toggle the class once more.
  • 12

    [enhancement] Add missing bower.json.

    Hey, maintainer(s) of Idered/cssParentSelector!

    We at VersionEye are working hard to keep up the quality of the bower's registry.

    We just finished our initial analysis of the quality of the Bower.io registry:

    7530 - registered packages, 224 of them doesnt exists anymore;

    We analysed 7306 existing packages and 1070 of them don't have bower.json on the master branch ( that's where a Bower client pulls a data ).

    Sadly, your library Idered/cssParentSelector is one of them.

    Can you spare 15 minutes to help us to make Bower better?

    Just add a new file bower.json and change attributes.

      "name": "Idered/cssParentSelector",
      "version": "1.0.0",
      "main": "path/to/main.css",
      "description": "please add it",
      "license": "Eclipse",
      "ignore": [
      "dependencies": {
        "<dependency_name>": "<semantic_version>",
        "<dependency_name>": "<Local_folder>",
        "<dependency_name>": "<package>"
      "devDependencies": {
        "<test-framework-name>": "<version>"

    Read more about bower.json on the official spefication and nodejs semver library has great examples of proper versioning.

    NB! Please validate your bower.json with jsonlint before commiting your updates.

    Thank you!

    Timo, twitter: @versioneye email: [email protected] VersionEye - no more legacy software!

  • 13

    fix a bug when there's no element on page



    when no checkbox on page, it will output:

    /*some css 1*/
    /*some css 2*/

    thus makes 'some css 2' invaild.

    Another case:


    if no checkbox is disabled, it will output:

    /*some css 1*/
    /*some css 2*/

    makes the selector is invalid.

  • 14

    Getting to work with adjacent selector instead of children?

    As I understand the spec, the following should work when the parent selector is implemented:

    h4! + p { }

    So it targets the h4 immediately above the p element. This doesn't work with this plugin though...