4

After a talk by Rob Dodson on Web Components, where he mentioned the brand new "cat" ^^ and "hat" ^ CSS selectors, I've asked about the possibilities of applying styles not only to a custom element's ShadowDOM, but also to the browser's native elements' ShadowDOM?

Is it possible to style elements from the ShadowDOM? In which browsers and how? The only relevant article I've found was by Dimitry Glazkov on 'What the Heck is Shadow DOM?', where he lays out reaching into ShadowDOM subtrees by using pseudo selectors and -webkit-appearance: none; rules.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Volker E.
  • 5,911
  • 11
  • 47
  • 64
  • See my recent answer **[here](http://stackoverflow.com/questions/27622605/what-is-the-content-pseudo-element-and-how-does-it-work/27629265#27629265)** for more info on styling elements in ShadowDOM. The Cat and the Hat selectors are no longer supported. – TylerH Dec 30 '14 at 14:21

2 Answers2

2

Due to the status of the draft of CSS Scoping Module Level 1 being able to change at any moment, my original approach wasn't working very long.

In Chrome v33+ you'll have to turn Enable Experimental Web Platform Features in chrome://flags on for the code below to work.


Starting with Chrome Canary v33 and its cat selector ^^ the answer is: Yes!
Update 2014-03-30: Chrome Canary v35+ supports the newest version of the selector, now the so-called /deep/ selector.

It styles over all boundaries and also works on native elements.

See: http://codepen.io/Volker_E/pen/jsHFC

/* ... Example for applying to all h2 elements, no matter if DOM or any ShadowDOM subtree ... */
:root ^^ h2 {
    font-family: "Arial Black", sans-serif;
}

/* Cr 33+: The "cat" also works on native elements' ShadowDOM */
video ^^ input[type="button"]:first-child {
    opacity: .75;
    -webkit-filter: drop-shadow( .2rem .2rem .2rem hsla( 5, 100%, 50%, 1 ) );
}

/* Cr 35+: /deep/ also works on native elements' ShadowDOM */
video /deep/ input[type="button"]:first-child {
    opacity: .75;
    -webkit-filter: drop-shadow( .2rem .2rem .2rem hsla( 5, 100%, 50%, 1 ) );
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
Volker E.
  • 5,911
  • 11
  • 47
  • 64
1

It is possible, at least in Chrome. If you check Shadow DOM of <input type="date"> you will see:

<input type="date">
  #document-fragment
    <div part="-webkit-datetime-edit" id="date-time-edit">
      <div part="-webkit-datetime-edit-fields-wrapper">
        <span role="spinbutton" aria-valuetext="blank" aria-valuemin="1" aria-valuemax="12" aria-help="Month" part="-webkit-datetime-edit-month-field">mm</span>
        <div part="-webkit-datetime-edit-text">/</div>
        <span role="spinbutton" aria-valuetext="blank" aria-valuemin="1" aria-valuemax="31" aria-help="Day" part="-webkit-datetime-edit-day-field">dd</span>
        <div part="-webkit-datetime-edit-text">/</div>
        <span role="spinbutton" aria-valuetext="blank" aria-valuemin="1" aria-valuemax="275760" aria-help="Year" part="-webkit-datetime-edit-year-field">yyyy</span>
      </div>
    </div>
</input>

Then you can style separate pseudo-elements:

::-webkit-datetime-edit-year-field {
  font-weight: bold;
}

According to Rob Dodson himself it is possible to use ^ and ^^ selectors to style native Shadow DOM. So this rule should work (Chrome Canary, I believe):

input[type="date"] ^ [part="-webkit-datetime-edit-year-field"] {
  font-weight: bold;
}
Pavlo
  • 43,301
  • 14
  • 77
  • 113
  • Nice answer, Glazkov already mentioned that. But if there are no pseudo-elements attached via attributes like in ` – Volker E. Nov 18 '13 at 09:27
  • @VolkerE. Than you have to use other selectors, such as `nth-child()` and `nth-of-type()`. – Pavlo Nov 18 '13 at 09:38