Targeting CSS Shadow Parts via URL search params
Bryan Ollendyke
Posted on August 23, 2022
Yeah I know; your jelly you didn't think to mash those words together for great SEO. No, I assure you it's a real thing courtesy of this fun issue came as an idea from Paul Hibbits, an educator who loves Doxify / GravCMS. The idea was to be able to let users (or the developer) send links to people with parts of the UI disabled. This has a few possible use-cases:
- Quick A/B test of thing vs not thing
- Allow removing share links and other distractions
- Allow for removing parts of the UI when embedding in an iframe
In order to achieve this, I mixed together some interesting solutions. First, we allow a URL search parameter like this welcome-page?disable-features=footer,site-menu-content
. We can parse this into a string like so
const urlParams = new URLSearchParams(window.location.search);
const disableFeatures = urlParams.get("disable-features");
if (disableFeatures != null) {
this.disableFeatures = disableFeatures;
}
This allows us to set the internal disableFeatures
property in our web component based on the URL's search location. In LitElement we then reflect
that attribute so that we can do CSS selectors like this haxcms-site-builder[disable-features="thing"]
.
Understanding *=
Reading the Moz Doc page on attribute selectors we see a *=
selector which says:
Represents elements with an attribute name of attr whose value contains at least one occurrence of value within the string.
This means that if we have things,and,stuff
we can match on *="and"
successfully. Using this knowledge, We can create a selector like: haxcms-site-builder[disable-features*="site-menu-content"]
and successfully target that URL condition.
Show me the Shadow Parts
The ::part syntax + attribute, is a relative newcomer to HTML spec. It allows for targeting parts of elements that lay within shadowRoots of other elements in order to provide specific styling.
haxcms-site-builder[disable-features*="site-menu"] .haxcms-theme-element::part(site-menu)
Combining these approaches we get a solution like so which can successfully allow (smart) users to target and disable parts of the UI via the URL parameter while safely only allowing the targeting of ones we allow.
TLDR the fun video
You got it
The full CSS selector
haxcms-site-builder[disable-features*="site-menu"] .haxcms-theme-element::part(site-menu),
haxcms-site-builder[disable-features*="page-breadcrumb"] .haxcms-theme-element::part(page-breadcrumb),
haxcms-site-builder[disable-features*="print-branch-btn"] .haxcms-theme-element::part(print-branch-btn),
haxcms-site-builder[disable-features*="rss-btn"] .haxcms-theme-element::part(rss-btn),
haxcms-site-builder[disable-features*="git-corner-btn"] .haxcms-theme-element::part(git-corner-btn),
haxcms-site-builder[disable-features*="search-btn"] .haxcms-theme-element::part(search-btn),
haxcms-site-builder[disable-features*="site-menu-content"] .haxcms-theme-element::part(site-menu-content),
haxcms-site-builder[disable-features*="footer"] .haxcms-theme-element::part(footer),
haxcms-site-builder[disable-features*="qr-code-btn"] .haxcms-theme-element::part(qr-code-btn),
haxcms-site-builder[disable-features*="right-col"] .haxcms-theme-element::part(right-col),
haxcms-site-builder[disable-features*="left-col"] .haxcms-theme-element::part(left-col)
{
display: none !important;
}
Posted on August 23, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.