Bootstrap with ::shadow and /deep/

1,037 views
Skip to first unread message

Karsten Becker

unread,
May 21, 2014, 6:40:27 AM5/21/14
to polym...@googlegroups.com
Hi,
I have a polymer application that is heavily using elements. The overall look of the page should be bootstrap, so I used applyAuthorStyle for all elements. This works well up to the latest carnary chrome, which now ignores those. So my app is basically broken there, and probably will be in a foreseeable future.

My first attempt at fixing this is by linking the bootstrap css from each polymer-element, which works, but the performance penalty is way too big. The site is flickering all over the place. So I was wondering, did anyone work on a bootstrap version with ::shadow and /deep/ that I could use to globally style my page?

Or am I missing another way of doing things?

Karsten

Martin Kleinschrodt

unread,
May 21, 2014, 8:33:46 AM5/21/14
to polym...@googlegroups.com
I've been wondering about this, too. Afaik the only way to get bootstrap to work across shadow dom boundaries is to adjust the selectors to use the /shadow-deep/ combinator. However, I'm wondering if using something like bootstrap is even idiomatic to web components. Perhaps what we need is something like a set of bootstrap-like styled web components? So instead of

<button type="button" class="btn btn-default">Default</button>

We could do something like

<button is="bootstrap-button" class="default">Default</button>

Karsten Becker

unread,
May 21, 2014, 10:45:34 AM5/21/14
to polym...@googlegroups.com
Well, then you still would have to specify the looks of that button within the bootstrap-button element. There you can either specify it locally (bad idea for performance and maintainability) or get it from the outside (better idea for both performance and maintainability). The things that you would want to specify locally, and which makes the shadow story interesting, is the fact that you can take care of the parts that you need, without being bothered from the outside, like shape, while color comes from the outside.

Douglas Hubler

unread,
May 21, 2014, 11:30:15 AM5/21/14
to polym...@googlegroups.com
I'm in the exact same situation with Polymer and Bootstrap in fact.  I'm blissfully productive using leaking CSS.   IMO Karsten was on the right track w/fixing this in bootstrap, there needs a adapter to be shadow dom aware.  Maybe there's some clever less/sass/stylus hacking to make this painless.   If i pull in a third party set of tags that are bootstrap based, then I should be able to apply same adapter to them as well.  If third party has specified CSS locally, then that would be difficult I think and would be an argument against defining them locally IMO.

Rob Dodson

unread,
May 21, 2014, 1:52:22 PM5/21/14
to Douglas Hubler, polymer-dev
This is kind of where the old world bumps up against the new world. Bootstrap was never designed to work with Web Components so it's not easy to shoehorn it in.

It sounds like what you want is for an element to know about and style its internal structure, but externally you should be able to easily theme these things so they look cohesive (probably by using /deep/). I don't think there's a quick fix way to go about that. Bootstrap (and libraries like it) will need to be rewritten to work in that model.

FWIW, we talk about this exact issue _a lot_ and we're trying to come up with good strategies to deal with it. So definitely don't take this as dismissal in any way. It's just a tough nut to crack ;)


On Wed, May 21, 2014 at 8:30 AM, Douglas Hubler <dhu...@gmail.com> wrote:
I'm in the exact same situation with Polymer and Bootstrap in fact.  I'm blissfully productive using leaking CSS.   IMO Karsten was on the right track w/fixing this in bootstrap, there needs a adapter to be shadow dom aware.  Maybe there's some clever less/sass/stylus hacking to make this painless.   If i pull in a third party set of tags that are bootstrap based, then I should be able to apply same adapter to them as well.  If third party has specified CSS locally, then that would be difficult I think and would be an argument against defining them locally IMO.

Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/b7ea2376-0c7f-4383-8e6f-c0317a1a3b8e%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

John Messerly

unread,
May 21, 2014, 2:21:53 PM5/21/14
to Rob Dodson, Douglas Hubler, polymer-dev
Idea here: could bootstrap.css be preprocessed to add this before each selector:
* /deep/

There are a few libraries out there for parsing CSS files. Probably not too hard to write a script for it.


Martin Kleinschrodt

unread,
May 21, 2014, 2:29:57 PM5/21/14
to polym...@googlegroups.com, Rob Dodson, Douglas Hubler
Something like html /deep/ or body /deep/ would probably be sufficient and better for performance but in principle that is likely the most pragmatic solution.

Karsten Becker

unread,
May 21, 2014, 6:11:54 PM5/21/14
to polym...@googlegroups.com, Rob Dodson, Douglas Hubler
Don't you actually need to insert a /deep/ into every descendant operator?
Like this:

ul li
{
background-color:yellow;
}

becomes

body /deep/ ul /deep/ li
{
background-color:yellow;
}

