<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>David Darnes on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>David Darnes</name>
  </author>
  <link href="https://web.dev/authors/daviddarnes/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/D4RF9eRlpsL0byFo3nTu.jpeg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>David is a senior front-end developer at Nordhealth.</subtitle>
  
  
  <entry>
    <title>How Nordhealth uses Custom Properties in Web Components</title>
    <link href="https://web.dev/custom-properties-web-components/"/>
    <updated>2022-08-17T00:00:00Z</updated>
    <id>https://web.dev/custom-properties-web-components/</id>
    <content type="html" mode="escaped">&lt;p&gt;I&#39;m Dave and I&#39;m a Senior Front-end Developer at &lt;a href=&quot;https://nordhealth.com/&quot; rel=&quot;noopener&quot;&gt;Nordhealth&lt;/a&gt;. I work on the design and development of our &lt;a href=&quot;https://nordhealth.design/&quot; rel=&quot;noopener&quot;&gt;design system Nord&lt;/a&gt;, which includes building Web Components for our component library. I wanted to share how we solved the problems around styling &lt;a href=&quot;https://developer.mozilla.org/docs/Web/Web_Components&quot; rel=&quot;noopener&quot;&gt;Web Components&lt;/a&gt; by using &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/--*&quot; rel=&quot;noopener&quot;&gt;CSS Custom Properties&lt;/a&gt;, and some of the other benefits of using Custom Properties in design systems and component libraries.&lt;/p&gt;
