<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jack</title>
    <description>The latest articles on Forem by Jack (@jackherizsmith).</description>
    <link>https://forem.com/jackherizsmith</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F420664%2Fbe16271c-a8b8-44ab-be06-3b3997d8a13f.jpeg</url>
      <title>Forem: Jack</title>
      <link>https://forem.com/jackherizsmith</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jackherizsmith"/>
    <language>en</language>
    <item>
      <title>Give your users some colour</title>
      <dc:creator>Jack</dc:creator>
      <pubDate>Tue, 13 Apr 2021 17:20:58 +0000</pubDate>
      <link>https://forem.com/jackherizsmith/give-your-users-some-colour-2po1</link>
      <guid>https://forem.com/jackherizsmith/give-your-users-some-colour-2po1</guid>
      <description>&lt;p&gt;This is a real quick one!&lt;/p&gt;

&lt;p&gt;If you have a project that involves users interacting with each other, like a chat app or something with profiles, it might be nice to assign them a colour. A bit like WhatsApp names. The challenge is how to make sure the same users always have the same colour as themselves, but within a wide range such that it's effectively random?&lt;/p&gt;

&lt;p&gt;You can use ASCII key codes and the modulo operator and combine with HSL for a quick solution that will always return a random, but identical, hue, thereby converting any string into colour.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Michael Jordan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// code is 771059910497101108327411111410097110&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nameHSL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`hsl(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 80%, 40%)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, you might prefer to use a UID or 'user created at' timestamp in case you have two Michael Jordans - this works for literally any string!&lt;/p&gt;

&lt;p&gt;For anyone wondering, MJ is this leafy green.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesfp1zwvvq2m09qvcoi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesfp1zwvvq2m09qvcoi5.png" alt="Screenshot 2021-04-13 at 18.14.15"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lovely.&lt;/p&gt;

</description>
      <category>css</category>
      <category>user</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Making a progress circle in React</title>
      <dc:creator>Jack</dc:creator>
      <pubDate>Sat, 06 Feb 2021 18:20:15 +0000</pubDate>
      <link>https://forem.com/jackherizsmith/making-a-progress-circle-in-react-3o65</link>
      <guid>https://forem.com/jackherizsmith/making-a-progress-circle-in-react-3o65</guid>
      <description>&lt;p&gt;When I need something simple that I don't know how to build quickly, it can be tempting to find a library for it. But what is actually going on inside any given library? And how do I make it do this specific thing, instead of the 20 other options this library comes packaged with? I think it can sometimes take longer to read the docs and find workarounds than to just build the thing from scratch, and then at the end it's lighter and easier to make adjustments.&lt;/p&gt;

&lt;p&gt;I recently wanted to make a progress circle / pie. It came out looking something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvfbgqwem54zv64cof0qs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvfbgqwem54zv64cof0qs.png" alt="complete progress circle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is how I did it in React. The aim of this article is for people to do things their own way rather than using a component someone else has built for them, so I'd love to know what you'd do differently or additionally in the comments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/chnHv7g2coez6ZEryb/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/chnHv7g2coez6ZEryb/giphy.gif" alt="ideas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SVGs
&lt;/h2&gt;

&lt;p&gt;I like SVGs a lot, they're awesome. They seem to have every attribute you could want and, unlike some CSS properties, they work on all main browsers. So actually we can do this whole thing without CSS. Since this is a dynamic component which will take a percentage value, we'll be using JavaScript to do all the calculations.&lt;/p&gt;

&lt;p&gt;We're going to make two circles, one (blue) on top of the other (light grey). We'll use SVG's stroke-dasharray, which sets the length of a dashed stroke, and stroke-dashoffset, which sets where it begins relative to its natural starting point.&lt;/p&gt;

