Not Your Typical Horizontal Rules
Articles & Blogs

Not Your Typical Horizontal Rules

Mar 24, 2021

<p>The HTML <code>&lt;hr&gt;</code> element adds a horizontal rule (or line) wherever you place it. A horizontal rule is used to provide a visual break and divide content. Like other HTML elements, horizontal rules can be styled using CSS (and SVG). This means that they don’t have to look like boring, plain horizontal lines. You can get a little creative with them, adding a nice little personal touch to your content and designs.</p> <p><svg role="separator" style="display: block; max-width: 65%; margin: 4rem auto;" width="500px" height="32px" viewBox="0 0 794 51" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <polygon id="path-1" points="0.907103825 0 798.907104 0 798.907104 364 0.907103825 364"></polygon> </defs> <g id="Page-1" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd"> <g id="36257-O0KTX6" transform="translate(0.000000, -212.000000)"> <g id="Group" transform="translate(-4.907104, 171.000000)"> <g id="Group-70"> <mask id="mask-2" fill="white"> <use xlink:href="#path-1"></use> </mask> <g id="Clip-67"></g> <path d="M610.198586,77 C699.286076,77 783.215114,73.4231956 849.907104,64.0083772 L849.765531,63.0342269 C783.152303,72.4392054 699.257163,76.0169938 610.198586,76.0160098 C468.900459,76.0169938 314.600519,67.0124993 195.629099,58.0080049 C136.142392,53.5062497 85.4880646,49.0035105 49.7059121,45.62744 C31.8148358,43.9389128 17.6415541,42.5318068 7.94178925,41.5478166 C3.09140831,41.0548375 -0.640344182,40.6681294 -3.15975068,40.40442 C-5.67816019,40.1407106 -6.98023573,40 -6.98422371,40 L-7.09289617,40.9780863 C-7.08292622,40.9790703 327.520578,77 610.198586,77 Z" id="Fill-68" fill="var(--hr-color)" mask="url(#mask-2)"></path> </g> <path d="M204.690104,47.32 C206.259104,42.729 211.015104,44.247 211.564104,45.397 C212.744104,47.867 213.564104,47.459 213.564104,47.459 C213.564104,47.459 211.475104,47.412 210.596104,49.717 C210.211104,50.727 208.816104,56.337 204.832104,58.949 C202.997104,60.153 200.700104,60.071 198.966104,61.194 C197.487104,62.163 196.569104,65.733 194.477104,65.784 C194.528104,65.733 194.579104,65.58 194.630104,65.479 C194.069104,65.835 193.355104,65.632 192.743104,65.632 C192.845104,65.376 192.590104,65.58 192.743104,65.325 C192.641104,65.428 192.641104,65.172 192.539104,65.223 C192.488104,64.764 192.284104,64.458 192.590104,64.101 C192.437104,64.254 192.590104,64.101 192.437104,64.203 C192.131104,63.285 196.633104,60.39 197.092104,57.891 C198.220104,51.746 202.522104,48.379 204.690104,47.32" id="Fill-73" fill="var(--hr-color)"></path> <path d="M237.461104,48.48 C240.188104,44.985 244.713104,48.584 244.314104,51.397 C248.502104,52.923 251.137104,63.152 251.621104,65.056 C251.621104,65.056 254.867104,70.497 254.733104,74.267 C254.250104,72.998 254.242104,74.368 253.553104,73.169 C253.483104,73.311 252.586104,72.323 252.517104,72.464 C251.439104,71.459 250.904104,67.897 250.103104,67.455 C249.301104,67.012 244.307104,65.92 241.012104,62.94 C237.824104,60.056 237.482104,56.195 237.693104,54.727 C238.377104,49.959 234.689104,50.147 234.689104,50.147 C234.689104,50.147 236.502104,49.709 237.461104,48.48" id="Fill-79" fill="var(--hr-color)"></path> <path d="M490.329073,53.2234708 C489.681073,52.5704708 487.329073,50.5564708 485.450073,51.0884708 C483.536073,51.6304708 481.516073,54.0154708 481.624073,56.5644708 L481.662073,56.5564708 C481.662073,56.5564708 480.546073,57.4964708 480.276073,57.7454708 C479.575073,58.3664708 475.473073,63.1004708 474.745073,69.2234708 C474.510073,71.1834708 474.352073,73.7664708 474.662073,75.0564708 C474.972073,76.3454708 473.722073,78.5464708 473.020073,79.9774708 C472.696073,80.5984708 469.438073,84.9064708 471.702073,83.9734708 C470.907104,85.7234708 472.329073,85.1394708 472.329073,85.1394708 C472.329073,85.1394708 471.827073,86.6204708 472.662073,86.6204708 C473.001073,86.6204708 473.995073,85.1394708 473.995073,85.1394708 C473.995073,85.1394708 473.995073,87.9734708 475.238073,84.4414708 C476.071073,87.7754708 477.917073,79.0904708 478.528073,77.9324708 C479.140073,76.7754708 481.459073,75.7964708 483.265073,74.8634708 C485.072073,73.9324708 486.663073,71.7724708 487.632073,69.7204708 C489.035073,66.8614708 489.662073,64.4804708 489.662073,61.3064708 C489.662073,54.2234708 492.971073,53.9734708 492.971073,53.9734708 C492.971073,53.9734708 490.976073,53.8764708 490.329073,53.2234708" id="Fill-87" fill="var(--hr-color)"></path> <path d="M177.695104,46.218 C179.252104,47.12 180.579104,51.973 180.214104,56.075 C179.708104,61.772 180.593104,64.226 180.581104,64.709 C180.567104,64.962 180.224104,63.94 180.126104,64.119 C180.028104,64.3 179.377104,66.022 179.377104,66.022 C178.314104,65.897 177.788104,64.477 177.788104,64.477 C177.788104,64.477 177.614104,65.198 177.439104,65.022 C176.716104,64.271 177.416104,61.669 177.165104,60.689 C176.433104,57.829 174.939104,58.128 173.502104,55.834 C171.625104,52.839 171.708104,49.822 172.127104,48.584 C172.433104,47.644 172.922104,46.91 172.226104,45.906 C171.746104,45.206 171.072104,45.652 170.403104,45.709 C170.714104,45.484 171.124104,45.445 171.434104,45.219 C171.788104,44.971 175.734104,39.39 177.695104,46.218" id="Fill-90" fill="var(--hr-color)"></path> <path d="M422.710104,55.938 C422.537104,55.574 421.710104,50.668 417.874104,51.317 C415.392104,51.738 413.710104,53.668 414.627104,57.084 C414.271104,59.936 412.264104,61.525 413.761104,67.05 C415.427104,73.204 419.112104,76.736 419.257104,78.691 C419.356104,80.243 419.127104,86.627 419.127104,86.627 C419.236104,86.528 420.370104,85.727 420.478104,85.628 C420.696104,85.909 420.845104,86.237 421.127104,86.501 C421.153104,86.355 421.604104,86.239 421.632104,86.093 C422.013104,86.465 422.516104,87.242 423.070104,87.497 C423.089104,87.079 423.173104,86.461 423.354104,86.134 C423.363104,86.406 424.202104,87.052 424.257104,87.243 C424.202104,87.052 424.678104,86.266 424.824104,85.33 C425.142104,85.72 426.640104,85.572 426.877104,85.918 C424.794104,82.584 424.141104,77.345 424.120104,75.908 C424.019104,72.43 426.519104,69.102 426.492104,65.673 C426.454104,60.903 422.710104,55.938 422.710104,55.938" id="Fill-98" fill="var(--hr-color)"></path> <path d="M302.845104,52.885 C302.750104,52.573 302.523104,47.483 298.347104,48.334 C296.386104,48.734 295.575104,51.737 296.049104,53.353 C295.437104,55.595 294.345104,56.846 294.877104,61.459 C295.470104,66.599 298.846104,68.692 298.732104,70.277 C298.630104,71.533 298.642104,73.546 298.598104,74.85 L298.535104,75.183 C298.632104,75.116 298.744104,75.156 298.841104,75.089 C298.980104,75.342 299.019104,76.129 299.210104,76.376 C299.248104,76.262 299.903104,75.988 299.529104,75.487 C299.785104,75.832 300.989104,77.493 301.170104,77.254 C301.146104,77.474 301.582104,76.552 301.603104,76.712 C301.582104,76.552 301.681104,76.558 301.906104,75.826 C302.110104,76.178 302.440104,76.195 302.585104,76.501 C303.798104,75.019 302.642104,71.989 302.793104,70.834 C303.120104,68.033 304.624104,64.088 305.002104,61.334 C305.529104,57.506 302.845104,52.885 302.845104,52.885" id="Fill-99" fill="var(--hr-color)"></path> <path d="M542.099104,60.139 C541.980104,59.748 542.402104,54.385 537.377104,54.3367902 C534.210104,54.307 533.793104,57.501 533.210104,60.084 C532.422104,62.891 530.212104,63.731 530.877104,69.501 C531.616104,75.928 535.338104,80.463 535.187104,82.446 C535.052104,84.019 534.894104,88.962 535.018104,88.878 C535.195104,89.194 535.379104,89.576 535.622104,89.884 C535.671104,89.741 535.845104,89.516 535.894104,89.374 C536.220104,89.805 537.677104,91.884 537.908104,91.584 C537.877104,91.859 538.835104,90.146 539.124104,89.228 C539.384104,89.669 539.485104,89.668 539.670104,90.051 C541.222104,88.192 540.271104,82.86 540.467104,81.415 C540.893104,77.911 543.928104,73.925 544.419104,70.48 C545.104104,65.688 542.099104,60.139 542.099104,60.139" id="Fill-100" fill="var(--hr-color)"></path> </g> </g> </g> </svg></p> <p>If you’re a frequent reader of this blog, then you’ve most likely already seen what a horizontal rule looks like on here. In fact, if you haven’t seen it before, then you might have <em>just</em> done that. The birds-on-a-wire illustration above this very paragraph is a styled <code>&lt;hr&gt;</code> element.</p> <div class="reader-mode-only"> <p class="reader-mode-only"><em>If you're reading this article in a reading app or a Web browser's reader mode, then the above horizontal rule will not appear with my custom styles, and you'll just see a horizontal line. Here is a picture of what the horizontal rule looks like:</em></p> <figure><img src="https://www.sarasoueidan.com/assets/images/hr.png" alt="The horizontal rule style I am using on my Web site. It is a vector illustration of a few bird silhouettes standing on a curvey horizontal black wire." /></figure>