But what about the child and sibling selectors?

ul > li
{
background-color:yellow;
}

How could you translate that? The effect that I would love to have is that I can make the <li> element web component. I don't really understand how one could deprecate applyAuthorStyle when those questions don't have good answers.

Essentially there should be four simple formula:

1) If you see a b replace it with body /deep/ a /deep/ b
2) if you see a>b replace it with body /deep/ a /not-so-deep/ b
3) if you see a+b replace it with body /deep/ a /adjacent-ignoring-shadows/ b
4) if you see a~b replace it with body /deep/ a /sibling-ignoring-shadows/ b

Disclaimer: I hate JavaScript and I am not awfully familiar with CSS. So it is very possible that I am missing something here..


On Wednesday, May 21, 2014 8:21:53 PM UTC+2, John Messerly wrote:

Eric Bidelman

unread,
May 21, 2014, 6:30:02 PM5/21/14
to Karsten Becker, Elliott Sprehn, polymer-dev, Rob Dodson, Douglas Hubler
+elliot


Karsten said: 
linking the bootstrap css from each polymer-element, which works, but the performance penalty is way too big.

Elliot, can you share what Blink does with share stylesheet caching across elements Something as big as Bootstrap probably breaks the optimizations. 



Elliott Sprehn

unread,
May 21, 2014, 9:38:23 PM5/21/14
to Eric Bidelman, Karsten Becker, polymer-dev, Rob Dodson, Douglas Hubler
In Chrome 35 @import or @media will disable the stylesheet sharing.
In Chrome 36 only @import will disable the sharing.

Bootstrap should be fine in 36. I think it has @media rules which caused issues in Chrome 35.

I know the @import thing is a footgun. We hope to fix it eventually. :)

Karsten Becker

unread,
May 22, 2014, 7:17:22 AM5/22/14
to polym...@googlegroups.com, Eric Bidelman, Karsten Becker, Rob Dodson, Douglas Hubler
Importing bootstrap does just help partially. Because various relationships are lost.
Here I attempted to create a button bar, and I fail to see how I could possibly make the /deep/ version look like the regular one. But IMO this should be possible:


The problems that are causing troubles are:
The child descendant  > (replacing it with /deep/ solves it only if there is no further nesting going on) 
The sibling selectors +,~ (AFAIK there is no replacement)

And various pseudo classes like :first-child, :last-child etc.

It would be nice to have a version of these that ignores shadow dom boundaries, and treats it like a light-dom. 

Karsten Becker

unread,
May 22, 2014, 8:39:19 AM5/22/14
to polym...@googlegroups.com, Rob Dodson, Douglas Hubler
ok, so I did write a quick tool for that: https://github.com/KarstenB/csstransform and used the resulting https://github.com/KarstenB/csstransform/blob/master/bootstrap_deep.css but a few issues arise from that:
In Canary the /deep/'d version has priority over local declarations even within the element (not a good idea), so those have to be marked as !important
Browsers that are not aware of /deep/ fail to render anything correctly. So you need to provide a switch based on the fact whether applyAuthorStyle is supported... (very ugly)


On Wednesday, May 21, 2014 8:21:53 PM UTC+2, John Messerly wrote:

Daniel Freedman

unread,
May 22, 2014, 2:23:13 PM5/22/14
to Karsten Becker, polymer-dev, Rob Dodson, Douglas Hubler
On Thu, May 22, 2014 at 5:39 AM, Karsten Becker <kbec...@gmail.com> wrote:
ok, so I did write a quick tool for that: https://github.com/KarstenB/csstransform and used the resulting https://github.com/KarstenB/csstransform/blob/master/bootstrap_deep.css but a few issues arise from that:
In Canary the /deep/'d version has priority over local declarations even within the element (not a good idea), so those have to be marked as !important

I disagree with this statement. With the encapsulation of styles that web components provide, there has to be some way to provide more information to the component than it had at creation time.
/deep/ and ::shadow solve this by providing that information from the outside world.
If the interior of a component were the only way to control styling, then there would have to be much more cooperation between them and the page author.
 
Browsers that are not aware of /deep/ fail to render anything correctly. So you need to provide a switch based on the fact whether applyAuthorStyle is supported... (very ugly)

The workaround you really want is the css "all" property set to "inherit". https://developer.mozilla.org/en-US/docs/Web/CSS/all.
This property is a superset of the old applyAuthorStyles and resetStyleInheritance properties of ShadowDOM, and it can be applied with normal css selectors and not set on each ShadowRoot instance.

Here is the "intent to implement" email regarding blink's (and therefore Chrome's) status on "all": https://groups.google.com/a/chromium.org/d/msg/blink-dev/VkDKCvdVKlA/yGYNtgxnsHMJ
 