&lt;p&gt;So the stroke dash length will be the circumference of the circle - &lt;code&gt;2 * pi * radius&lt;/code&gt; - and the offset which we need to change for the blue circle will be a percentage of that. When we want to visualise 85%, that stroke will have to start at 15% of whatever the circumference is, so that we can only see the remaining 85% of the line before the dash ends.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"transparent"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"lightgrey"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"2rem"&lt;/span&gt; &lt;span class="na"&gt;stroke-dasharray=&lt;/span&gt;&lt;span class="s"&gt;"439.8"&lt;/span&gt; &lt;span class="na"&gt;stroke-dashoffset=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/circle&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"transparent"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"2rem"&lt;/span&gt; &lt;span class="na"&gt;stroke-dasharray=&lt;/span&gt;&lt;span class="s"&gt;"439.8"&lt;/span&gt; &lt;span class="na"&gt;stroke-dashoffset=&lt;/span&gt;&lt;span class="s"&gt;"66"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/circle&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We're already off to a flying start, with some hard-coded values - in particular, the radius of &lt;code&gt;70&lt;/code&gt;, the circumference of &lt;code&gt;439.8&lt;/code&gt; and its "85%" bar starting at &lt;code&gt;66&lt;/code&gt;. If you try this yourself, you'll see we're 90 degrees clockwise of where we'd want to be, and also missing the text value that should sit neatly in the middle. So we can put the circles in a group to rotate it -90 degrees, and add some text.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;g&lt;/span&gt; &lt;span class="na"&gt;transform=&lt;/span&gt;&lt;span class="s"&gt;"rotate(-90 100 100)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"transparent"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"lightgrey"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"2rem"&lt;/span&gt; &lt;span class="na"&gt;stroke-dasharray=&lt;/span&gt;&lt;span class="s"&gt;"439.8"&lt;/span&gt; &lt;span class="na"&gt;stroke-dashoffset=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/circle&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"transparent"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"2rem"&lt;/span&gt; &lt;span class="na"&gt;stroke-dasharray=&lt;/span&gt;&lt;span class="s"&gt;"439.8"&lt;/span&gt; &lt;span class="na"&gt;stroke-dashoffset=&lt;/span&gt;&lt;span class="s"&gt;"66"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;/circle&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/g&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;text&lt;/span&gt; &lt;span class="na"&gt;x=&lt;/span&gt;&lt;span class="s"&gt;"50%"&lt;/span&gt; &lt;span class="na"&gt;y=&lt;/span&gt;&lt;span class="s"&gt;"50%"&lt;/span&gt; &lt;span class="na"&gt;dominant-baseline=&lt;/span&gt;&lt;span class="s"&gt;"central"&lt;/span&gt; &lt;span class="na"&gt;text-anchor=&lt;/span&gt;&lt;span class="s"&gt;"middle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;85%&lt;span class="nt"&gt;&amp;lt;/text&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There are some of those great SVG attributes I mentioned earlier - &lt;code&gt;dominant-baseline&lt;/code&gt; and &lt;code&gt;text-anchor&lt;/code&gt; helping us centre our text vertically and horizontally. Doing stuff like this in CSS can be a bit of a headache. When rotating SVGs we can also specify the centre of rotation - in this case its in the middle at &lt;code&gt;100 100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This actually already gives us the progress circle at the top of the article, so we're ready to move this to React.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it a component
&lt;/h2&gt;

&lt;p&gt;Using React gives us a lot of dynamic control over the values we're using. Let's take the percentage we want as an input, and the colour we want the progress to be.&lt;/p&gt;