&lt;h2 id=&quot;how-we-build-web-components&quot;&gt;How we build Web Components &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/custom-properties-web-components/#how-we-build-web-components&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To build &lt;a href=&quot;https://nordhealth.design/components/&quot; rel=&quot;noopener&quot;&gt;our Web Components&lt;/a&gt; we use &lt;a href=&quot;https://lit.dev/&quot; rel=&quot;noopener&quot;&gt;Lit&lt;/a&gt;, a library that provides a lot of boilerplate code such as state, scoped styles, templating, and more. Not only is Lit lightweight but it&#39;s also built on native JavaScript APIs, meaning we can deliver a lean bundle of code that takes advantage of  features the browser already has.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;html&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; css&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; LitElement&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;lit&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SimpleGreeting&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LitElement&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; styles &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; css&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;:host { color: blue; font-family: sans-serif; }&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; properties &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;there&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; html&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;p&gt;Hey &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, welcome to Web Components!&amp;lt;/p&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;customElements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;simple-greeting&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SimpleGreeting&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;A Web Component written with Lit.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But the most appealing thing about Web Components is that they work with almost any existing JavaScript framework, or even no framework at all. Once the main JavaScript package is referenced in the page, using a Web Component is very much like using a native HTML element. The only real tell-tale sign that it isn&#39;t a native HTML element is the consistent hyphen within the tags, which is a standard to signify to the browser that this is a Web Component.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;module&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;./simple-greeting.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;simple-greeting&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Dave&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;simple-greeting&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;Using the Web Component created above on a page.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;shadow-dom-style-encapsulation&quot;&gt;Shadow DOM style encapsulation &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/custom-properties-web-components/#shadow-dom-style-encapsulation&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Much in the same way native HTML elements have a &lt;a href=&quot;https://developer.mozilla.org/docs/Web/Web_Components/Using_shadow_DOM&quot; rel=&quot;noopener&quot;&gt;Shadow DOM&lt;/a&gt;, so do Web Components. Shadow DOM is a hidden tree of nodes within an element. The best way to visualise this is by opening up your web inspector and turning on the option to &amp;quot;Show Shadow DOM tree&amp;quot;. Once you&#39;ve done this, try looking at a native input element in the inspector—you&#39;ll now have the option to open up that input and see all the elements within it. You can even try this with one of our Web Components—try inspecting &lt;a href=&quot;https://nordhealth.design/components/input/&quot; rel=&quot;noopener&quot;&gt;our custom input component&lt;/a&gt; to see its Shadow DOM.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;The shadow DOM inspected in DevTools.&quot; decoding=&quot;async&quot; height=&quot;369&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/kheDArv5csY6rvQUJDbWRscckLr1/KH3KfdprFwtC5XRINZgB.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;figcaption&gt;  
Example of the Shadow DOM in a regular text input element and in our Nord input Web Component.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of the advantages (or drawbacks, depending on your outlook) to Shadow DOM is style encapsulation. If you write CSS within your Web Component, those styles can&#39;t leak out and affect the main page or other elements; they are completely contained within the component. In addition, CSS written for the main page or a parent Web Component can&#39;t leak into your Web Component.&lt;/p&gt;
&lt;p&gt;This encapsulation of styles is a benefit in our component library. It gives us more of a guarantee that when someone uses one of our components, it will look as we intended, regardless of the styles applied to the parent page. And to further make sure, we add &lt;code&gt;all: unset;&lt;/code&gt; to the root, or &amp;quot;host&amp;quot;, of all our Web Components.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:host&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unset&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; block&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;box-sizing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; border-box&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;text-align&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; start&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;Some component boilerplate code being applied to the shadow root, or host selector.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;However, what if someone using your Web Component has a legitimate reason to change certain styles? Maybe there&#39;s a line of text that needs more contrast due to its context, or a border needs to be thicker? If no styles can get into your component, how can you unlock those styling options?&lt;/p&gt;
&lt;p&gt;That&#39;s where CSS Custom Properties come in.&lt;/p&gt;
&lt;h2 id=&quot;css-custom-properties&quot;&gt;CSS Custom Properties &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/custom-properties-web-components/#css-custom-properties&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/Using_CSS_custom_properties&quot; rel=&quot;noopener&quot;&gt;Custom Properties&lt;/a&gt; are very appropriately named—they are CSS properties that you can entirely name yourself and apply whatever value is needed. The only requirement is that you prefix them with two hyphens. Once you&#39;ve declared your custom property, the value can be used in your CSS using the &lt;code&gt;var()&lt;/code&gt; function.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-color-accent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;53&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 89&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 199&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.n-color-accent-text&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-accent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;Example from our CSS Framework of a design token as a Custom Property and it being used on a helper class.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When it comes to inheritance, all Custom Properties are inherited, which follows the typical behaviour of regular CSS properties and values. Any custom property applied to a parent element, or the element itself, can be used as a value on other properties. We make heavy use of Custom Properties for our design tokens by applying them to the root element via our CSS Framework, which means that all elements on the page can use these token values, whether that be a Web Component, CSS helper class, or a developer wanting to pluck a value from our list of tokens.&lt;/p&gt;
&lt;p&gt;This ability to inherit Custom Properties, with the use of the &lt;code&gt;var()&lt;/code&gt; function, is how we pierce through our Web Components&#39; Shadow DOM and let developers have more finegrained control when styling our components.&lt;/p&gt;
&lt;h2 id=&quot;custom-properties-in-a-nord-web-component&quot;&gt;Custom Properties in a Nord Web Component &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/custom-properties-web-components/#custom-properties-in-a-nord-web-component&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Whenever we&#39;re developing a component for our design system, we take a thoughtful approach to its CSS—we like to aim for lean but very maintainable code. The design tokens we have are defined as Custom Properties within our main CSS Framework on the root element.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-space-m&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 16px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-space-l&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 24px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-color-background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 255&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-color-border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;216&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 222&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 228&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;CSS Custom Properties being defined on the root selector.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These token values are then referenced within our components. In some cases, we&#39;ll apply the value directly on the CSS property, but for others, we&#39;ll actually define a new contextual Custom Property and apply the value to that.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:host&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-tab-group-padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-tab-list-background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-background&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-tab-list-border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inset 0 -1px 0 0 &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-border&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.n-tab-group-list&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;box-shadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-tab-list-border&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-tab-list-background&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-space-s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;Custom Properties being defined on the shadow root of the component and then being used in the component styles. Custom Properties from the list of design tokens are also being used.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We&#39;ll also abstract some values that are specific to the component but not in our tokens and turn them into a contextual Custom Property. Custom Properties that are contextual to the component provide us with two key benefits. First, it means we can be more &amp;quot;dry&amp;quot; with our CSS as that value can be applied to multiple properties inside the component.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.n-tab-group-list::before&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;padding-inline-start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-tab-group-padding&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.n-tab-group-list::after&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;padding-inline-end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-tab-group-padding&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;The tab group padding contextual Custom Property being used in multiple places within the component code.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;And second, it makes component state and variation changes really clean—it&#39;s only the custom property that needs to be changed to update all those properties when, say, you&#39;re styling a hover or active state or, in this case, a variation.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:host([padding=&quot;l&quot;])&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--n-tab-group-padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-space-l&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;A variation of the tab component where the padding is being changed using a single Custom Property update rather than multiple updates.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But the most powerful benefit is that when we define these contextual Custom Properties on a component, we create a sort of custom CSS API for each of our components, which can be tapped into by the user of that component.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;&amp;lt;nord-tab-group label=&quot;Title&quot;&gt;&lt;br /&gt;  &amp;lt;!-- ... --&gt;&lt;br /&gt;&amp;lt;/nord-tab-group&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;style&gt;&lt;br /&gt;  nord-tab-group&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;--n-tab-group-padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-space-xl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&amp;lt;/style&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;Using the tab group component on the page and updating the padding Custom Property to a larger size.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The preceding example shows one of our Web Components with a contextual Custom Property changed via a selector. The result of this entire approach is a component that provides enough styling flexibility to the user while still keeping most of the actual styles in check. Plus, as a bonus, we as component developers have the ability to intercept those styles applied by the user. If we wish to adjust or extend one of those properties, we can without the user needing to change any of their code.&lt;/p&gt;
&lt;p&gt;We find this approach extremely powerful, not only for us as creators of our design system components, but also for our development team when they use these components in our products.&lt;/p&gt;
&lt;h2 id=&quot;taking-custom-properties-further&quot;&gt;Taking Custom Properties further &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/custom-properties-web-components/#taking-custom-properties-further&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At the time of writing we don&#39;t actually reveal these contextual Custom Properties in &lt;a href=&quot;https://nordhealth.design/&quot; rel=&quot;noopener&quot;&gt;our documentation&lt;/a&gt;; however, we plan to so that our wider development team can understand and leverage these properties. Our components are packaged on npm with &lt;a href=&quot;https://github.com/webcomponents/custom-elements-manifest&quot; rel=&quot;noopener&quot;&gt;a manifest file&lt;/a&gt;, which contains everything there is to know about them. We then consume the manifest file as data when our documentation site is deployed, which is done using &lt;a href=&quot;https://www.11ty.dev/&quot; rel=&quot;noopener&quot;&gt;Eleventy&lt;/a&gt; and its &lt;a href=&quot;https://www.11ty.dev/docs/data-global-custom/&quot; rel=&quot;noopener&quot;&gt;Global Data feature&lt;/a&gt;. We plan to include these contextual Custom Properties in this manifest data file.&lt;/p&gt;
&lt;p&gt;Another area we wish to improve on is how these contextual Custom Properties inherit values. Currently, for example, if you wanted to adjust the colour of two divider components, you&#39;d need to target both of those components specifically with selectors, or apply the custom property directly on the element with the style attribute. This might seem fine, but it would be more helpful if the developer could define those styles on a containing element or even at the root level.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- ... --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;  &lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;nord-divider&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;--n-divider-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-status-danger&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-space-s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-surface-raised&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;section nord-divider&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;--n-divider-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-status-success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;Two instances of our divider component which need two different colour treatments. One is nested inside a section which we can utilise for a more specific selector, but we have to target the divider specifically.&lt;/figcaption&gt;
&lt;/figure&gt;  
&lt;p&gt;The reason you have to set the Custom Property value directly on the component is because we&#39;re defining them on the same element via the component host selector. The global design tokens that we use directly in the component pass straight through, unaffected by this issue, and can even be intercepted on parent elements. How can we get the best of both worlds?&lt;/p&gt;
&lt;h2 id=&quot;private-and-public-custom-properties&quot;&gt;Private and public Custom Properties &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/custom-properties-web-components/#private-and-public-custom-properties&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://lea.verou.me/2021/10/custom-properties-with-defaults/&quot; rel=&quot;noopener&quot;&gt;Private custom properties is something that has been put together by Lea Verou&lt;/a&gt;, which is a contextual &amp;quot;private&amp;quot; Custom Property on the component itself but set to a &amp;quot;public&amp;quot; Custom Property with a fallback.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:host&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--_n-divider-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-divider-color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-border&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;--_n-divider-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-divider-size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 1px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token selector&quot;&gt;.n-divider&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token property&quot;&gt;border-block-start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; solid &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--_n-divider-size&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--_n-divider-color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;/* ... */&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;The divider Web Component CSS with the contextual Custom Properties adjusted so that the internal CSS relies on a private Custom Property, which has been set to a public Custom Property with a fallback.&lt;/figcaption&gt; 
&lt;/figure&gt;
&lt;p&gt;Defining our contextual Custom Properties in this fashion means we can still do all the things we were doing before, such as inheriting global token values and reusing values throughout our component code; but the component will also gracefully inherit new definitions of that property on itself or any parent element.&lt;/p&gt;
&lt;figure&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;nord-divider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- ... --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;  &lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;nord-divider&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;--n-divider-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-status-danger&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class=&quot;token selector&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-space-s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-surface-raised&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token property&quot;&gt;--n-divider-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--n-color-status-success&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;figcaption&gt;The two dividers again but this time the divider can be recolored by adding the divider&#39;s contextual Custom Property to the section selector. The divider will inherit it, producing a cleaner and more flexible piece of code.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;While it may be argued that this method isn&#39;t truly &amp;quot;private&amp;quot; we still think this is a rather elegant solution to a problem we were worried about. When we have the opportunity, we&#39;ll be tackling this in our components so our development team has more control over component usage while still benefiting from the guardrails we have in place.&lt;/p&gt;
&lt;p&gt;I hope you found this insight into how we use Web Components with CSS Custom Properties useful. Let us know what you think and if you decide to use any of these methods in your own work, you can find me on Twitter &lt;a href=&quot;https://twitter.com/DavidDarnes?ref_src=twsrc%5Etfw&quot; rel=&quot;noopener&quot;&gt;@DavidDarnes&lt;/a&gt;. You can also find Nordhealth &lt;a href=&quot;https://twitter.com/nordhealthhq?lang=en&quot; rel=&quot;noopener&quot;&gt;@NordhealthHQ&lt;/a&gt; on Twitter, as well as the rest of my team, who have worked hard on bringing this design system together and executing the features mentioned in this article: &lt;a href=&quot;https://twitter.com/viljamis?lang=en&quot; rel=&quot;noopener&quot;&gt;@Viljamis&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/wickynilliams?lang=en&quot; rel=&quot;noopener&quot;&gt;@WickyNilliams&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/eric_habich&quot; rel=&quot;noopener&quot;&gt;@eric_habich&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hero image by &lt;a href=&quot;https://unsplash.com/@dancristianpaduret?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot; rel=&quot;noopener&quot;&gt;Dan Cristian Pădureț&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</content>
    <author>
      <name>David Darnes</name>
    </author>
  </entry>
</feed>