</div> <p>Prior to creating this horizontal rule style, my horizontal rules looked as boring as you could possibly imagine. Until one day, I looked at that boring line and imagined a bunch of birds sitting on it <small><em>(because, well, BIRDS!)</em></small>. And then it clicked! I got an SVG image of a bunch of birds (silhouettes) on a wire, modified it to look like I wanted it to, and used it to style my <code>&lt;hr&gt;</code> elements to look like what you can see above.</p> <p>In this post, I’ll go over how I did it, and how my horizontal rules can possibly be improved further, so that they adapt to various contexts, while remaining semantic and accessible.</p> <h2 id="semantics-and-accessibility" tabindex="-1">Semantics and accessibility</h2> <p>An HTML horizontal rule is, <strong>by definition, not just a visual divider.</strong> It has semantics and plays a meaningful role in the context of its surrounding content:</p> <blockquote> <p>The HTML <code>&lt;hr&gt;</code> element represents a paragraph-level thematic break, e.g. a scene change in a story, or a transition to another topic within a section of a reference book.</p> </blockquote> <p>The <code>hr</code> element has <a href="https://www.w3.org/TR/html-aria/#dfn-implicit-aria-semantics">an implicit role</a> of <code>separator</code>. As such, <code>&lt;hr&gt;</code> is understood and announced by screen readers. A <code>hr</code> is announced as “Horizontal Splitter” by VoiceOver on macOS. The <code>hr</code> is also displayed as a horizontal line by reading apps and reader modes, where your CSS is typically stripped out and HTML semantics are used to determine how an element is styled by the reading app.</p> <p>What’s interesting is that a horizontal rule has an implicit orientation which is <code>horizontal</code> by default. This means that if you’re using <em>vertical</em> rules to split content, you can inform screen readers that the rule is vertical by setting the <code>aria-orientation</code> attribute value to <code>vertical</code>:</p> <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>hr</span> <span class="token attr-name">aria-orientation</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>vertical<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"><span class="token comment">&lt;!-- Note that you needn’t &amp; shouldn’t explicitly set role="separator" on the hr element because its semantics are implicit --></span></span></code></pre> <p>VoiceOver on macOS announces horizontal rules with a vertical orientation as “Vertical Splitter”.</p> <p>In addition to separating paragraphs in an article, horizontal rules can be used for separating groups of menu items in a menu, for example. They can also be interactive.</p> <p><strong>Further reading:</strong></p> <ul> <li><a href="https://www.w3.org/TR/wai-aria-1.1/#separator">ARIA spec for <code>separator</code></a></li> </ul> <p>Since horizontal rules are semantic elements announced by screen readers, then <strong>unless you’re using a horizontal rule to <em>semantically</em> divide content</strong>, you should hide it from screen readers using <code>aria-hidden=&quot;true&quot;</code>. In other words: use <code>aria-hidden=&quot;true&quot;</code> to hide decorational horizontal lines. Do <em>not</em> hide them if they are providing semantic, thematic content breaks.</p> <h2 id="styling-with-css" tabindex="-1">Styling with CSS</h2> <p>Like other empty HTML elements, the <code>&lt;hr&gt;</code> element can be limitedly styled using CSS. For example, you can change its width and height, border, and background color, as well as use gradients or apply a background image, etc. And even though it’s a content-less element, it seems that you can even create <a href="https://www.sarasoueidan.com/blog/horizontal-rules/(https://css-tricks.com/examples/hrs/)">simple <code>hr</code> styles</a> using <code>::before</code> and <code>::after</code> pseudo-elements, too.</p> <p>To create the birds-on-a-wire horizontal rules used on this site, all I did was set the dimensions of the <code>hr</code>, and apply the SVG image as a background image in CSS:</p> <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token selector">hr</span> <span class="token punctuation">{</span></span><br /><span class="highlight-line"> <span class="token property">width</span><span class="token punctuation">:</span> ..<span class="token punctuation">;</span></span><br /><span class="highlight-line"> <span class="token property">height</span><span class="token punctuation">:</span> ..<span class="token punctuation">;</span></span><br /><span class="highlight-line"> <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">"data:image/svg+xml,..."</span><span class="token punctuation">)</span></span><span class="token punctuation">;</span></span><br /><span class="highlight-line"> <span class="token property">background-repeat</span><span class="token punctuation">:</span> no-repeat<span class="token punctuation">;</span></span><br /><span class="highlight-line"> <span class="token property">background-size</span><span class="token punctuation">:</span> 100% auto<span class="token punctuation">;</span></span><br /><span class="highlight-line"> <span class="token comment">/* .. /</span></span><br /><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre> <p>There’s nothing too fancy going on in the CSS. But the above styles have irked me ever since I wrote them. Generally, I try to avoid using background images for anything that’s not purely decoration. And the horizontal rules, as mentioned earlier, are <em>not</em> pure decoration. I also prefer to avoid using SVGs as background images and tend to inline them whenever I can so that I can take full advantage of their stylability with CSS.</p> <p><strong>An SVG implemented as a background image cannot be styled from its containing (or referencing) stylesheet.</strong> I want the <code>hr</code> to be adaptive. I want to be able to customize it for different themes, and have the ability to modify and control its color(s) via CSS whenever I want. I also want to style it so that it remains accessible in user-controlled environments <small>(such as Windows High Contrast Mode, for example)</small>. And while I don’t plan on animating the horizontal rules on this blog, I’d still like to have the option to add a subtle animation should I ever want to. After all, SVGs are handy because they are so powerful and flexible—they’re about more than crisp lines and illustrations.</p> <p>To style the horizontal rule to match various themes, I could possibly change the background image on the <code>hr</code> for each theme. This would work. But if the images are inlined in the CSS, then I’ll end with a larger CSS file. And if they’re not inlined, I’ll end up with multiple requests to multiple images, which isn’t great for performance. Not to mention having to create and maintain multiple images, which is not the best workflow for something that could be simpler.</p> <p>Additionally, in Windows High Contrast Mode, we have no control over the active theme colors. So if I want to make sure the horizontal rule always has enough contrast with the background, then I’ll need to be able to change and control its colors in my CSS, which I can’t do if if the SVG is a background image. This means that I might end with a black horizontal rule on a black background, for example.</p> <p><small><em>(On the other hand, if you don’t really care about the horizontal rule’s styles in WHCM and you just want it to remain properly accessible, you could just strip away the background image and let WHCM style the <code>hr</code> the way it would do by default.)</em></small></p> <p>I could just use a background image on the <code>&lt;hr&gt;</code> and stop at that point. But if if I want the horizontal rule to be truly adaptive, then I need a little more flexibility that the <code>&lt;hr&gt;</code> element itself doesn’t provide…</p> <h2 id="a-more-flexible-and-adaptive-implementation-with-inline-svg-and-aria" tabindex="-1">A more flexible and adaptive implementation with inline SVG and ARIA</h2> <p>The best way to get the full flexibility of an SVG is by inlining it. But the <code>&lt;hr&gt;</code> element is content-less — it has no opening and closing tags within which you can place other elements.</p> <p>The only way to work around the limitations of <code>&lt;hr&gt;</code> while preserving semantics for screen reader users is to use a <code>div</code> and provide the semantics of an <code>hr</code> using ARIA. Yes, I am cringing at the idea as I type this. But hear me out. I think it’s worth exploring and going down this road if you want to get creative with your horizontal rules while also making sure they remain visually accessible and customizable in various contexts and environments.</p> <p>The alternative approach to creating flexible horizontal rules would essentially look like this:</p> <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">role</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>separator<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> <span class="token comment">&lt;!-- hide the SVG from screen readers to avoid them announcing it --></span></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">aria-hidden</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token attr-name">focusable</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>...<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>...<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>...<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> <span class="token comment">&lt;!-- svg content --></span></span><br /><span class="highlight-line"> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span></span></code></pre> <p>Or, as my friend <a href="https://scottohara.me/">Scott</a> pointed out, the <code>separator</code> role could be directly applied to the <code>svg</code>, in which case there’s no need to hide the SVG with <code>aria-hidden</code> anymore:</p> <pre class="language-html"><code class="language-html"><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">role</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>separator<span class="token punctuation">"</span></span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>794px<span class="token punctuation">"</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>51px<span class="token punctuation">"</span></span> <span class="token attr-name">viewBox</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0 0 794 51<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xlink</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://www.w3.org/1999/xlink<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></span><br /><span class="highlight-line"> <span class="token comment">&lt;!-- svg content --></span></span><br /><span class="highlight-line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">></span></span></span></code></pre> <p>Using the above markup:</p> <ul> <li>we create a semantic horizontal rule that is understood and properly announced by screen readers, and</li> <li>the illustration, being an inline SVG now, becomes easier to style and control with CSS.</li> </ul> <p>For convenience, the above horizontal rule markup could be wrapped in a custom component, or separated into a template partial or a shortcode, so that it can be more efficiently inserted where a <code>&lt;hr&gt;</code> would otherwise go.</p> <p>With the SVG inlined, I can use CSS custom properties to control what the SVG looks like in different contexts. For example, with <a href="https://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/">CSS custom properties sprinkled inside the SVG</a>, I could then control that content using CSS, modifying and changing its colors. For example, in Windows High Contrast Mode, I could set the color of the SVG to whatever is the current text color:</p> <pre class="language-css"><code class="language-css"><span class="highlight-line"><span class="token comment">/ IE and Legacy Edge /</span></span><br /><span class="highlight-line"><span class="token atrule"><span class="token rule">@media</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">-ms-high-contrast</span><span class="token punctuation">:</span> active<span class="token punctuation">)</span></span> <span class="token punctuation">{</span></span><br /><span class="highlight-line"> <span class="token selector">div[role="separator"] svg</span> <span class="token punctuation">{</span></span><br /><span class="highlight-line"> <span class="token property">--hr-color</span><span class="token punctuation">:</span> windowText<span class="token punctuation">;</span></span><br /><span class="highlight-line"> <span class="token punctuation">}</span></span><br /><span class="highlight-line"><span class="token punctuation">}</span></span><br /><span class="highlight-line"><span class="token comment">/ Using the new standards for forced colors, currently supported in Chromium Edge */</span></span><br /><span class="highlight-line"><span class="token atrule"><span class="token rule">@media</span> screen <span class="token keyword">and</span> <span class="token punctuation">(</span><span class="token property">forced-colors</span><span class="token punctuation">:</span> active<span class="token punctuation">)</span></span> <span class="token punctuation">{</span></span><br /><span class="highlight-line"> <span class="token selector">div[role="separator"] svg</span> <span class="token punctuation">{</span></span><br /><span class="highlight-line"> <span class="token property">--hr-color</span><span class="token punctuation">:</span> CanvasText<span class="token punctuation">;</span></span><br /><span class="highlight-line"> <span class="token punctuation">}</span></span><br /><span class="highlight-line"><span class="token punctuation">}</span></span></code></pre> <p>That way, the horizontal rule will always have enough contrast with the background behind it.</p> <p>If the content of the SVG is multi-colored, you can define and set values for multiple variables in the same manner, thus creating different versions—or themes—of the horizontal rule for different contexts or environments.</p> <p><strong>Further reading:</strong></p> <ul> <li><a href="https://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/">Styling SVG <code>&lt;use&gt;</code> Content with CSS</a>, in which I elaborate more about theming SVG images using CSS custom properties</li> <li><a href="https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/">Styling for Windows high contrast with new standards for forced colors</a> <small>(Hat tip: <a href="https://twitter.com/aardrian/status/1375201979849408514?s=20">Adrian Roselli</a>)</small></li> </ul> <p>Using this technique:</p> <ul> <li>The horizontal rule is styleable and customizable using CSS.</li> <li>It can be animated with CSS and/or JavaScript.</li> <li>It will display like it is intended to (birds on a wire) even in environments where my CSS is stripped off, such as reading apps. Because the it is now an <em>image</em>, it will be displayed just the way it is, as opposed to an <code>&lt;hr&gt;</code> that would be displayed and styled by the reading app.</li> <li>Using the high contrast media query, it can be adapted to always remain accessible with whatever user theme is currently active.</li> </ul> <p>Here is a video of me changing the color of my birds-on-a-wire horizontal rule in realtime using Chrome devtools. This is made possible by using inline SVG and CSS custom properties to apply the color to the SVG content:</p> <figure> <div class="video"> <iframe src="https://player.vimeo.com/video/528984771?badge=0&amp;autopause=0&amp;playerid=0&amp;appid=58479" width="100%" height="auto" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen="" title="theming with inline SVG and CSS custom properties"></iframe> </div> </figure> <h2 id="closing-thoughts" tabindex="-1">Closing Thoughts</h2> <p>Just like using inline SVG for icons is the best practice to ensure the icons remain adaptive and accessible, SVG can similarly provide better resilience for horizontal rules when you want to get more creative with them. Whether or not you use this technique, it’s good to have in your knowledge base, just in case you ever need it.</p>

Jump to
Projectsbrowse
Peoplebrowse
Companiesbrowse
Saved
Editor
Autosaves as you type