&lt;p&gt;We'll start by 'cleaning' the input to make sure it's a number we can use, we can set up the SVG parts as re-useable components and then we're basically done.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cleanPercentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNegativeOrNaN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isFinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// we can set non-numbers to 0 here&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isTooHigh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isNegativeOrNaN&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;isTooHigh&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;circ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strokePct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;circ&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// where stroke will start, e.g. from 15% to 100%.&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;
      &lt;span class="na"&gt;r&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"transparent"&lt;/span&gt;
      &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;strokePct&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;circ&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;colour&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// remove colour as 0% sets full circumference&lt;/span&gt;
      &lt;span class="na"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;strokeDasharray&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;circ&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;strokeDashoffset&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;percentage&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;strokePct&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt;
      &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"50%"&lt;/span&gt;
      &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"50%"&lt;/span&gt;
      &lt;span class="na"&gt;dominantBaseline&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"central"&lt;/span&gt;
      &lt;span class="na"&gt;textAnchor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"middle"&lt;/span&gt;
      &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.5em&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;%
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Pie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;colour&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cleanPercentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt; &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`rotate(-90 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100 100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="na"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"lightgrey"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="na"&gt;colour&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;colour&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pct&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pct&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And actually this is just a starting point, since there are still hard-coded values - do we want to fix our radius to &lt;code&gt;70&lt;/code&gt;, or stroke width to &lt;code&gt;2rem&lt;/code&gt;, or circle size to &lt;code&gt;200&lt;/code&gt;? I think probably not, and now that's all in our control - I've left curly braces wherever I would continue to add dynamic values. At the moment the component takes just percentage and colour, but it could take stroke width, radius, rounded ends and so on.&lt;/p&gt;

&lt;p&gt;You can see the final code with some examples where I've added some more colours, rounded the ends using &lt;code&gt;stroke-linecap="round"&lt;/code&gt; below; I've also included a "Randomise" button so you can see it in action.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/heuristic-burnell-kttl5?module=/Pie.jsx"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
      <category>datavis</category>
    </item>
    <item>
      <title>Making a 'Back to Top' button without Javascript</title>
      <dc:creator>Jack</dc:creator>
      <pubDate>Sun, 11 Oct 2020 12:27:31 +0000</pubDate>
      <link>https://forem.com/jackherizsmith/making-a-back-to-top-button-without-javascript-2ej6</link>
      <guid>https://forem.com/jackherizsmith/making-a-back-to-top-button-without-javascript-2ej6</guid>
      <description>&lt;h1&gt;
  
  
  The 'back to top' button
&lt;/h1&gt;

&lt;p&gt;Here is my tutorial on making a 'back to top' button without JavaScript. Please also refer to &lt;a href="https://www.nngroup.com/articles/back-to-top/" rel="noopener noreferrer"&gt;these very helpful design guidelines&lt;/a&gt;. Do let me know in the comments if there is anything here I can be doing differently, especially if I've missed anything regarding accessibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;I recently built a portfolio site for a freelance journalist who required a lightweight portfolio site (which I did with &lt;a href="https://www.11ty.dev/" rel="noopener noreferrer"&gt;Eleventy&lt;/a&gt;), where she could host her articles and have visitors contact her.&lt;/p&gt;

&lt;p&gt;When I got to designing the full-length article page itself, I wanted to provide a button for readers to get back to the top since there is information that could be of interest after reading: a link to download the original article as a PDF, another to the online article, details like when it was written and so on.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement it?
&lt;/h2&gt;

&lt;p&gt;I asked Google how this could be done - I find it helpful to get different perspectives on solutions before diving into code. I was surprised to find that every answer involved using JavaScript / jQuery. Unless I'm missing something, most code concerning layout that &lt;em&gt;can&lt;/em&gt; be done with CSS, should be. JavaScript breaks more easily, requires more work by the browser and &lt;a href="https://www.wired.com/2015/11/i-turned-off-javascript-for-a-whole-week-and-it-was-glorious/" rel="noopener noreferrer"&gt;not all users run JavaScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1303268890638778368-524" src="https://platform.twitter.com/embed/Tweet.html?id=1303268890638778368"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1303268890638778368-524');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1303268890638778368&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;If you already know about CSS' &lt;code&gt;position&lt;/code&gt; property, skip to the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting into &lt;code&gt;position&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We need to understand the various CSS positions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;static&lt;/code&gt;: this is the default value for every element and is named only so that it can be referred to when describing what other positions do. A more helpful name might be &lt;code&gt;none&lt;/code&gt;. The only time you would ever need to use it would be to remove an element's &lt;code&gt;position&lt;/code&gt; that had been set elsewhere in a less specific &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax#CSS_declaration_blocks" rel="noopener noreferrer"&gt;declaration block&lt;/a&gt;, i.e. you never need to use it (just go and remove the &lt;code&gt;position&lt;/code&gt; property from that other block). Think of &lt;code&gt;static&lt;/code&gt; as 'unpositioned', in that it just happens to be where it ends up on the page. This is very useful, because you want most of your elements to 'end up' where you'd expect... it's just that you don't need to apply this property in order for that to happen. As far as I know, this is the most anyone has ever written about the &lt;code&gt;static&lt;/code&gt; position.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;relative&lt;/code&gt;: this establishes the element on the page, &lt;em&gt;relative&lt;/em&gt; to where you'd expect it to be (its &lt;code&gt;static&lt;/code&gt; position). If you add &lt;code&gt;left: 20px;&lt;/code&gt; it will move 20px from the left edge of where you'd expect it to be. If you make an element &lt;code&gt;relative&lt;/code&gt; without also changing its position, it might look like nothing has happened but your CSS now knows it is there on purpose (unlike an 'unpositioned' &lt;code&gt;static&lt;/code&gt; element), and so it can now be used as a reference for any child elements.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;absolute&lt;/code&gt;: an &lt;code&gt;absolute&lt;/code&gt; positioned element will go anywhere on the page relative to its closest parent that isn't &lt;code&gt;static&lt;/code&gt;, or &lt;code&gt;body&lt;/code&gt; if it doesn't have one. With &lt;code&gt;top: 0;&lt;/code&gt; this will line up the top of the &lt;code&gt;absolute&lt;/code&gt; element with the top of its closest positioned parent.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fixed&lt;/code&gt;: sets the position of an element relative to the window rather than anything on the page - the Dev.to navbar that you can see at the top is &lt;code&gt;fixed&lt;/code&gt;, for example, so it scrolls &lt;em&gt;with your screen&lt;/em&gt; not with the page (unless you've changed this default in your settings).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sticky&lt;/code&gt;: this toggles between &lt;code&gt;relative&lt;/code&gt; and &lt;code&gt;fixed&lt;/code&gt;. It will behave like a &lt;code&gt;relative&lt;/code&gt; element until it gets to its &lt;code&gt;sticky&lt;/code&gt; position, and stays &lt;code&gt;fixed&lt;/code&gt; there until its containing element no longer accommodates its position and it toggles back again. This CSS &lt;code&gt;position&lt;/code&gt; has been around since 2013 and is up to 95% global usage when using the -webkit- prefix according to &lt;a href="https://caniuse.com/?search=sticky" rel="noopener noreferrer"&gt;caniuse&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;So, we're going to make a &lt;code&gt;relative&lt;/code&gt; page (&lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;) with an &lt;code&gt;absolute&lt;/code&gt; scrollbar (&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;) that contains a &lt;code&gt;sticky&lt;/code&gt; button (er, the 'button' is in fact an anchor element, since it navigates rather than triggering an event.. so let's call it a link from now on: &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;We won't want to navigate 'back to top' whilst we're already there, so the scrollbar should begin below where the screen loads, i.e. at least 100% of the viewport height from the top of &lt;code&gt;main&lt;/code&gt;. Once we do see the link, we want it to stay in the bottom right, because that's where users expect to find it. Let's say there's a &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt; at the end of the page, and we want to prevent the link scrolling to the bottom of &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, so the scroll bar will also be offset from the bottom.&lt;/p&gt;

&lt;p&gt;Here is the most basic implementation of the 'back to top' link without using any JavaScript:&lt;/p&gt;

&lt;h3&gt;
  
  
  The HTML
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;&lt;br&gt;
    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;Words&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--your page content--&amp;gt;&lt;/span&gt;&lt;br&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"scroll-top"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--scrollbar at the end of main--&amp;gt;&lt;/span&gt;&lt;br&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"scroll-top__link"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Back to top&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!--href="#" navigates to the top of the page--&amp;gt;&lt;/span&gt;&lt;br&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;Footer&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;&lt;br&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  The CSS&lt;br&gt;
&lt;/h3&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt; &lt;span class="c"&gt;/* to place scrollbar &lt;em&gt;/&lt;/em&gt;&lt;/span&gt;&lt;br&gt;
&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300vh&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt; &lt;span class="c"&gt;/ so we can scroll &lt;em&gt;/&lt;/em&gt;&lt;/span&gt;&lt;br&gt;
&lt;span class="nt"&gt;footer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5rem&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt; &lt;span class="c"&gt;/ a typical footer height */&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nc"&gt;.scroll-top&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* relative to its positioned &amp;lt;main&amp;gt; parent &lt;em&gt;/&lt;/em&gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/ starts below the bottom of the screen &lt;em&gt;/&lt;/em&gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/ stops scrolling before the end &lt;em&gt;/&lt;/em&gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/ offset from right hand side */&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="nc"&gt;.scroll-top__link&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-webkit-sticky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* for Safari &lt;em&gt;/&lt;/em&gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sticky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/ 'relative' until element reaches... &lt;em&gt;/&lt;/em&gt;&lt;/span&gt;&lt;br&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;90vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/ 90% viewport height from the top, when it becomes 'fixed' - until its container toggles it back to 'relative' */&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  The JavaScript&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;¯\_(ツ)_/¯&lt;/p&gt;

&lt;h2&gt;
  
  
  The final product
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1rrsiqwgd9esolcwvbkq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1rrsiqwgd9esolcwvbkq.gif" alt="basic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I included an outline on all the elements so you can see how &lt;code&gt;position&lt;/code&gt; is coming into play.&lt;/p&gt;

&lt;p&gt;Let's add lots of text to our &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; so we don't have to give it an arbitrary height, and introduce smooth scrolling, colour, hover opacity and some padding in our CSS. Here's what that looks like in practice:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jackherizsmith/embed/oNxVWrK?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;So there it is, all you need to make a 'back to top' link without any JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;edit&lt;/strong&gt;: &lt;code&gt;href="#"&lt;/code&gt; in an anchor tag tells the browser to scroll to the top of the page without adding to the history, so this shouldn't affect user navigation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;much later edit&lt;/strong&gt;: the &lt;code&gt;div&lt;/code&gt; / invisible scroll bar obviously sits on top of the page, so anything underneath it is unclickable. This is a problem for links in text underneath the path of the button.&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>tutorial</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
