guest@mukunda.com:/blog# ./cat 2023/getting-around-existing-css-for-overlays.txt Name: Getting Around Existing CSS for Overlays Date: Jan 22, 2023 Despite starting my CSS adventures probably two decades ago, I'd never heard about "specificity" until now. I figured CSS just did things top-down. That makes sense to me, and I don't see why specificity was ever implemented to begin with. What we get are side effects that make it hard to put two separate components together. On top of that odd rule, there is no easy way to undo element-level styles. Say a site has this CSS: h1 { font: stupid; } You have an overlay injected onto the site. You figure that this should do the trick to undo any styles: #overlay-panel { all: initial; ... } However, it doesn't. If you have: <div id="overlay-panel"> <h1>Title</h1> </div> It is going to render in the stupid font, because the h1 rule is targeting any plain h1 specifically, so that h1 will not inherit from our initial rule. To get around this is VERY tedious. It would be quite convenient if there was a CSS "barrier" feature that we could use to block any previous stylesheets. This is what I ended up doing (after some trial and error of many approaches!): First, I keep everything in a unique selector, as to avoid touching anything on the underlying site. This sets up our base styles that will be inherited by subelements. #mypanel {...} Next, I use a wildcard "revert" style for everything. Revert should cause inheritance for properties that inherit (inheriting from the base properties that I defined, and not what the underlying site defined), and otherwise reset any other properties. #mypanel * { all: revert } However, we can't just do this, since it breaks some features. For example, with SVG, it overrides properties that are introduced by element attributes. Same for "contenteditable". To get around the SVG problem, I excluded all SVG elements from the rule. If a site is styling SVG directly, it will cause problems, but I'm not going to care about that case. @namespace svg "http://www.w3.org/2000/svg"; #mypanel *:not(svg|*) { all: revert } For contenteditable, I just reintroduced the properties that it overwrites. I don't actually see why this rule should be overwriting "attribute" styles (which I figured would have a high specificity), but this is the hand we're dealt, I guess. #mypanel div[contenteditable] { -webkit-user-modify: read-write; overflow-wrap: break-word; -webkit-line-break: after-white-space; } This is pretty ugly to me, working with implementation- specific properties like that, but I don't see any other choice. If anyone has a better way to create a barrier between a site and extension elements, I'm interested in hearing your approach. Send the author a comment << Index