Douglas Hubler

unread,
May 27, 2014, 4:27:15 PM5/27/14
to polym...@googlegroups.com
With chrome 35 in stable channel, this issue now has come to a head.   

We're planning on ditching bootstrap (for a combination of reasons) and coming up with a single css file for our application. This css will be referenced on the main page and on *each* element as Karsten originally tested.  Kartsten reported performance hits so I avoided @import and @media in my css.  I used devtools/Network to verify css is downloaded exactly once and web server is contacted exactly twice.   This stands true no matter how many polymer elements I put on the page, how many nested the elements there are or how many different types of polymer elements I import.   The only caveat with this approach is having to specify css in every element which really isn't that bad.  Karsten, if you have more suggestions on where I might see issues, please reply if you could.

In reality, if wanted to keep bootstrap I could just edit it to avoid @media per Eliot's reply.

The only disconcerting point about this plan is that each polymer element is importing *way* more CSS definitions then it's actually using, but as long as it's not negatively affecting performance, I can get over this issue.


Elliott Sprehn

unread,
May 27, 2014, 4:42:56 PM5/27/14
to Douglas Hubler, polymer-dev
I would definitely suggest breaking up your CSS into chunks specific to each component. We need to break free of the idea of having one massive CSS file and one massive JS file like we did in the past. With web components write small css files and embed them inside your self contained elements.

If I import an <app-panel> I shouldn't need to download all the CSS for every other app-* widget. :)


Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

Douglas Hubler

unread,
May 27, 2014, 6:51:12 PM5/27/14
to polym...@googlegroups.com, Douglas Hubler

On Tuesday, May 27, 2014 4:42:56 PM UTC-4, Elliott Sprehn wrote:
I would definitely suggest breaking up your CSS into chunks specific to each component. We need to break free of the idea of having one massive CSS file and one massive JS file like we did in the past. With web components write small css files and embed them inside your self contained elements.

fair point, maybe I'll strive for something in-between one css and one css per polymer-element.  Some logical grouping.

Joe Gregorio

unread,
May 28, 2014, 9:26:29 AM5/28/14
to Douglas Hubler, polym...@googlegroups.com
Does UnCSS work with shadow DOM? https://github.com/giakki/uncss

Addy Osmani

unread,
May 28, 2014, 10:51:34 AM5/28/14
to polym...@googlegroups.com, Douglas Hubler
(grunt-uncss author here)

UnCSS and grunt-uncss rely on PhantomJS for rendering the content we scrape. Unfortunately, Phantom is currently using WebKit rather than Blink as their rendering engine, meaning that we can't reliably interpret styles in Shadow DOM. You may be able to get a good way with the output of Polymer's platform polyfills however. I haven't tested in practice though :)

dan...@springnet.co.uk

unread,
May 28, 2014, 12:28:50 PM5/28/14
to polym...@googlegroups.com, Douglas Hubler
Hi Douglas,

Glad I stumbled upon this thread as we're currently working towards using Web Components with Sass developed with an OOCSS mindset (BEM class naming conventions etc) and I'm struggling slightly to see how I will be able to fit the two together at the moment :S. 

Broadly speaking it seems like Web Components have tried to tackle the similar issues with CSS that the likes of the OOCSS/BEM/SMA conventions are tackling.

It would be great to keep in contact to see how you get - maybe we can swap some notes?

Rob/Eric - can you keep me posted on how you guys are getting on with tackling this issue internally? I'd love to be able to help some how.

*Just to note...I am not using Bootstrap, but my own custom set of tools I've built up over the past 2/3 years (files are broken into small modules and placed within a file structure similar to this: tools, base, objects, components) and are compiled at present into a single CSS*

Cheers,
Dan  

Rob Dodson

unread,
May 28, 2014, 2:26:25 PM5/28/14
to dan...@springnet.co.uk, polymer-dev, Douglas Hubler
At least for the moment the best examples will be the core-* elements. Though, many of those do not share styles. Keep an eye on the list and Github as we'll be rolling out improved UI elements in the future.


Follow Polymer on Google+: plus.google.com/107187849809354688692

---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

Daniel Peplow

unread,
May 28, 2014, 3:26:55 PM5/28/14
to Rob Dodson, polymer-dev, Douglas Hubler
Thanks for the reply Rob :)

se...@matveenko.ru

unread,
Nov 17, 2014, 4:17:24 PM11/17/14
to polym...@googlegroups.com, dhu...@gmail.com
I think that CSS Variables spec looks very promising in this context (supported by Firefox only for now).

It will require some efforts to reimplement bootstrap using css variables and it will not be bootstrap anymore. But this seems the only fair way to implement styling accross a bunch of components, shadow dom, etc.
Reply all
Reply to author
Forward
0 new messages