<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>SMTH</title>
	<subtitle>Articles by Sam Smith.</subtitle>
	<link href="https://smth.uk/feed/articles.xml" rel="self"/>
	<link href="https://smth.uk/"/>
	<updated>2024-09-29T00:00:00Z</updated>
	<id>https://smth.uk/</id>
	<author>
		<name>Sam Smith</name>
	</author>
	
	<entry>
		<title>Rebuilding a twenty year old website</title>
		<link href="https://smth.uk/rebuilding-a-twenty-year-old-website/"/>
		<updated>2024-09-29T00:00:00Z</updated>
		<id>https://smth.uk/rebuilding-a-twenty-year-old-website/</id>
		<content type="html">&lt;p&gt;It was 2004; Myspace was the hot social media platform, Lost was the TV show everyone was talking about, and the UK Government was mailing out a booklet called &amp;quot;Preparing for Emergencies&amp;quot;. This was a twenty-odd page, A5 (landscape) booklet, with an incongruent visual identity. It contained some reassurances and advice for what to do in a some broad categories of future emergency. It felt silly at the time but in hindsight it feels like a bit of a dream to have a government that takes potential threats to its citizens seriously. Anyway, it was very easy to make fun of, and I needed little excuse back then to make fun of the government or to make a new website. So &amp;quot;&lt;a href=&quot;https://preparingforzombies.zmbi.uk/&quot;&gt;Preparing for Zombies&lt;/a&gt;&amp;quot; was born. Before you click that, two disclaimers: 1) It&#39;s dumb, don&#39;t bother reading it. 2) that&#39;s not, strictly speaking, the website I made in 2004.&lt;/p&gt;
&lt;p&gt;The Preparing for Zombies site had been offline for a while, I would occasionally think &amp;quot;I should put that live somewhere&amp;quot;. When it occurred to me that the site was twenty years old it felt like an opportunity to do something a little more interesting. So I decided to rebuild the site, using 2024 tools and practices, and document what I do differently. The brief I gave myself was to recreate the original website, making changes only when I saw opportunities for improvement, afforded by modern practices. The copy would remain as it was. The spirit of the design would remain, but would inevitably be shaped by the radically different devices we now use to consume websites.&lt;/p&gt;
&lt;h2 id=&quot;tooling&quot;&gt;Tooling &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#tooling&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We don&#39;t do much these days before thinking about what tools we are going to use, so that seems like a good place to start. This being a static site, there&#39;s not really any need for a &amp;quot;backend&amp;quot; - a database or server side language. That was true in 2004 as it is now, but one reason I might have opted for a language like PHP would have been includes. Ever since we stopped using &lt;code&gt;&amp;lt;frameset&amp;gt;&lt;/code&gt; to layout web pages we have been faced with the question of how to do includes. For example, navigation that needs to appear on every page. It appears my 2004 solution to this was Dreamweaver.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/75223dc2-521.webp&quot; alt=&quot;Screenshot of Dreamweaver, showing options for designer and coder layouts&quot; width=&quot;521&quot; height=&quot;380&quot; loading=&quot;lazy&quot; /&gt;
&lt;p&gt;In 2004 Dreamweaver was an integrated development environment (IDE) developed by Macromedia. The following year Macromedia was acquired by Adobe, who still sells Dreamweaver today; though I have no idea how the software has changed. Back in 2004 at least, Dreamweaver attempted to offer &lt;a href=&quot;https://en.wikipedia.org/wiki/WYSIWYG&quot;&gt;WYSIWYG&lt;/a&gt; capabilities, writing code for you. It wrote notoriously bad code, and the very idea of machines writing HTML was widely ridiculed for years to come. Today though, with tools like Figma Dev Mode, and Microsoft&#39;s Copilot that idea seems to be back in favour (hopefully with some lessons having been learnt). I don&#39;t think I let Dreamweaver write my code in 2004, but it did give me HTML includes. I only had the compiled HTML (.htm files!), but in there were comments like &lt;code&gt;&amp;lt;!-- #BeginLibraryItem &amp;quot;/Library/menu.lbi&amp;quot; --&amp;gt;&lt;/code&gt;. I don&#39;t really remember this Library Item feature, but &lt;a href=&quot;https://helpx.adobe.com/dreamweaver/using/library-items.html&quot;&gt;apparently it&#39;s still a thing&lt;/a&gt;.  Today my solution is to use some sort of templating language, usually something like Nunjucks, or other Mustache-like language. The build step is not carried out by my code editor (VS Code) in 2024; in this case I have used &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;, the current hotness in static site generation.&lt;/p&gt;
&lt;h2 id=&quot;semantic-html&quot;&gt;Semantic HTML &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#semantic-html&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While it&#39;s easy to criticise Dreamweaver for writing bad code, us humans can be guilty of it too. This rebuild is not the second, but third iteration of the Preparing for Zombies website. The second iteration would have been made a couple of years after the first, when &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/float&quot;&gt;floats&lt;/a&gt; were added to CSS. Floats were the first tool in CSS to allow us to do anything resembling layout; in 2004 standard practice for controlling layout was to put everything inside &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;s. As much as I&#39;d like to pretend that second iteration was the only one, if we&#39;re talking 2004 I have to acknowledge the table layout.&lt;/p&gt;
&lt;p&gt;Related to HTML semantics is the introduction of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA&quot;&gt;ARIA&lt;/a&gt;. ARIA can be useful when you start to roll your own non-standard bits of interface, such as in this case where I&#39;ve &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement&quot;&gt;progressively enhanced&lt;/a&gt; the main navigation to behave like a modal.&lt;/p&gt;
&lt;h2 id=&quot;javascript&quot;&gt;Javascript &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#javascript&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As I&#39;ve touched upon it let&#39;s talk a little about Javascript (JS). JS has moved relatively quickly over the past twenty year, but Preparing for Zombies being a content focused site there was no JS in the original. One take would be that the 2024 iteration should be stuffed with JS. I haven&#39;t done that. I think it would be fair to consider it a downgrade if the new site required Javascript to do what the old one did without it. As mentioned though I have added a few bits of JS to smooth out the some experiences. The aforementioned navigation modal has JS to manage focus, moving it and making parts of the page &lt;code&gt;inert&lt;/code&gt; to trap it. There&#39;s also Astro&#39;s implementation of View Transitions, which were useful to make the audio player persist (keep playing) across page loads. That audio player also has custom controls, requiring Javascript. What&#39;s interesting here from a &amp;quot;what&#39;s new?&amp;quot; point of view is the use of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components&quot;&gt;Web Components&lt;/a&gt;, or more specifically &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements&quot;&gt;custom elements&lt;/a&gt;. I made three custom elements as part of this rebuild: &lt;code&gt;&amp;lt;audio-player&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;contents-modal&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;open-menu&amp;gt;&lt;/code&gt; (my naming could have been better here, &amp;quot;contents&amp;quot; and &amp;quot;menu&amp;quot; referring to the same thing). Web Components are not giving me any new functionality, but I find them to be a nice design pattern for creating discrete bits of interface like these. To give an example of what one of these components does, &lt;code&gt;&amp;lt;open-menu&amp;gt;&lt;/code&gt; takes the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; that&#39;s inside it, converts it to a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, and adds an event listener to it.&lt;/p&gt;
&lt;h2 id=&quot;small-screens&quot;&gt;Small screens &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#small-screens&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Perhaps the most obvious change to the frontend of websites is the range of devices we use to visit them. The 2004 site didn&#39;t care much about the size of your screen. We didn&#39;t have smart phones then, assumed everyone&#39;s screen was more or less the same size, and picked a number of pixels that we were fairly confident would fit on everyones screen. &lt;em&gt;Responsive web design (RWD)&lt;/em&gt; is now ubiquitous, but Ethan Marcotte wouldn&#39;t coin that term for another six years. The 2024 iteration obviously needed to be brought up to date in this respect. Almost all the visual changes I made derive from the idea of design responding to the characteristics of the device. From the use of relative &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units&quot;&gt;units&lt;/a&gt; instead of absolute, to putting the navigation in an off-canvas menu. One of the first tools we had for responsive web pages was media queries, they were almost synonymous with RWD. While those remain in heavy use today, and indeed have been introduced to this rebuild, they can be a blunt tool, and are becoming less and less &lt;em&gt;the&lt;/em&gt; answer to the responsive question. The CSS layout properties that have followed float have been designed with adapting to screen size in mind. In 2024 I&#39;m spoilt for choice, making use of CSS columns, viewport units, min() and max() functions, flex, grid. Whether we call this &lt;em&gt;responsive&lt;/em&gt; or &lt;a href=&quot;https://zeldman.com/2018/05/02/transcript-intrinsic-web-design-with-jen-simmons-the-big-web-show/&quot;&gt;&lt;em&gt;intrinsic&lt;/em&gt;&lt;/a&gt; web design, all of these techniques are working together to adapt to the available space. In this case I &lt;em&gt;mostly&lt;/em&gt; took the approach of scaling everything with the viewport, which feels like a spiritual successor to the fixed layouts of twenty years ago.&lt;/p&gt;
&lt;h2 id=&quot;css&quot;&gt;CSS &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#css&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So how different was the CSS? One thing that jumps out when looking at the old CSS is the browser hacks. Thankfully we find ourselves in a good spot in 2024, where we don&#39;t have to concern ourselves with browser specific CSS. In my 2004 CSS however there were a few hacks, some targeting IE generally some targeting specific versions IE 5 and IE 6. Aside from the weird syntax used in the hacks, the old CSS looks very recognisable as CSS you&#39;d see today. I would say that the specificity is a little all over the place for my current taste. Sometimes targeting elements, sometimes classes, sometimes IDs. For this little dumb site, that wouldn&#39;t matter, but for my 2024 iteration I&#39;m following my &lt;a href=&quot;https://c3css.com/&quot;&gt;C3CSS methodology&lt;/a&gt;. Even that feels dated in 2024, such methodologies become much less useful with the introduction of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@scope&quot;&gt;@scope&lt;/a&gt;. Amongst the biggest changes would be those I just mentioned, the responsive layout stuff, but those are certainly not the only game changers.&lt;/p&gt;
&lt;p&gt;Another change that had big impact on how websites look was the rise of &lt;code&gt;@font-face&lt;/code&gt;. This rule had been around for a long time, but wasn&#39;t typically used in 2004 due to amongst &lt;a href=&quot;https://thehistoryoftheweb.com/web-fonts/&quot;&gt;other things&lt;/a&gt; it not being supported by FireFox. In 2004 the choice of typefaces was really limited to so called &amp;quot;web safe fonts&amp;quot; - fonts thought to be universally installed across all devices. I think at the time those were widely considered to be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Arial (sans-serif)&lt;/li&gt;
&lt;li&gt;Verdana (sans-serif)&lt;/li&gt;
&lt;li&gt;Tahoma (sans-serif)&lt;/li&gt;
&lt;li&gt;Trebuchet (sans-serif)&lt;/li&gt;
&lt;li&gt;Times New Roman (serif)&lt;/li&gt;
&lt;li&gt;Georgia (serif)&lt;/li&gt;
&lt;li&gt;Garamond (serif)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Images aside, these were considered the de facto choices for web design. The 2004 Preparing for Zombies used Verdana throughout. You could argue there was no reason to change that for this rebuild, but I would counter that being deliberate about typography is fundamental to web design in 2024. That being said, I have replaced Verdana with everyones goto font &lt;a href=&quot;https://www.indiantypefoundry.com/fonts/poppins&quot;&gt;Poppins&lt;/a&gt;. In my defence I don&#39;t think I&#39;ve ever used this typeface in a design before, so I&#39;m clinging on to my assertion that this is a deliberate design choice (I feel it has similar characteristics to the wider visual language, in particular it&#39;s very circular forms relate well to the circles that appear throughout the design).&lt;/p&gt;
&lt;p&gt;A CSS property that has been added since 2004 and made a big difference to this rebuild was the humble &lt;code&gt;border-radius&lt;/code&gt;. We got this in FireFox a couple of years after the first build, and it wasn&#39;t supported by IE until IE9 in 2011. There are a lot of rounded corners in this design, they all needed to be images in 2004. The &lt;a href=&quot;https://preparingforzombies.zmbi.uk/emergency-planning/&quot;&gt;quote portraits&lt;/a&gt; have gone from being pre-rounded in Photoshop, with border baked in, to a simple square headshot with CSS border. Where &lt;code&gt;border-radius&lt;/code&gt; really became a hero though was the rounded corner box, such as these &lt;a href=&quot;https://preparingforzombies.zmbi.uk/basic-first-aid-continued/&quot;&gt;call-out boxes&lt;/a&gt;. Each of those corners was a separate image, a technique typical of the time.&lt;/p&gt;
&lt;figure class=&quot;image-group&quot;&gt;
  &lt;figcaption class=&quot;image-group_caption&quot;&gt;Still from video &lt;a href=&quot;https://css-tricks.com/videos/24-rounded-corners/&quot;&gt;Rounded Corners&lt;/a&gt;, by Chris Coyier&lt;/figcaption&gt;
  &lt;img src=&quot;https://smth.uk/img/d0f8999e-1152.webp&quot; alt=&quot;Screenshot of a rounded corner being made in Photoshop&quot; width=&quot;1152&quot; height=&quot;864&quot; loading=&quot;lazy&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;So much has changed in CSS in the last twenty year, but I&#39;ll just mention two more additions. First, the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements&quot;&gt;pseudo-elements&lt;/a&gt;. Similar to the introduction of floats, these pseudo-elements felt like a turning point, away from the hacky ways of the past, towards a future were we might be able to have HTML based on the content &lt;em&gt;and&lt;/em&gt; have control over the design at the same time. In this case I&#39;ve used them (in combination with &lt;code&gt;border-radius&lt;/code&gt;) to do a task that now seems trivial, styling &lt;a href=&quot;https://preparingforzombies.zmbi.uk/general-advice/&quot;&gt;list markers&lt;/a&gt;. This very simple example demonstrates how far we&#39;ve come. In 2004 a list item with a custom marker meant putting the text and an image in table cells. And lastly, I couldn&#39;t talk about CSS developments without mentioning perhaps my favourite, the much more recent &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:has&quot;&gt;&lt;code&gt;:has()&lt;/code&gt;&lt;/a&gt;. I&#39;ve talked about some more &lt;a href=&quot;https://smth.uk/contextual-styling-with-:has/&quot;&gt;interesting examples&lt;/a&gt; in the past, but in this rebuild I used the &lt;code&gt;:has()&lt;/code&gt; selector for one small enhancement, to control what happens to &lt;a href=&quot;https://preparingforzombies.zmbi.uk/coping/&quot;&gt;items in an accordion&lt;/a&gt;, when one of them is opened (spoiler: they just disappear).&lt;/p&gt;
&lt;h2 id=&quot;audio-%2F-video&quot;&gt;Audio / video &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#audio-%2F-video&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As you may have seen, the accordion I just mentioned contains videos. The original site didn&#39;t have videos. Not only did we not have the &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; element that makes this possible, we didn&#39;t even have Youtube in 2004. That&#39;s why it didn&#39;t feel strange that instead of videos you could play, this section of the original site contained links to somewhere you could buy physical copies of the films. Similarly, in 2004 the site had another page with links to zombie themed music you could buy from iTunes. In the age of music streaming that would feel weird, so I replaced that page with an &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; player, added to the site navigation. The addition of the &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; elements to HTML makes adding this media simple, though when you want to customise the UI you are somewhat on your own.&lt;/p&gt;
&lt;h2 id=&quot;images&quot;&gt;Images &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#images&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is another form of media we need to discuss - images. All the images in the original build were GIFs. JPGs and PNGs I think were more typical though. I&#39;m not sure if it was my knowledge or the available tools that were lacking in 2004, but at least with the the tools I was using GIFs sometimes had an advantage over JPGs and PNGs, they could have transparent backgrounds (sort of) while having a reasonably small file size. I would have been using Photoshop back then, and exporting transparent PNGs with it&#39;s &amp;quot;Save for web&amp;quot; feature could result in huge files. It wasn&#39;t until later that I learned of &lt;a href=&quot;https://pngquant.org/&quot;&gt;pngquant&lt;/a&gt; and the tools built on it, including a Photoshop plugin and standalone applications. These tools allowed us to get PNGs down to sizes suitable for web use, and relieved me of my relationship with GIFs. We were also not using SVG in 2004. While SVG existed, and was in the web spec, I don&#39;t think it was in any browsers, certainly not Internet Explorer. The landscape has shifted quite a bit in the last twenty years. In this update I have used SVG for some graphical elements, such as the logo. For the raster images we now of course have better options, such as WebP and more recently AVIF. Swapping the images out for WebP has meant that they can be higher resolution and transparent where required without becoming prohibitively large in file size. It&#39;s worth noting that the largest of these new images (up to 180kb) are still much heavier than I would have contemplated using in 2004, but higher resolution screens and improvements in bandwidth have raised the bar.&lt;/p&gt;
&lt;h2 id=&quot;generative-ai&quot;&gt;Generative AI &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#generative-ai&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This feels like I&#39;m about to introduce myself at group therapy.. I used generative AI in the production of the raster images. I&#39;m no fan of the current wave of AI. There are obvious concerns in terms of plagiarism, carbon footprint, and in the case of text generation e.g ChatGPT, an alarming tendency to treat the output as a source of truth or knowledge. That combined with &amp;quot;AI&amp;quot; being stuffed into every piece of software for apparently no reason other than hype has turned me off ChatGPT before even trying it. Image generation on the other hand has retained my interest. I think that&#39;s probably largely because I see these tools as potential creative aids (generating works of fiction), and my creative practice is all visual. So a tool that helps produce an illustration is going to be more appealing to me than a tool that writes stories. While being far from sure about how I felt about this technology, this project felt like an opportunity to try it in earnest. It certainly felt like the 2024 thing to do. All the zombie images were generated using &lt;a href=&quot;https://en.wikipedia.org/wiki/Stable_Diffusion&quot;&gt;Stable Diffusion&lt;/a&gt;. I installed and ran this locally, so according to my energy provider the electricity used came from renewable sources. My experience of working with this process was hit and miss. I found that I would get a lot of pretty rubbish looking images then the occasional exceptionally impressive image would materialise. Or at least one part of an image being exceptionally impressive. Curiously, I noticed that if you gather the exceptional images together they would often look very similar to each other, to the extent that you can recognise reoccurring details and even faces. These are just anecdotal findings of course, but an obvious interpretation here is that these rare few quality images are the result of the tool producing on those occasions something very close to an image the software was trained on. Or to put it another way, ripping off someone&#39;s work. This is a key question for me, &amp;quot;can these tools reproduce (rip off) an image from the training data?&amp;quot;. Others have done more rigorous testing in this area. In the paper &lt;a href=&quot;https://arxiv.org/abs/2212.03860&quot;&gt;&lt;em&gt;Diffusion Art or Digital Forgery? Investigating Data Replication in Diffusion Models&lt;/em&gt;&lt;/a&gt; the authors observed that when using small training datasets most generated images were &amp;quot;extremely similar to the training data&amp;quot;, and as training data is increased unique variations are introduced. This suggests to me that reproducing training images is a part of how these tools work. The paper concludes that even with large training datasets &amp;quot;copies do appear to occur often enough that their presence cannot be safely ignored&amp;quot;. These findings correlate at least with my hypothesis that the best images are ripping off the work of others, rather than being informed by them. This gets to the heart of my concerns. Humans creating art will look at other work, they might try to emulate it, they might &amp;quot;borrow&amp;quot; (copy) bits of it. This is how we humans learn. I think that is uncontroversial. In principle I feel the same about machines, but there is a line between learning from others work, and stealing it. This is a blurry line, but it&#39;s one we comprehend pretty well. We have copyright laws, and laws against forgery. Key to navigating all this is the artists knowledge of how original or otherwise their work is. That knowledge is very much missing from this process. I also found the amount of visual control I had to be lacking, relying quite heavily on trial and error. Though I was able to develop some methods that got me pretty close to the concept I had. Aesthetically I was pretty pleased with the results, after some not insignificant manual editing.&lt;/p&gt;
&lt;h2 id=&quot;testing&quot;&gt;Testing &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/#testing&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We should talk a little about web browsers. Firefox may have just been released when I made Preparing for Zombies. Safari was introduced the year before. Mostly we were concerned with Internet Explorer. In 2024 there are many more browsers, but at the same time much less divergence in how they render our code. That&#39;s in part because although there are many browsers in use they are almost all powered by one of three browser engines. More importantly though is the adherence of those browsers to Web Standards, achieved thanks to the &lt;a href=&quot;https://www.webstandards.org/&quot;&gt;Web Standards Project&lt;/a&gt;. The work of that group, which started around 1998, got us from the bad old days of browser hacks, to Microsoft releasing a relatively standards compliant browser in 2009 (IE8).&lt;/p&gt;
&lt;p&gt;We didn&#39;t have Google Lighthouse in 2004, the earliest commit on the GitHub repository is eight years ago. I&#39;m not sure what the closest thing we had back then was, maybe an &lt;a href=&quot;https://validator.w3.org/&quot;&gt;HTML validator&lt;/a&gt;. We certainly didn&#39;t have such tools in the browser. The first step towards the DevTools we take for granted today would be taken in around 2005/2006 when the Firefox extension FireBug arrived 🙏. It&#39;s perhaps a little unfair to run a twenty year old website through Lighthouse, but for the sake of science I&#39;ll do it. Running the 2004 website in a local server and testing with Lighthouse in the browser, it gets:&lt;/p&gt;
&lt;dl class=&quot;lighthouse&quot;&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;good&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;Performance&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;100&lt;/dd&gt;
			&lt;/div&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;ok&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;Accessibility&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;86&lt;/dd&gt;
			&lt;/div&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;ok&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;Best practices&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;89&lt;/dd&gt;
			&lt;/div&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;good&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;SEO&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;100&lt;/dd&gt;
			&lt;/div&gt;&lt;/dl&gt;
&lt;p&gt;So what does past me get get marked down on? There are two items under accessibility:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; element does not have a &lt;code&gt;[lang]&lt;/code&gt; attribute&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Heading elements are not in a sequentially-descending order&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don&#39;t think there&#39;s much insight to derive from that, other than I made a couple of (hefty) rookie errors. Under best practices there are three items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;Serves images with low resolution&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;No &lt;code&gt;&amp;lt;meta name=&amp;quot;viewport&amp;quot;&amp;gt;&lt;/code&gt; tag found&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;Document contains a &lt;code&gt;doctype&lt;/code&gt; that triggers &lt;code&gt;limited-quirks-mode&lt;/code&gt;&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These feel much more a reflection of the time. The first is because the images are too small for the high pixel density displays of today. The viewport meta tag was an HTML5 addition, circa 2008. This was needed to ease the transition from fixed width to responsive pages. Now we are at the other side of that transition, not including the viewport meta tag is understandably considered bad practice. The doctype is something I never think about these day, but around the time of the first build there was a decision to make about what doctype to use. As it happens, for reasons I don&#39;t recall, the doctype I used here was &amp;quot;HTML 4.01 Transitional&amp;quot;. This meant it was somewhere between &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode&quot;&gt;Quirks Mode and Standards Mode&lt;/a&gt;, aka &lt;code&gt;limited-quirks-mode&lt;/code&gt;. The best practice Lighthouse is recommending here is specifying a doctype that prevents any sort of quirks mode.&lt;/p&gt;
&lt;p&gt;As for the &lt;a href=&quot;https://preparingforzombies.zmbi.uk/&quot;&gt;2024 rebuild&lt;/a&gt;, as you might hope it gets 100s across the board.&lt;/p&gt;
&lt;dl class=&quot;lighthouse&quot;&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;good&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;Performance&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;100&lt;/dd&gt;
			&lt;/div&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;good&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;Accessibility&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;100&lt;/dd&gt;
			&lt;/div&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;good&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;Best practices&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;100&lt;/dd&gt;
			&lt;/div&gt;&lt;div class=&quot;lighthouse_item&quot; data-rating=&quot;good&quot;&gt;
				&lt;dt class=&quot;lighthouse_label&quot;&gt;SEO&lt;/dt&gt;
				&lt;dd class=&quot;lighthouse_score&quot;&gt;100&lt;/dd&gt;
			&lt;/div&gt;&lt;/dl&gt;
</content>
	</entry>
	
	<entry>
		<title>Get image pixel colours in Eleventy / Node</title>
		<link href="https://smth.uk/get-image-pixel-colours-in-eleventy-node/"/>
		<updated>2024-06-07T00:00:00Z</updated>
		<id>https://smth.uk/get-image-pixel-colours-in-eleventy-node/</id>
		<content type="html">&lt;p&gt;If you&#39;re pre-building pages with &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;Eleventy (static site generator)&lt;/a&gt; you&#39;re probably taking advantage of the &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/&quot;&gt;Eleventy Image plugin&lt;/a&gt; for transforming your images. In this post I&#39;m going to walk through doing a little extra work to get colour information from those images at the same time.&lt;/p&gt;
&lt;h2 id=&quot;tl%3Bdr&quot;&gt;TL;DR &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/get-image-pixel-colours-in-eleventy-node/#tl%3Bdr&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;sharp&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(src)&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;raw&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;toBuffer&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;`rgb(${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;}, ${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;}, ${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;})`&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  });&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h2 id=&quot;how-is-this-useful%3F&quot;&gt;How is this useful? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/get-image-pixel-colours-in-eleventy-node/#how-is-this-useful%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are many ways you could make use of the following technique, but one example that you&#39;ll probably recognise is an audio player that uses colours from album artwork in its interface.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/5ecffadc-1400.webp&quot; alt=&quot;Four screenshots of a music player app, with different background gradients&quot; width=&quot;1400&quot; height=&quot;704&quot; loading=&quot;lazy&quot; /&gt;
&lt;p&gt;In a Web context your first thought might be to do this in the browser, but if we&#39;re already transforming our images on a server / during a build, that feels like a much better time to be running this operation.&lt;/p&gt;
&lt;h2 id=&quot;a-simple-example&quot;&gt;A simple example &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/get-image-pixel-colours-in-eleventy-node/#a-simple-example&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For the sake of this post I&#39;m going to use the simplest use-case I can think of. I&#39;ve got some images isolated on coloured backgrounds, and I want their containers to have the same background colour. I&#39;m going to use photos of some pots I&#39;ve been making recently.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/33def33e-1400.webp&quot; alt=&quot;Screenshot of a photo of teapot, on a blue page showing either side&quot; width=&quot;1400&quot; height=&quot;710&quot; loading=&quot;lazy&quot; /&gt;
&lt;p&gt;What this screenshot shows is a full height photo on a web page, with the page background visible either side. I&#39;ve made the background blue for demonstration purposes. Our aim here is for those blue areas to be the same colour as the photo background.&lt;/p&gt;
&lt;p&gt;There are many JavaScript libraries for getting colours from images, a popular example is &lt;a href=&quot;https://lokeshdhakar.com/projects/color-thief/&quot;&gt;Color Thief&lt;/a&gt;. These libraries tend to produce palettes based on averaged colours. This is might be what you want for something like the music player example. In this case though I just want one, predictable colour, so I&#39;m going to make use of a tool that Eleventy Image is already using under the hood - &lt;a href=&quot;https://sharp.pixelplumbing.com/&quot;&gt;Sharp&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;eleventy-image-setup&quot;&gt;Eleventy Image setup &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/get-image-pixel-colours-in-eleventy-node/#eleventy-image-setup&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As a starting point, in my &lt;code&gt;.eleventy.js&lt;/code&gt; file I have this fairly standard short-code configured:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;eleventyConfig.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;addShortcode&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;image&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;src&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;alt&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; metadata &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;Image&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(src, {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    widths: [&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;512&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;],&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    formats: [&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;webp&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;jpeg&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;],&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  });&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; imageAttributes &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    class: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;`${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;}_img`&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    alt,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    sizes: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;100vw&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    loading: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;lazy&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    decoding: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;async&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  };&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; Image.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;generateHTML&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(metadata, imageAttributes);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Inside this I&#39;m going to add two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A function to get the colour of the first (top-left) pixel&lt;/li&gt;
&lt;li&gt;A style attribute containing a custom property on the &lt;code&gt;picture&lt;/code&gt; element&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;get-pixel-colour-with-sharp&quot;&gt;Get pixel colour with Sharp &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/get-image-pixel-colours-in-eleventy-node/#get-pixel-colour-with-sharp&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You&#39;ll need to add &lt;code&gt;const sharp = require(&amp;quot;sharp&amp;quot;)&lt;/code&gt; to the top of &lt;code&gt;.eleventy.js&lt;/code&gt;, then in your &lt;code&gt;addShortcode&lt;/code&gt; function add:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;bgColor&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;sharp&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(src)&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;raw&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;toBuffer&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;`rgb(${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;}, ${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;}, ${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;})`&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    });&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;We are passing our source image (&lt;code&gt;src&lt;/code&gt;) to Sharp, and as &lt;a href=&quot;https://github.com/lovell/sharp/issues/934#issuecomment-327167266&quot;&gt;described here&lt;/a&gt;, getting data about the pixels back. We are returning an RGB colour value from the red, green, and blue values of the first pixel. With that we are nearly there, we just need to get that &lt;code&gt;rgb()&lt;/code&gt; value to CSS so we can make use of it.&lt;/p&gt;
&lt;h2 id=&quot;add-a-css-custom-property&quot;&gt;Add a CSS custom property &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/get-image-pixel-colours-in-eleventy-node/#add-a-css-custom-property&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can get our colour to CSS via a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties&quot;&gt;custom property&lt;/a&gt; in a style attribute. I need that custom property higher in the DOM than the &lt;code&gt;img&lt;/code&gt; element though, because I want to colour the wrapper of the &lt;code&gt;img&lt;/code&gt; not the &lt;code&gt;img&lt;/code&gt; itself. We could &lt;a href=&quot;https://www.11ty.dev/docs/plugins/image/#make-your-own-markup&quot;&gt;hand write the output of or short-code&lt;/a&gt; and add a wrapper there, but as I know that a &lt;code&gt;picture&lt;/code&gt; element is going to be created here I make use of &lt;code&gt;pictureAttributes&lt;/code&gt; (added in v4 of Eleventy Image). This is passed via &lt;code&gt;options&lt;/code&gt; (again inside &lt;code&gt;addShortcode&lt;/code&gt;) like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; options &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  pictureAttributes: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    class: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;`${&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;}_picture`&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    style: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;`--background: ${&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;bgColor&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;}`&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Then modify the return statement to include &lt;code&gt;options&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; Image.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;generateHTML&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(metadata, imageAttributes, options);&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;As well as passing the colour to the &lt;code&gt;style&lt;/code&gt; attribute, I also added a class here. So in my CSS I can finally add that background colour:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.pot-list_picture&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;You can see the &lt;a href=&quot;https://samsmith.uk/&quot;&gt;result here&lt;/a&gt;.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Website carbon</title>
		<link href="https://smth.uk/website-carbon/"/>
		<updated>2023-07-30T00:00:00Z</updated>
		<id>https://smth.uk/website-carbon/</id>
		<content type="html">&lt;p class=&quot;article_call-out&quot;&gt;This web page is cleaner than &lt;mark&gt;97%&lt;/mark&gt; of web pages tested.&lt;br /&gt;&lt;mark&gt;0.02 g of CO&lt;sub&gt;2&lt;/sub&gt;&lt;/mark&gt; is produced every time someone visits this web page.&lt;/p&gt;
&lt;h2 id=&quot;where-are-these-numbers-coming-from%3F&quot;&gt;Where are these numbers coming from? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/website-carbon/#where-are-these-numbers-coming-from%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I&#39;m using data from &lt;a href=&quot;https://www.websitecarbon.com/&quot;&gt;websitecarbon.com&lt;/a&gt;, a carbon calculator built by Wholegrain Digital. You can read more about the calculator there. You&#39;ll also find instructions for adding a badge to your own site.&lt;/p&gt;
&lt;h2 id=&quot;how-are-these-numbers-calculated%3F&quot;&gt;How are these numbers calculated? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/website-carbon/#how-are-these-numbers-calculated%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The calculator uses four data points, which it describes as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Data transfer over the wire&lt;/li&gt;
&lt;li&gt;Energy intensity of web data&lt;/li&gt;
&lt;li&gt;Energy source used by the data centre&lt;/li&gt;
&lt;li&gt;Carbon intensity of electricity&lt;/li&gt;
&lt;li&gt;Website traffic&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Energy intensity of web data&lt;/em&gt; and &lt;em&gt;Website traffic&lt;/em&gt; are average values. &lt;em&gt;Energy source used by the data centre&lt;/em&gt; and &lt;em&gt;Carbon intensity of electricity&lt;/em&gt; can vary depending on whether the website host is &lt;a href=&quot;https://www.thegreenwebfoundation.org/&quot;&gt;considered green&lt;/a&gt;. The biggest variable though is &lt;em&gt;Data transfer over the wire&lt;/em&gt;, and that&#39;s what this calculator is essentially using as a proxy for carbon footprint. You may ask &amp;quot;is data transfer a good proxy?&amp;quot;. &lt;a href=&quot;https://fershad.com/writing/is-data-the-best-proxy-for-website-carbon-emissions/&quot;&gt;According to Web Sustainability Consultant Fershad Irani&lt;/a&gt;, it &amp;quot;isn’t the best proxy&amp;quot; but right now &amp;quot;it’s the best we’ve got&amp;quot;.&lt;/p&gt;
&lt;h2 id=&quot;why-display-these-numbers-on-the-site%3F&quot;&gt;Why display these numbers on the site? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/website-carbon/#why-display-these-numbers-on-the-site%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&#39;s easy to overlook how much carbon is emitted by a website, but it&#39;s not an inconsequential amount. According to Wholegrain Digital, the internet consumes more electricity in a year than the entire United Kingdom. Testing in public like this keeps my contribution visible, and keeps me in check. I hope this also helps increase awareness of web carbon emissions.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Contextual styling with :has</title>
		<link href="https://smth.uk/contextual-styling-with-:has/"/>
		<updated>2022-06-26T00:00:00Z</updated>
		<id>https://smth.uk/contextual-styling-with-:has/</id>
		<content type="html">&lt;p&gt;Early 2019 was a simpler time, when most of us had a bit more bandwidth to think about the finer details of web design. Back then I was &lt;a href=&quot;https://smth.uk/context-not-modifier/&quot;&gt;banging on about contextual styling&lt;/a&gt;; I&#39;d like to revisit this today, this time through the lens of the &lt;code&gt;:has()&lt;/code&gt; pseudo-class.&lt;/p&gt;
&lt;h2 id=&quot;context-in-css&quot;&gt;Context in CSS &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/contextual-styling-with-:has/#context-in-css&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When I talk about context in CSS I&#39;m thinking about these sorts of things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Descendants&lt;/li&gt;
&lt;li&gt;Children&lt;/li&gt;
&lt;li&gt;Siblings&lt;/li&gt;
&lt;li&gt;Browser size / shape&lt;/li&gt;
&lt;li&gt;User preferences&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last two on that list are very explicitly addressed with media queries. We have some tools to create styles based on the others, such as child and sibling selectors, but there are limitations. Sibling combinators are limited to elements that follow the target element in the DOM, either immediately (&lt;code&gt;+&lt;/code&gt;) or not necessarily immediately (&lt;code&gt;~&lt;/code&gt;). Then there&#39;s the lack of a parent selector, until now… well, soon.&lt;/p&gt;
&lt;h2 id=&quot;%3Ahas&quot;&gt;:has &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/contextual-styling-with-:has/#%3Ahas&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Note that at the time of writing, &lt;code&gt;:has()&lt;/code&gt; is only &lt;a href=&quot;https://caniuse.com/css-has&quot;&gt;supported&lt;/a&gt; in Safari 15.4 and behind a flag in Chrome.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;:has()&lt;/code&gt; pseudo-class can be a sort of a parent selector, but where you write your styles on the parent, based on what children it has. For example if you wanted to style links differently if they contain images you could do this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Using our existing CSS tools we can get more specific. Let&#39;s say we want to style our link differently if its only direct child is an image. We can do that:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:only-child&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;We shouldn&#39;t think about &lt;code&gt;:has()&lt;/code&gt; as &amp;quot;a sort of parent selector&amp;quot; though, it&#39;s better than that. Let&#39;s take the problem of only being able to target siblings that are later in the DOM. For example, we want to style &lt;code&gt;.banner&lt;/code&gt; differently if it is immediately followed by &lt;code&gt;.footer&lt;/code&gt;. We can&#39;t do that with sibling combinators alone; we can do that with the addition of &lt;code&gt;:has()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.banner:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.footer&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h2 id=&quot;let&#39;s-build-something&quot;&gt;Let&#39;s build something &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/contextual-styling-with-:has/#let&#39;s-build-something&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All sounds very cool in theory, let&#39;s put it into practice. I&#39;ve come up with another couple of simple use-cases and a little project to use as a vehicle for them. Use-cases are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hover over a link and its parent styling changes - effectively a hover-within&lt;/li&gt;
&lt;li&gt;Style an element based on the state of a web component within it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To try these ideas out I&#39;m going to build a little dashboard that lists my side projects and displays their lighthouse scores alongside them. I&#39;ll build this on top of &lt;a href=&quot;https://github.com/zachleat/speedlify/&quot;&gt;Speedlify&lt;/a&gt; by &lt;a href=&quot;https://www.zachleat.com/&quot;&gt;Zach Leatherman&lt;/a&gt;, which will give me the &lt;a href=&quot;https://github.com/zachleat/speedlify-score&quot;&gt;speedlify-score&lt;/a&gt; web component.&lt;/p&gt;
&lt;p&gt;Here&#39;s my design:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/p1.png&quot; width=&quot;1015&quot; height=&quot;735&quot; alt=&quot;List of website URLs with one item highlighted green&quot; /&gt;
&lt;p&gt;The green row represents what will happen when you hover the URL. The plan is that the highlight colour will be dependant on the scores to the right. So if the lowest score is in the &amp;quot;Needs Improvement&amp;quot; range (50 to 89) it will be orange, and likewise if it&#39;s in the &amp;quot;Poor&amp;quot; range it will be red.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/p2.png&quot; width=&quot;1015&quot; height=&quot;360&quot; alt=&quot;List of website URLs with one item highlighted orange&quot; /&gt;
&lt;p&gt;With the basic design styled, let&#39;s use &lt;code&gt;:has()&lt;/code&gt; to get the hover working. In the SCSS for the list item, I have some custom properties controlling the colours. I simply reassign these when &lt;code&gt;.site-list_item&lt;/code&gt; has a hover:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;scss&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.site-list_item&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$green}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$white}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$grey}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$black}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:hover&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Worth noting that if you were giving &lt;code&gt;focus-within&lt;/code&gt; the same style, you might be tempted to comma separate the two like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;scss&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:focus-within&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:hover&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This whole block would be ignored in browsers that do not support &lt;code&gt;:has()&lt;/code&gt;, so you should write them as separate declarations:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;scss&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:focus-within&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:hover&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;On to our second challenge - changing the accent colour dependant on the scores. The &lt;code&gt;speedlify-score&lt;/code&gt; component has a class on each score to colour code the score circles. A &amp;quot;Good&amp;quot; score will look like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Performance&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;speedlify-score speedlify-score-good&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;100&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;While a &amp;quot;Bad&amp;quot; score will look like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Performance&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;speedlify-score speedlify-score-bad&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;49&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;We can use the existence of these classes to update our custom properties, like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;scss&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.site-list_item&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$green}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$white}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$grey}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$black}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:hover&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--background-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.speedlify-score-ok&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$orange}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$black}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;&amp;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;:has&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.speedlify-score-bad&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$red}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;--accent-colour-contrast&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;#{$white}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Here we are using green by default, then if there&#39;s an &amp;quot;OK&amp;quot; (Needs Improvement) score we switch to orange and/or if theres a &amp;quot;Bad&amp;quot; score we switch to red.&lt;/p&gt;
&lt;p&gt;That&#39;s it, both the objectives met with a few lines of very neat CSS. You can &lt;a href=&quot;https://mintcanary.com/&quot;&gt;see the end result here&lt;/a&gt;, but I couldn&#39;t find a project with less than &amp;quot;Good&amp;quot; scores I&#39;m afraid 😎 Both of these design challenges could be achieved without &lt;code&gt;:has()&lt;/code&gt; with perhaps some convoluted CSS or more likely Javascript, but I like how robust and easy to comprehend this feels. Of course I&#39;m only scratching the surface here; I&#39;m excited to see what possibilities the &lt;code&gt;:has()&lt;/code&gt; pseudo-class opens up.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>REM based media queries are weird</title>
		<link href="https://smth.uk/rem-based-media-queries-are-weird/"/>
		<updated>2022-06-05T00:00:00Z</updated>
		<id>https://smth.uk/rem-based-media-queries-are-weird/</id>
		<content type="html">&lt;p&gt;Relative units (such as rems) in media queries might not behave as you expect. The TL;DR is that 1rem in a media query condition is always equal to the font-size set in browser settings, and is not affected by a root font-size assigned in CSS. If this is not news to you, or you hold an unwavering opinion that you should never set a root font size, there’s probably nothing more to see here. If everything you thought you understood about rems is crumbling under your feet or you’re open minded about setting a root font size, join me as I walk through the considerations.&lt;/p&gt;
&lt;h2 id=&quot;what%E2%80%99s-a-rem-based-media-query&quot;&gt;What’s a REM based media query &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rem-based-media-queries-are-weird/#what%E2%80%99s-a-rem-based-media-query&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By this I mean a media query that uses a rem value in the media condition, something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;@media&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;min-width&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* my CSS here */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;The issue I’m discussing here is true of all relative units though, not just rems, so also applies to:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;@media&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;min-width&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* my CSS here */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h2 id=&quot;what-do-you-mean-they-are-weird%3F&quot;&gt;What do you mean they are weird? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rem-based-media-queries-are-weird/#what-do-you-mean-they-are-weird%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By weird I mean that 1rem in a media query condition, is not necessarily equal to 1rem elsewhere in your CSS. While 1rem everywhere else is equal to the font size at the &lt;code&gt;html&lt;/code&gt; element, in media queries it is always equal to the font size set in the browser preferences.&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
&lt;blockquote cite=&quot;https://drafts.csswg.org/mediaqueries/#units&quot;&gt;
&lt;p&gt;Relative length units in media queries are based on the initial value, which means that units are never based on results of declarations. For example, in HTML, the em unit is relative to the initial value of font-size, defined by the user agent or the user’s preferences, not any styling on the page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption class=&quot;blockquote_attribution&quot;&gt;— &lt;a href=&quot;https://drafts.csswg.org/mediaqueries/#units&quot;&gt;Media Queries Level 4&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So if you change the size of a rem in your CSS, it diverges from the size of a rem as far as media queries are concerned. I don’t think that is what anyone would expect. I believe the reason for this implementation is to avoid infinite loops. In case for some reason you tried to do this, for example:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;@media&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;min-width&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* at browser width of 500px do this */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* browser width is 600px, let&#39;s do this */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* oh wait, rem value has changed, breakpoint is now 1000px */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* leave the font-size at 10px */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* oh in that case the breakpoint is 500px, let&#39;s do this */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* ok font-size changed to 20px, breakpoint is now 1000px */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* leave the font-size at 10px... */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h2 id=&quot;why-not-just-use-pixels-in-media-queries%3F&quot;&gt;Why not just use pixels in media queries? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rem-based-media-queries-are-weird/#why-not-just-use-pixels-in-media-queries%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You absolutely can, as with all these questions you just need to be clear what that means for your project. The difference between using px or rem in a media query comes when the font size is changed at the browser setting level. If that font size is made significantly larger, and you are using media queries to determine how much space is afforded to the text, this question becomes significant. Say for example you have a column of text, and on large screens a sidebar sits next to that text (dependant on media query). You added the sidebar at the breakpoint you did because you’ve deemed there to be enough space for both. If the font size is larger though, is there still enough space for both? A pixel media query doesn’t care about the size of the text and adds the sidebar regardless. With a rem media query on the other hand, that breakpoint will grow with the font size, meaning the text proportionally retains the amount of space you originally deemed appropriate.&lt;/p&gt;
&lt;h2 id=&quot;so-just-avoid-setting-a-root-font-size%3F&quot;&gt;So just avoid setting a root font-size? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rem-based-media-queries-are-weird/#so-just-avoid-setting-a-root-font-size%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In practice rem weirdness is one of many things to consider when deciding where and how to use pixels and/or rems. I don’t think there is a right or wrong approach, or really any rules to follow. I’d much rather be aware of the consequences of the choices, and make those choices based on the project I’m working on. Not setting a root font size will avoid the media query weirdness, and is perhaps a good default. Let’s look at some considerations you need to make when considering setting your own root font size. First of all, you probably don&#39;t want a fixed value font size (such as px) on your HTML element. Doing so prevents your visitors from using the font size they have set in their browser. This is as close as I&#39;m going to come to a rule here (I would argue there are reasonable exceptions). You almost certainly don&#39;t want to be doing this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; }&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;In that case your best solution is to leave the HTML element alone. Having no font size set both avoids an accessibility blunder and keeps the rem media query story simple.&lt;/p&gt;
&lt;p&gt;As you start to make a stronger case for setting a root font-size, the decision of whether to do so gets trickier. Some people like to do this for example:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;62.5&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; }&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;In this case the change has been made in order to make the equation for converting pixels to rems easier (1rem now equals 10px). If used responsibly, this is probably not a terrible idea; percentages preserve the ability to influence the font size from the browser setting, and presumably you are going to bump the sizes back up to something resembling that setting. You need now though to weigh up what you are gaining - easier mental maths, vs what you are losing - among other things the ability to use rems in media queries without them being weird. In this case I’d suggest finding a different solution to the maths problem, get a preprocessor to do it for example, or maybe even a native CSS calc():&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;18&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* a rem value equivalent to 18px */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;So far my advice has been to leave the HTML element alone. For some that seems to be a rule set in stone, but you can do some neat things with root font sizes. While &lt;code&gt;html { font-size: 62.5%; }&lt;/code&gt; is fine but avoidable, something like this is really powerful and uniquely reliant on setting a root font size:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vw&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This kind of thinking opens up possibilities for an elegant approach to responsive design that reduces reliance on breakpoints. I do this sort of thing quite a lot (I did it on this blog), and I think it&#39;s a legit argument against leaving the root alone. This is the point where I stop saying “leave the html element alone” and start saying “your approach depends on the requirements of your project”. Just know that if you do this... rems in media queries get weird. Whether this is a problem will depend on your project, the way you work, and your willingness to simultaneously hold two ideas of what a rem is. Having set a root font size you still get the same benefits when using rems in media queries as you would otherwise. Where you might get caught out is if you need a media query that relates to something which has a size influenced by rems.&lt;/p&gt;
&lt;h2 id=&quot;an-example&quot;&gt;An example &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rem-based-media-queries-are-weird/#an-example&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;How might weird rems cause a problem? Essentially if you try to use a media query to accommodate something on the page which is sized in rems. If you allow your mind to drift into a magical world where rems in media queries are not weird, you might think this is easy. You might do something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.thing&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;@media&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;min-width&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.thing&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This is a silly but hopefully illustrative example where we say if the browser is wide enough to fit a 50rem thing in it, make the thing 50rem wide. But of course, if you have decided to diverge your rems (set a font size on your html element) then those two occurrences of &lt;code&gt;50rem&lt;/code&gt; might represent wildly different pixel values - the first being 50 x the font size in the browser settings, the second be 50 x your &lt;code&gt;html&lt;/code&gt; font size. Kind of weird, huh?&lt;/p&gt;
&lt;h2 id=&quot;will-it-always-be-this-way%3F&quot;&gt;Will it always be this way? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/rem-based-media-queries-are-weird/#will-it-always-be-this-way%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In my opinion it would be great if 1rem was consistent wherever it was used. Not so much to avoid confusion, but to be able to reliably and usefully use rems with media queries. Essentially to be able to query “does a 50rem wide thing fit on the screen?” I guess at this point we’d need a new syntax for that, and I have no idea how difficult this would be or if anyone else even cares. The behaviour I’ve discussed here is not at all new, but I feel like the issue of infinite loops is something we are going to run into more as we transition from a heavy reliance on media queries, to sizing things more intrinsically. Infinite loops were for a long time cited as the reason we can’t have container queries. Maybe the solutions being worked on there could be applied to media queries too; or maybe container queries just remove the need for a fix. Hopefully container queries don’t end up being weird.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Meaningful page transitions</title>
		<link href="https://smth.uk/meaningful-page-transitions/"/>
		<updated>2022-04-18T00:00:00Z</updated>
		<id>https://smth.uk/meaningful-page-transitions/</id>
		<content type="html">&lt;p&gt;A couple of posts ago (which on my current blogging schedule was a couple of years ago) I wrote about &lt;a href=&quot;https://smth.uk/enhance-your-web-page-transitions/&quot;&gt;the value of transitions&lt;/a&gt;, and gave examples of some commons ones. The examples were sliding or pushing, vertically or horizontally - essentially rectangles moving on and off the screen. These transitions can cover most use cases and will get you a long way, but as with any other aspect of a design, we should be considering transitions on an individual basis. Transitions can help guide a visitor through an experience, and also be an opportunity to re-enforce the visual identity. With animation being a relatively new feature of web design, and animated page transitions not being natively supported in browsers it&#39;s easy to not give them as much consideration as much as other aspects of a design.&lt;/p&gt;
&lt;p&gt;Today I’m going to design and build a little app with bespoke transitions that hopefully take into account the particular needs of the design. To do this I will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://smth.uk/meaningful-page-transitions/#design%2C-let%E2%80%99s-go&quot;&gt;Design&lt;/a&gt; some static mock-ups (in Figma).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://smth.uk/meaningful-page-transitions/#build-the-app-already&quot;&gt;Build&lt;/a&gt; the app with Vue (Vue gives us a bit of a jump-start with transitions)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://smth.uk/meaningful-page-transitions/#finally%2C-some-style&quot;&gt;Style&lt;/a&gt; the transitions with CSS&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;design%2C-let%E2%80%99s-go&quot;&gt;Design, let’s go &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/meaningful-page-transitions/#design%2C-let%E2%80%99s-go&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A colleague of mine recently mentioned an idea she had for an app. I’m borrowing it for this exercise.  The idea is essentially “Give yourself a medal”. So in my imagined version of this app we’d have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A button you can press... to give yourself a medal&lt;/li&gt;
&lt;li&gt;Some sort of gratification where you “receive” your “medal”&lt;/li&gt;
&lt;li&gt;And to give us another screen to work with, a collection where you can see your hard earned medals&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I start by designing those three views. Here’s what I’ve got:&lt;/p&gt;
&lt;figure role=&quot;group&quot; aria-labelledby=&quot;fig1&quot; class=&quot;image-group&quot;&gt;
&lt;figcaption id=&quot;fig1&quot; class=&quot;image-group_caption&quot;&gt;Mockups for the start screen, the awarded medal, and the collection respectively.
&lt;/figcaption&gt;
&lt;div class=&quot;image-group_images&quot;&gt;
    &lt;img src=&quot;https://smth.uk/img/gyam-start.png&quot; width=&quot;282&quot; height=&quot;500&quot; alt=&quot;Start screen&quot; /&gt;
    &lt;img src=&quot;https://smth.uk/img/gyam-add.png&quot; width=&quot;282&quot; height=&quot;500&quot; alt=&quot;New medal screen&quot; /&gt;
    &lt;img src=&quot;https://smth.uk/img/gyam-collection.png&quot; width=&quot;282&quot; height=&quot;500&quot; alt=&quot;Collection screen&quot; /&gt;
&lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;A bit more borrowing here - shout out to &lt;a href=&quot;https://graphicsurf.com/&quot;&gt;GraphicSurf&lt;/a&gt; for the medal illustrations.&lt;/p&gt;
&lt;p&gt;With those designs signed off (by me) it’s time to think about our transitions. How do we get from the big button (that orange thing with “#1” on it) to the presentation of the medal? I like transitions to be anchored to the thing you are pressing. If I have an off-canvas / burger menu for example, I will usually bring it in from the side of the screen where the menu icon is. Here the button is anchored to the centre of the page, so it feels natural that the animation originate there. With circles being such a strong feature of the design, it also feels natural that they feature in the transitions. So here’s what I’m thinking, a circular wipe from one view to the next.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/gyam-adding.png&quot; width=&quot;282&quot; height=&quot;500&quot; alt=&quot;Circular wipe between start screen and new medal screen&quot; /&gt;
&lt;p&gt;I think that’s all I need in terms of mock-ups for the transition between those two views. My plan here is that after a set period of time this view will automatically close and we will be returned to the start. We could just reverse the animation for that transition, but we can do better than that. You may have noticed that a little number has appeared in the bottom right of the screen at this stage. The intention here is that this will be a counter to tell us how many medals we have. This counter will also act as a button to show all the medals in the collection. To help make clear what is happening here we can make the wipe centre on that counter as it closes. This I think will give the impression of the medal on screen being transported into that corner, drawing attention to the existence of the counter / button.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/gyam-closing.png&quot; width=&quot;282&quot; height=&quot;500&quot; alt=&quot;Circular wipe between new medal screen and start screen&quot; /&gt;
&lt;p&gt;With our attention on that button, what happens when we press it? Again we want to reinforce what is happening by anchoring the animation to the point where we are interacting, so here we can reuse the previous corner animation to open and close the collection. Done.&lt;/p&gt;
&lt;h2 id=&quot;build-the-app-already&quot;&gt;Build the app already &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/meaningful-page-transitions/#build-the-app-already&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I’m going to build this little app as a single page in Vue. Vue will do the work of hiding and showing our sections, and also add classes before and after a transition. These are the classes that we will attach our styles to in order to build our bespoke transitions. We don’t have native transitions in browsers yet, so Vue is a nice shortcut that will get us to the styling stage really quickly. If you’re not using a framework that does this there are JavaScript libraries that can add those transition classes to regular page transitions. See &lt;a href=&quot;https://smth.uk/enhance-your-web-page-transitions/&quot;&gt;this post for how to do that using Barba.js&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’ve made a Vue component for each of the bits that I’ll be transitioning. Here is the first component we want to transition in - the presentation of the new medal.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;v-if&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;showNew&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;v-if&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;LatestMedal&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new_image&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #82071E&quot;&gt;:src=&quot;medalImage&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;alt&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Medal&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new_img&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;v-if&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;LatestMedal&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new_message&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			{{ LatestMedal.message }}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Whether this component is visible depends on the boolean &lt;code&gt;showNew&lt;/code&gt;, which is set to true when the big button is pressed, and then back to false a couple of seconds later. The transition magic starts when we add a Vue &lt;code&gt;&amp;lt;transition&amp;gt;&lt;/code&gt; component.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;transition&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;v-if&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;showNew&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;v-if&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;LatestMedal&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new_image&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #82071E&quot;&gt;:src=&quot;medalImage&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;alt&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Medal&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new_img&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;v-if&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;LatestMedal&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;new_message&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				{{ LatestMedal.message }}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;transition&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;The transition component adds our enter and leave classes when the visibility is toggled. I’ve given the transition a name - &lt;code&gt;new&lt;/code&gt; which will prefix the transition classes. This means we can individually style our multiple transitions (by giving them unique names). From a transition point of view, this is essentially all we need to do in Vue. Repeating for the collection view. You can read more about the &lt;a href=&quot;https://vuejs.org/guide/built-ins/transition.html#css-based-transitions&quot;&gt;transitions classes in the Vue docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;finally%2C-some-style&quot;&gt;Finally, some style &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/meaningful-page-transitions/#finally%2C-some-style&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Just two CSS tasks to do now; create the animations and apply them to our transition classes. That’s going to look something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;@keyframes&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;reveal-center&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;clip-path&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vmin&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;clip-path&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vmin&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;@keyframes&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;reveal-corner&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;clip-path&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vmin&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;at&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vw&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vh&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;clip-path&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vmin&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;at&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vw&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vh&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.new-enter-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;animation&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: reveal-center &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.6&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.new-leave-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;animation&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: reveal-corner &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.4&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;reverse&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.collection-enter-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;animation&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: reveal-corner &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.5&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.collection-leave-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;animation&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: reveal-corner &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.5&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;reverse&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;And that’s about all it takes to get a couple of nice, bespoke transitions going. Nailed it. &lt;a href=&quot;https://gyam.smth.ooo/&quot;&gt;Give yourself a medal!&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>I tried Windows for a year</title>
		<link href="https://smth.uk/i-tried-windows-for-a-year/"/>
		<updated>2021-08-30T00:00:00Z</updated>
		<id>https://smth.uk/i-tried-windows-for-a-year/</id>
		<content type="html">&lt;p&gt;Until about a year ago I had been a full time Mac user of about fifteen years. I loved macOS (or OSX as it was known then) from the first time I encountered it, and I&#39;d never looked back. I wouldn&#39;t describe myself as an &amp;quot;Apple fanboy&amp;quot; however - I&#39;ve never owned an iPhone, iPad or even an iPod. My love for Macintoshes has dwindled over the years too (the aesthetics and build quality are no longer exceptional in my opinion). For better or worse, it is the macOS operating system that I buy Apple hardware for.&lt;/p&gt;
&lt;p&gt;As events of 2020 transpired, I was left without a functioning Mac (one of the more minor inconveniences of that year). Macs being what they are, I needed an Apple Store to take a look at the iMac that had just died, but of course we were in lockdown, and there were no Apple Stores. It would have been premature to buy a new computer; I was short on options. My eyes turned to the gaming PC in the corner.&lt;/p&gt;
&lt;p&gt;I started weighing up the options I had. Install Linux on it maybe.. no It&#39;d be too limited in terms of design software. Hackintosh? Probably asking for trouble. I could try working on Windows I guess..&lt;/p&gt;
&lt;p&gt;And so it began, my time working on Windows. I decided to take this opportunity to give Windows 10 a proper go, and not run back to macOS as soon as possible. Over a year later I am typing this on that Windows machine, in an application called &lt;a href=&quot;https://typora.io/&quot;&gt;Typora&lt;/a&gt; - one of the many discoveries I&#39;ve had to make in that time.&lt;/p&gt;
&lt;p&gt;What follows are some general &lt;a href=&quot;https://smth.uk/i-tried-windows-for-a-year/#general-annoyances&quot;&gt;negatives&lt;/a&gt; and &lt;a href=&quot;https://smth.uk/i-tried-windows-for-a-year/#the-good-stuff&quot;&gt;positives&lt;/a&gt; about using Windows, followed by my experiences while doing &lt;a href=&quot;https://smth.uk/i-tried-windows-for-a-year/#specific-tasks&quot;&gt;design and development tasks&lt;/a&gt; in particular. This will mostly be a comparison of the operating systems, but will touch upon hardware. It&#39;s worth saying at this point that the killer &amp;quot;feature&amp;quot; of macOS for me is essentially that it, and everything that runs on it &lt;em&gt;just works&lt;/em&gt;™. This is facilitated of course by the limitation on hardware it will run on. To the credit of Windows, it attempts to run on any combination of hardware, including whatever you cobble together yourself. It is partly for this reason that I had a functioning PC that I could repurpose, and ultimately get stuff done on.&lt;/p&gt;
&lt;h2 id=&quot;general-annoyances&quot;&gt;General annoyances &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#general-annoyances&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the grand scheme of things, the two operating systems are pretty similar. They certainly have more in common than they have differences, and seem to be converging all the time. While you probably will have some &amp;quot;I can&#39;t believe this is so broken&amp;quot; Windows moments, a lot of what separates the two are small user experience details. But evidenced by the eternal PC vs Mac debate, these are details that people care about. Perhaps unsurprisingly the differences I noticed first were those that felt immediately unsatisfactory.&lt;/p&gt;
&lt;h3 id=&quot;the-business-model&quot;&gt;The business model &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#the-business-model&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This may sound like a strange way to start a list of user experience problems, but when you switch to Windows this becomes very apparent. Windows is full of ads, and prompts to get you to use Microsoft services. A lot of the ads and data collection stuff can be turned off with a bit of work. It seems you can never escape the prompts to sign into every Microsoft service you&#39;ll never want to use though. In the paradigm we find ourselves, you might be used to this and it might not bother you. I can&#39;t help but find it a bit obnoxious personally.&lt;/p&gt;
&lt;h3 id=&quot;interface-clarity&quot;&gt;Interface clarity &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#interface-clarity&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I need to preface this by saying that I was not comparing like-for-like here. I wasn&#39;t just swapping operating systems, but also displays. My Mac had an integrated 27&amp;quot; 5K display. I replaced this with a 27&amp;quot; 4K display (Benq PD2720U). While the drop from 5K to 4K might sound relatively trivial, it actually makes a huge difference. Because of the interface scaling you&#39;re going to require, the maths just works better for 5K at 27&amp;quot;. You can use 200% scaling rather than 150%, avoiding sub-pixel blurriness. It&#39;s no accident that Apple opted for 5K in their iMacs. This is one of the legitimate occasions where Apple hardware is better value for money. When I bought my iMac at least, it cost about the same as a 5K display would have cost on its own. So operating system aside, some disappointment was inevitable here. That said, I felt Windows was doing a worse job of scaling, and brought with it various jaggedness and blurriness issues. The severity of these issues varies; in the worst cases some applications simply don&#39;t appear to have been updated since we started using higher pixel densities. These interfaces will look straight up blurry to the point of being virtually unusable. Other problems are probably more subjective, and tend to differ from application to application. For example I found the Figma native app to be blurry, but when running Figma in Firefox it looked a little better. Generally I found everything, but most noticeably text, looked either too jagged or too blurry in most cases. This was all very distracting for a while, especially during design work, but the good news is that I got used to it eventually and could start to see past the imperfections.&lt;/p&gt;
&lt;p&gt;Other issues of clarity were less ambiguous. The Windows interfaces feel like they are lacking attention to detail. Things like dark text on dark backgrounds are pretty typical of the experience you can expect from the core Windows interface. There&#39;s a lack of consistency too, you can clearly see Windows 10 visual language alongside bits of Windows 8, 7, Vista, and probably earlier. Windows feels unfinished.&lt;/p&gt;
&lt;h3 id=&quot;native-applications&quot;&gt;Native applications &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#native-applications&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I found I as left wanting a little when it came to Windows applications. A lot of the applications we use are either Web based or available cross platform of course, but when that&#39;s not the case chances are what you want either doesn&#39;t exist or looks like it hasn&#39;t been updated since 2006. For example I wanted a calendar app that can sync via CalDAV. Apparently that&#39;s not a thing on Windows.&lt;/p&gt;
&lt;h3 id=&quot;customer-support&quot;&gt;Customer support &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#customer-support&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As far as I can tell there is no customer support for Windows. To be fair, I&#39;m not sure how it would work. Is it realistic to offer support for all the variables that constitute a Windows computer? When you run into a problem, which you probably will, you&#39;re on your own. In contrast Apple&#39;s support in my experience is pretty good. You can speak to a knowledgeable and helpful human almost immediately.&lt;/p&gt;
&lt;h2 id=&quot;the-good-stuff&quot;&gt;The good stuff &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#the-good-stuff&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you can get beyond these sorts of annoyances, there will hopefully be some pleasant surprises too. For me there were a few day-to-day aspects of Windows that felt like an upgrade.&lt;/p&gt;
&lt;h3 id=&quot;touch-screen-support&quot;&gt;Touch screen support &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#touch-screen-support&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I didn&#39;t have a burning desire for this, and it will be more valuable to some than others, but this is a really nice option to have at your disposal.&lt;/p&gt;
&lt;h3 id=&quot;file-explorer&quot;&gt;File Explorer &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#file-explorer&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This could be easily overlooked but File Explorer (Finder in Mac parlance) is possibly the part of the operating system you are going to interact with most. File Explorer is a bit of a mess from a design point of view, but simply for the fact that you can easily copy and paste the path to the folder you&#39;re in means it is better than Finder in my opinion.&lt;/p&gt;
&lt;h3 id=&quot;audio-configuration&quot;&gt;Audio configuration &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#audio-configuration&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Listening to music is something I often do while working, and I want to control that music from my desk but have it play through my hi-fi. For me this means having an audio device which some applications (a music player and a browser) output to. On Mac I had to use a third party application to achieve this, which I would need to start whenever I wanted to listen to music. On Windows this feature is built in, and you can set it once and forget about it.&lt;/p&gt;
&lt;h2 id=&quot;specific-tasks&quot;&gt;Specific tasks &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#specific-tasks&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most of my time spent at a computer is spent doing either Web design or front-end development work. So how did that go?&lt;/p&gt;
&lt;h3 id=&quot;design&quot;&gt;Design &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#design&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you can get past the clarity issues discussed above (which I did, eventually) the story is pretty good here. Windows is well supported by design applications these days, I didn&#39;t find myself missing anything. If you are a Sketch user you will need to find a replacement but you do at least have some options in the screen design space. Anecdotally I feel like a bit of a second class citizen as a designer on Windows. When there are bugs not getting fixed for a long time, you can&#39;t help but wonder if them being Windows specific almost makes them an edge case.&lt;/p&gt;
&lt;p&gt;Not purely a design task, but one that I associate with design files is backing up. Design files are &lt;em&gt;the&lt;/em&gt; thing that I care about being backed up and don&#39;t have a natural home in Git (as any code I write does). I relied on Time Machine for this in macOS, which I found reliable, and something I never had to think / worry about. Windows comes with no such backup tool, so unless you&#39;re already using a cross platform backup system you&#39;re going to need to shop around for something new. I tried quite a few backup applications, both free and paid for. I struggled to find something that worked for me in a comparable way to Time Machine. I came close, Acronis True Image was pretty solid, but when I did hit an issue, I found the customer support to be less than helpful. I had another nagging doubt about Acronis while I was using it, that being that it backs up your files in a proprietary format. This means that you are essentially locked into paying for a subscription to this product for as long as you want access to your backups. I eventually decided that this wasn&#39;t for me and cancelled my subscription. I had to broaden the scope of my search at this point. One option I explored was syncing my files to a &amp;quot;cloud&amp;quot;, figuring that the files existing in two places was all the precaution I really needed. I used Adobe Cloud for this (as I was already paying for it), and in short I can&#39;t recommend it. Adobe some how deleted all my design files, those deletions were synced to my machine, and the files were lost. Adobe were unable or unwilling to explain how this happened or to recover the lost files. They seemed content to direct me to their terms of service which state they are not liable for lost data. Don&#39;t rely on Adobe for backups.. or anything if you can &lt;a href=&quot;https://uninstall.tech/adobe/&quot;&gt;avoid it&lt;/a&gt;. The solution I settled on was a program called &lt;a href=&quot;https://restic.net/&quot;&gt;Restic&lt;/a&gt;. Restic &lt;em&gt;is&lt;/em&gt; a backup solution, but different to what I was originally looking for in two key ways. Firstly it has no GUI - it&#39;s command line only, and secondly automated / scheduled backups are not part of what the application offers. Having lived with it for a while, I can say that running from the command line is not an issue - performing backups is really easy (admittedly that&#39;s coming from someone who uses command line interfaces regularly). The automation side of things might be more of an issue for you. There are two options here; use third party tools to schedule Restic backups, or do your backups manually. I haven&#39;t spent much time looking into the first option, but opted to switch my mindset to backups being a manual thing. In a funny way I think it being a command line tool helped with this. I now think of backing up design files in a similar way as I do about committing code to version control.&lt;/p&gt;
&lt;h3 id=&quot;development&quot;&gt;Development &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#development&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If I had come to this cross roads just a couple of years earlier, I don&#39;t think I would have entertained the idea of doing front-end development on Windows. &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/wsl/&quot;&gt;Windows Subsystem for Linux&lt;/a&gt; (WSL) has changed this story dramatically, and means that when you&#39;re developing on Windows, you&#39;re actually developing on Linux. I like this idea a lot in theory. In practice it&#39;s pretty good, but not without its issues.&lt;/p&gt;
&lt;p&gt;Working with WSL means working in Bash, which means your day-to-day tasks will be a lot like working in Terminal on a Mac. The significant difference will be speed. WSL does add a noticeable delay to any task you are running. Not huge, but noticeable. At this point we need to talk about WSL 1 vs WSL 2. If getting started with WSL now you might assume WSL 2 is the way to go. It&#39;s faster and brings with it some &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/wsl/compare-versions&quot;&gt;additional features&lt;/a&gt;. There is a big caveat though, WSL 2 essentially doesn&#39;t work with files on your Windows file system (it&#39;s prohibitively slow). If you&#39;re happy having all your files live in Linux then WSL 2 is probably the way to go. Personally I like using a Git GUI and the story there is &lt;a href=&quot;https://github.com/microsoft/WSL/issues/4273&quot;&gt;a bit unclear for WSL 2&lt;/a&gt; at the moment. With WSL 1 on the other hand, you can store your project files in Windows, run Git on Windows, and use any Git GUI that runs on Windows. For this reason I&#39;ve stuck with WSL 1 for now and live with the performance hit, which is manageable.&lt;/p&gt;
&lt;p&gt;Again I sometimes feel like a bit of an edge case when something isn&#39;t working with WSL. I&#39;m not sure it&#39;s true to say that most front-end developers use a Mac; I&#39;ve seen stats in the past that seem to suggest the split is around 50/50 with Windows. I do wonder though if this is the case in some circles, and perhaps those circles are important to you. Consider this, when was the last time you saw a demo of a new tool / library / framework not be demoed on a Mac?&lt;/p&gt;
&lt;p&gt;One last consideration here is browser testing. In Windows there&#39;s no Safari. You also lose the iOS emulator that macOS has. This means more time in some sort of virtualisation software, which isn&#39;t always the best developer experience.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;That felt like long-winded way of saying working in Windows is mostly fine, so for those who have skipped down to here I&#39;ll try to sum up with a couple of pertinent questions.&lt;/p&gt;
&lt;h3 id=&quot;has-windows-won-me-over%3F&quot;&gt;Has Windows won me over? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#has-windows-won-me-over%3F&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In short, no. All being equal, if I could freely choose what OS I run I would choose macOS.&lt;/p&gt;
&lt;h3 id=&quot;if-i-was-in-the-market-for-a-new-computer%2C-what-would-i-buy%3F&quot;&gt;If I was in the market for a new computer, what would I buy? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/i-tried-windows-for-a-year/#if-i-was-in-the-market-for-a-new-computer%2C-what-would-i-buy%3F&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is a much harder question to answer, and I&#39;m not sure the answer would be a Mac. I have for a long time been concerned about the decreasing ability to repair and upgrade Macs. Not only does this leave you in the lurch during a pandemic, it&#39;s wasteful. The only Mac from the current range that really appeals to me is the Mac Pro, but that&#39;s way over powered and over priced for my needs. I think probably right now I&#39;d go for a used Mac Pro 5,1, but would still be a little concerned about the longevity. All of this highlights the compromises we make in Apple hardware in order to avoid compromises in the software. With those compromises in Windows feeling more or less manageable, Windows is a tempting option. With Windows 11 on the horizon maybe this becomes more compelling in the near future.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>My formative Web experiences</title>
		<link href="https://smth.uk/my-formative-web-experiences/"/>
		<updated>2020-09-27T00:00:00Z</updated>
		<id>https://smth.uk/my-formative-web-experiences/</id>
		<content type="html">&lt;p&gt;After &lt;a href=&quot;https://adactio.com/&quot;&gt;Jeremy Keith&lt;/a&gt;&#39;s wonderful reading of The History of the Web by &lt;a href=&quot;https://twitter.com/jay_hoffmann&quot;&gt;Jay Hoffmann&lt;/a&gt; on &lt;a href=&quot;https://shoptalkshow.com/431/&quot;&gt;this week&#39;s Shoptalk Show&lt;/a&gt;, Dave Rupert, reminiscing about his first experience of the Web, challenged the listeners to &amp;quot;go write blog posts about your Web experience&amp;quot;. I feel like I&#39;m overdue a blogpost, and this sounds like a nice idea, so here goes.&lt;/p&gt;
&lt;p&gt;Back in 1997, I was at Art School, and I think it&#39;s fair to say slightly disenchanted with what the my course was offering. Maybe that&#39;s the point of Art School though. This establishment did have something going for it however - a library... with computers in it! As I recall, there was some sort of induction session required before using the library; as part of this induction we were shown a small CRT monitor displaying an interface identifying itself as &lt;strong&gt;AltaVista&lt;/strong&gt;. Though I didn&#39;t comprehend it at the time, I was getting my first glimpse of a search engine, and indeed my first glimpse of the Web.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/File:Altavista-1996.png#/media/File:Altavista-1996.png&quot;&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/en/7/78/Altavista-1996.png&quot; alt=&quot;Screenshot of the AltaVista search engine in November 1996&quot; width=&quot;376&quot; height=&quot;265&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have vague but fond memories of spending a lot of time in that library over the coming year. I&#39;m sure this early experience of the Web would be a familiar voyage of discovery for many. New concepts entered my life; I found chatrooms, and email, and probably most influentially - personal websites. I guess what characterised a personal website back then was something that seemed to have no real purpose for existing, and clearly looked handmade (or whatever the digital equivalent to that is). It looked like regular people were building the Web. It looked like maybe I could build the Web?!&lt;/p&gt;
&lt;p&gt;As it happened, these personal websites didn&#39;t feel like a &lt;em&gt;completely&lt;/em&gt; new concept to me. They reminded me of something I&#39;d seen before. When I was younger I had a &lt;a href=&quot;https://en.wikipedia.org/wiki/Amiga&quot;&gt;Commodore Amiga&lt;/a&gt;. Games in those days came on floppy disks. Games in those days were also wildly pirated. There was a phenomenon where Amiga owners would create a bootable floppy disk containing lists of all the games they &amp;quot;own&amp;quot;. These disks were exchanged between Amiga owners to facilitate &amp;quot;swapping&amp;quot; of games - do me a copy of this and I&#39;ll give you a copy of that. Rather than just being a utilitarian list of games however, these disks became quite creative things, with custom graphics, little biographies, and even 8bit music. They very much resembled what I would later discover as personal websites. In case you&#39;re wondering what the discovery and transfer mechanisms were, people would put their names and addresses in personal ads in the back of computer magazines. It was the large scale piracy of its day, facilitated by the leading computer magazines. It was a strange time. Anyway, the Amiga swap disk thing was fun and exciting; and years later, in 1997 I was getting a similar feeling from the Web.&lt;/p&gt;
&lt;p&gt;With the excitement of a child engaged in a not so underground piracy ring, I began my two decade plus adventure into making Web pages. It must have been around this time that I actually started to use the library (the Web) for educational purposes. I learned that all I needed to make a webpage was Notepad (an application ubiquitously installed on Windows PCs, including those in the Art School Library), and somewhere online to put the files - a webhost. Geocities was the place to host websites at that time. If you know Geocites, then it probably evokes memories of the sort of sites I was visiting and building.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://oneterabyteofkilobyteage.tumblr.com/post/125435539284/original-url&quot;&gt;&lt;img src=&quot;https://64.media.tumblr.com/03d3d6f716e6ae0107bb6756e61bbfd7/tumblr_nsb4tn2brF1rlkewbo1_1280.png&quot; alt=&quot;Screenshot of a Geocities page repeating the phrase This is the happy site!&quot; width=&quot;400&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://oneterabyteofkilobyteage.tumblr.com/post/117329668474/original-url&quot;&gt;&lt;img src=&quot;https://64.media.tumblr.com/8d4d910e7d85709c749d2daa5bde4838/tumblr_nnd3lljZgc1rlkewbo1_1280.png&quot; alt=&quot;Screenshot of a Geocities page repeating the word FUCK over and over&quot; width=&quot;400&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://oneterabyteofkilobyteage.tumblr.com/post/43687867416/original-url&quot;&gt;&lt;img src=&quot;https://64.media.tumblr.com/9bd6b94da2debb364a3c9bd2421a1437/tumblr_millyy2GFz1rlkewbo1_1280.png&quot; alt=&quot;Screenshot of a Geocities page titled The Following Bads Are Not Punk&quot; width=&quot;400&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;s&gt;Un&lt;/s&gt;fortunately I don&#39;t have anything I made at that time. The earliest of my websites I was able to find was one called &amp;quot;Preparing for Zombies&amp;quot;, which I made in the early 2000s. That site was a spoof of a UK Government campaign of the time. A &lt;a href=&quot;https://smth.uk/rebuilding-a-twenty-year-old-website/&quot;&gt;rebuild&lt;/a&gt; of that site is &lt;a href=&quot;https://preparingforzombies.zmbi.uk/&quot;&gt;online here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By this time I had used a student loan to buy my own computer, and was now online at home. It was in this period that I had my first taste of social media. The Web still felt weird and fun, and MySpace in many ways felt akin to those early personal websites. The DIY spirit of Geocities lived on here, if only at an aesthetic level. MySpace allowed you to customise your profile with your own HTML and CSS. This feels like such a strange idea now, but it happened, and people loved it.&lt;/p&gt;
&lt;p&gt;Somewhere along the line I started to get serious about design, and in 2005 came my first design job. It was at a small marketing agency, where I was mostly designing for print. It was my passion for the Web of course, that got me to this point; and I&#39;m not sure I would have become a designer without first becoming a Web maker. While I&#39;m reflecting on how I came to enjoy the career I have, I want to make a serious point. I owe this career to two things that I have touched upon already, that deserve reiteration. One is free access to a library (via free access to education), and the other is the low barrier to entry of coding a webpage. I mention these again, and together because I feel they are both are under threat. Certainly in the UK, education has become increasingly expensive; and libraries have been closing en masse under the weight of austerity policies brought in after the banking crisis of 2008. In terms of barrier to entry, when I started out, the way to make a webpage was to open a text editor and type a few HTML tags. While that is as true today as it was 23 years ago, the normalisation of overengineering in frontend development makes me wonder if some people, perhaps groups of people, are being deterred from getting involved.&lt;/p&gt;
&lt;p&gt;Back to the story, it&#39;s 2005, I&#39;m now a professional Web / Graphic Designer. What does any self respecting Web Designer need? A portfolio site. I&#39;m not sure if this was my first domain purchase, but it&#39;s the earliest survivor. There was much less choice of TLDs back then, so &lt;a href=&quot;https://samsmith.name/&quot;&gt;samsmith.name&lt;/a&gt; was born.  That site has had lots of little iterations over the years, but still serves the same purpose today. Something else was born around then - a love affair with domain names. Something I came to appreciate was that to really have ownership of your bits of the Web, you need at least one domain to call your own. Just a few months after &lt;a href=&quot;http://samsmith.name/&quot;&gt;samsmith.name&lt;/a&gt; came &lt;a href=&quot;https://elisted.org/&quot;&gt;elisted.org&lt;/a&gt;. This was to be home to a website directory. It was a lofty ambition, to build a site of sites; but that wasn&#39;t quite as crazy as it now sounds. Website directories were a thing back then.  Again &lt;a href=&quot;http://elisted.org/&quot;&gt;elisted.org&lt;/a&gt; is still online today, albeit with the much more modest scope of listing a few sites that I find useful.&lt;/p&gt;
&lt;p&gt;As social media continued to grow in popularity, Facebook was unleashed onto the world.  I was a late adopter as I recall, resisting the switch from MySpace. I eventually followed the crowd and switched in around 2007. As with MySpace, there was a focus on people having a page on the Web, and the concept of &amp;quot;friends&amp;quot;. I can&#39;t remember much of what set Facebook apart, but I do remember it feeling new. One small gimmick it had was the &amp;quot;status&amp;quot;. This was essentially the cornerstone of social media, the thing you write. Here though that thing &lt;em&gt;had&lt;/em&gt; to start with &amp;quot;&lt;Your name=&quot;&quot;&gt; is&amp;quot;; so mine for example would be pre-filed with &amp;quot;Sam is&amp;quot;. This was a fun little constraint I thought. Years later I decided to &lt;a href=&quot;https://deletefacebook.com/&quot;&gt;delete Facebook&lt;/a&gt;, but before I did I downloaded my data. Here are some of my first Facebook statuses.&lt;/Your&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sam is looking forward to seeing Misfits on Sunday&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Sam is wondering why&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Sam is questioning the sambuca on a week night&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In 2012 the Web gave me perhaps its biggest gift yet, remote working. Working from home has its positives and negatives, as I&#39;m sure many people have been learning in 2020. The biggest negative for me is ironically the reason why working from home has now been so widely adopted - its tendency towards isolation. This is perhaps a tendency of the Web more broadly. The positives on the other hand are a freedom and flexibility that can enhance and transform your quality of life. For me this meant, after living in one small town up to this point, I moved to three of my favourite cities. I don&#39;t know if this qualifies me as what I believe the kids call a &amp;quot;digital nomad&amp;quot;.&lt;/p&gt;
&lt;p&gt;Meanwhile, somewhere along the line, the Web had gotten very business like. Social media had lost any connection to the creativity, self expression, and weirdness that came before. Google had decided that not being evil wasn&#39;t good for their bottom line. The Web was starting to leave a bad taste in my mouth. It must have been about 2015 when I started my first Web boycott. I set about removing Google from my life. We were still in the fallout of the Snowden revelations, so this idea was very much in the air. It wasn&#39;t privacy concerns that lead me to take this action though. I was already somewhat of a grudging Google user at this point; the Google backlash simply made me reflect on what an absurdly big undertaking it seemed to stop using Google products. At the end of the day, it was the monopoly that irked me most. I started to wonder what the experience of degoogling my life would be like, so decided to find out. I have to admit that I have yet to complete this task, as I still have a functioning Android phone. So far though, it has been a wholly positive experience, not only do I feel better about the products I use, but almost across the board it has lead to me finding generally better products and services. If you are interested, I have started a &lt;a href=&quot;https://uninstall.tech/&quot;&gt;list of my favourite Google and Facebook alternatives&lt;/a&gt; (the domain buying habit continues).&lt;/p&gt;
&lt;p&gt;Avoiding the big tech players got me (back) into an indie mindset when it comes to the Web. This inevitably lead me to the &lt;a href=&quot;https://indieweb.org/&quot;&gt;IndieWeb&lt;/a&gt; movement. While I have yet to be directly involved in the IndieWeb community, I have been inspired by their ideas and principles. These principles, based around the idea of personal websites, seem geared towards building a Web more like the one I fell in love with. That in turn leads me to today, and the website you are (probably) reading this on. This site has been, and continues to be an attempt to rekindle a little bit of the magic of the early personal websites; as well as incorporate some of the forward thinking IndieWeb ideas, such as &lt;a href=&quot;https://indieweb.org/Webmention&quot;&gt;Webmentions&lt;/a&gt;. Stepping back from it for the first time I can see that I have a long way to go. I could certainly crank up the &lt;a href=&quot;https://whimsical.club/&quot;&gt;whimsy&lt;/a&gt;. In &lt;a href=&quot;https://makefrontendshitagain.party/&quot;&gt;the words of Sara Vieira&lt;/a&gt;, &amp;quot;We need to make dumb shit! Make useless stuff; make the web fun again!&amp;quot;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Enhance your web page transitions</title>
		<link href="https://smth.uk/enhance-your-web-page-transitions/"/>
		<updated>2020-05-24T00:00:00Z</updated>
		<id>https://smth.uk/enhance-your-web-page-transitions/</id>
		<content type="html">&lt;p&gt;Page transitions on the Web are typically very abrupt - you click a link, then the browser replaces the current page with the new one, as quickly as it can. This is a good starting point, and perhaps sometimes what we want, but a more gradual transition can be easier for people to follow. Visual transitions are what we are used to in the &amp;quot;real world&amp;quot;; sudden changes don&#39;t tend to happen, aside from perhaps a power outage (which is never welcome). Animating transitions can offer continuity and make it easier to retain context. In this article we are going to take some simple webpages, and progressively enhance the transitions, to take advantage of this.&lt;/p&gt;
&lt;p&gt;Mobile apps are full of animated transitions. It feels to me that most fundamental amongst these are slide and push animations. So things either slide in and out of view over the top of the current content, or they slide in and push the current content off the screen. To cover these fundamentals, we will incorporate four transitions into our pages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;slide up&lt;/li&gt;
&lt;li&gt;slide down&lt;/li&gt;
&lt;li&gt;push left&lt;/li&gt;
&lt;li&gt;push right&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is what we are aiming for:&lt;/p&gt;
&lt;video width=&quot;360&quot; height=&quot;640&quot; src=&quot;https://smth.uk/img/transitions-final.webm&quot; controls=&quot;&quot;&gt;
  Your browser does not support this video.
&lt;/video&gt;
&lt;p&gt;Our starting point is a collection of HTML pages (styled with CSS as you see fit). For the example in the video above this would be an index page and four subpages. The index page links to each subpage (the square icons). Each subpage links to the previous and next subpages, and back to the index page (the arrow icons). At this point we have a solid foundation to build upon, and not a million miles away from the finished interface.&lt;/p&gt;
&lt;video width=&quot;360&quot; height=&quot;640&quot; src=&quot;https://smth.uk/img/transitions-html.webm&quot; controls=&quot;&quot;&gt;
  Your browser does not support this video.
&lt;/video&gt;
&lt;p&gt;To add animation to our page transitions we essentially need to get the content from the new page into the current page, without a page reload. A common approach to this is to build a single page application (SPA), but full blown SPAs bring with them at best added fragility, and at worst a diminished user experience.&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;An escalator can never break – it can only become stairs. You would never see an “Escalator Temporarily Out Of Order” sign, just “Escalator Temporarily Stairs. Sorry for the convenience. We apologize for the fact that you can still get up there.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption class=&quot;blockquote_attribution&quot;&gt;— Mitch Hedberg&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For a progressive enhancement approach to this problem, we can use Barba.js - a small (7kb) JavaScript library for animating page transitions. To get started with Barba, we need some sort of JavaScript bundler, like Webpack or Rollup. &lt;a href=&quot;https://github.com/rollup/rollup-starter-app&quot;&gt;rollup-starter-app&lt;/a&gt; is a good boilerplate if you don&#39;t already have a JavaScript bundling build step. We also need NPM or Yarn to install the required packages.&lt;/p&gt;
&lt;p&gt;First we install Barba:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npm install @barba/core&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;By default Barba assumes we are going to use a JavaScript library for animation. Because we want to use CSS, we also need to install the CSS plugin:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npm install @barba/css&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;In our JS file, we import the packages, tell Barba to use the plugin, and initialise Barba:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; barba &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;@barba/core&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; css &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;@barba/css&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// tell Barba to use the css plugin&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;barba.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(css);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// init Barba&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;barba.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;We need to add a few things to our HTML so Barba understands the page structure. These things are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wrapper&lt;/code&gt; - wraps the whole page, typically added to the &lt;code&gt;body&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;container&lt;/code&gt; - defines the section of the page which needs to be replaced when we change page&lt;/li&gt;
&lt;li&gt;&lt;code&gt;namespace&lt;/code&gt; - allows us to define different groups of pages, so we can give them different transitions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these are added with data attributes, like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-barba&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;wrapper&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- content that will not change (in our case the header) --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-barba&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-barba-namespace&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;company&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- content that will be replaced when navigating --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- if we had a footer, it could go here --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;In the case of my example, I defined two namespaces, &lt;code&gt;company&lt;/code&gt; for the index page, and &lt;code&gt;product&lt;/code&gt; for the subpages. This enables us to specify transitions like so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;company to product = slide up&lt;/li&gt;
&lt;li&gt;product to company = slide down&lt;/li&gt;
&lt;li&gt;product to product = push left or right&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another way to determine what transition is applied is by looking at the link which was clicked. We will use this method to determine whether the push transition should be left or right. To do that we need to make sure that the next and previous links have a class or attribute to identify them as such. In my case I used &lt;code&gt;direction--prev&lt;/code&gt; and &lt;code&gt;direction--next&lt;/code&gt; classes.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;product-nav_item direction--prev&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;href&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s define those transitions now. We do that inside our &lt;code&gt;init&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// init Barba&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;barba.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;({&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  transitions: [{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    name: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;slide-up-&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;leave&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    from: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;company&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    to: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;product&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }, {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    name: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;slide-down-&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;leave&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    from: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;product&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    to: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;company&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }, {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    name: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;slide-left-&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;leave&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    from: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;custom&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: ({ &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;trigger&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; }) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; trigger.classList &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;&amp;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; trigger.classList.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;contains&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;direction--prev&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    to: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;product&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }, {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    name: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;slide-right-&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;leave&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    from: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;custom&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: ({ &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;trigger&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; }) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; trigger.classList &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;&amp;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; trigger.classList.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;contains&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;direction--next&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    to: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;product&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }]&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;There are four transitions configured here, each essentially containing a name, and conditions for when it should be used. The conditions are defined with the &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to&lt;/code&gt; rules. The simplest just using the namespaces, and a couple of them looking for those previous and next classes we set up earlier. The names given here are used by the Barba CSS plugin to create class names to use during transitions. For each transition defined, Barba will generate the following classes:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;]-leave {}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;]-leave-active {}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;]-leave-to {}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;]-enter {}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;]-enter-active {}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;]-enter-to {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;If you are wondering why I put hyphens at the end of my transition names, that&#39;s just a style preference. The resulting double hyphen in the class name, e.g &lt;code&gt;slide-up--leave&lt;/code&gt;, differentiates it from a component class in the &lt;a href=&quot;https://c3css.com/&quot;&gt;C3 CSS methodology&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once you&#39;ve added your bundled JavaScript to your pages, Barba should be up and running. You won&#39;t see much of a difference yet though, as the transitions have no styling. Let&#39;s add that in our CSS.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* Slide up / down */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-up--leave-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-up--enter-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transition&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: transform &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;250&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;ms&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.2&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-down--enter-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-down--leave-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transition&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: transform &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;ms&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.4&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-up--enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-down--leave-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-up--leave-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-down--enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* Slide left / right */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-left--leave-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-left--enter-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-right--leave-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-right--enter-active&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transition&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: transform &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;250&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;ms&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cubic-bezier&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.4&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.2&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-left--leave&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-left--enter-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-right--leave&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-right--enter-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;translateX&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-left--enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-right--leave-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;translateX&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;-100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-left--leave-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.slide-right--enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;translateX&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Here we are using transforms to move our container, dependant upon what transition is being used and the current stage of that transition. Probably the best way to get your head around when these classes are applied is to set a long transition duration then inspect the page and watch the classes being applied as you click around. The transition timings (easing) I&#39;m using here are taken from &lt;a href=&quot;https://material.io/design/motion/speed.html&quot;&gt;Material Design&lt;/a&gt;; you might want to look at &lt;a href=&quot;https://matthewlein.com/tools/ceaser&quot;&gt;other timings&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&#39;re getting close now. With this CSS added, you should now have something like this:&lt;/p&gt;
&lt;video width=&quot;360&quot; height=&quot;640&quot; src=&quot;https://smth.uk/img/transitions-js.webm&quot; controls=&quot;&quot;&gt;
  Your browser does not support this video.
&lt;/video&gt;
&lt;p&gt;It&#39;s starting to resemble what we are aiming for but with a couple of issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The icons disappear before we want them to when sliding up and down&lt;/li&gt;
&lt;li&gt;Pages sliding in from left / right don&#39;t do so until the current page has finished sliding out.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of these issues come down to the fact that the &lt;em&gt;leave&lt;/em&gt; and &lt;em&gt;enter&lt;/em&gt; parts of the animations are playing in sequence. What happens when we click a link is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Exit animation&lt;/li&gt;
&lt;li&gt;Content is replaced&lt;/li&gt;
&lt;li&gt;Enter animation&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This would make sense for some transition effects, but for all of ours we need this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;New content &lt;em&gt;added&lt;/em&gt; to the page&lt;/li&gt;
&lt;li&gt;Exit and enter animations play together&lt;/li&gt;
&lt;li&gt;Old content removed&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can switch to this behaviour by enabling &lt;a href=&quot;https://barba.js.org/docs/advanced/transitions/#Sync-mode&quot;&gt;Barba&#39;s Sync mode&lt;/a&gt;. To do that we need to add &lt;code&gt;sync: true&lt;/code&gt; to each of our transitions. For example:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;barba.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;({&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  transitions: [{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    name: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;slide-up-&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    sync: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;leave&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;enter&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;() {},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    from: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;company&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    to: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      namespace: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;product&#39;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }]&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Now we have the sequence of events that we want, but we also have some new challenges. Barba is giving us the content container from two pages at the same time, but that&#39;s as far as it is going to help us. We now have to figure out how to style the second container. Things get a little less elegant here. We have a new block of content dumped in the DOM, breaking our layout. What needs to be done with this is probably going to change depending on your design, but you are almost certainly going to need to set this new container to &lt;code&gt;position: absolute&lt;/code&gt;, which means it loses a lot of intrinsic sizing and positioning. We are going to need to do a little heavy lifting. Below is what I did. There are other ways to achieve the same thing; I&#39;d be interested to hear how you would improve it.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* second container */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;position&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* remove it from flow */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;top&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* position after header (which is 9rem tall) */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;min-height&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;vh&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* at least height of viewport minus the header */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;opacity&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* prevent flash of content before transition starts */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container.slide-down--enter-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container.slide-left--enter-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container.slide-right--enter-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container.slide-up--enter-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;opacity&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* while transition is active set opacity back to 1 */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.container.slide-down--enter-to&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;z-index&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;-1&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* this is later in the DOM but needs to sit behind */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;left&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* force full width grid */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;right&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;That was a nasty little hurdle at the end, but we are pretty much at the finish line. One last tip: if you want to apply specific outside of the container, styling while transitions are in progress (to hide overflow for example), you can use &lt;a href=&quot;https://barba.js.org/docs/advanced/hooks/&quot;&gt;hooks&lt;/a&gt; to add and remove classes:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;barba.hooks.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;before&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  document.body.classList.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;transitioning--true&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;});&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;barba.hooks.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;after&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  document.body.classList.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;remove&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;transitioning--true&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;And that&#39;s it - quick native-like transitions, added to some humble HTML pages. You can &lt;a href=&quot;https://uninstall.tech/facebook&quot;&gt;see the end result here&lt;/a&gt;, (needs narrow viewport to see the links).&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>A modern front-end workflow for Wordpress</title>
		<link href="https://smth.uk/a-modern-front-end-workflow-for-wordpress/"/>
		<updated>2020-02-05T00:00:00Z</updated>
		<id>https://smth.uk/a-modern-front-end-workflow-for-wordpress/</id>
		<content type="html">&lt;p&gt;For all intents and purposes, this is a first look at the Wordpress starter theme &lt;a href=&quot;https://roots.io/sage/&quot;&gt;Sage&lt;/a&gt;. I think I did, a long time ago, try an earlier incarnation of this theme, when it was called Roots, but I can&#39;t remember much about it (I must be going back the best part of a decade here). &lt;a href=&quot;https://roots.io/&quot;&gt;Roots&lt;/a&gt; is now a suit of Wordpress development tools, one of which being the starter theme, now known as Sage. Shortly after trying the original Roots, I for whatever reason switched to &lt;a href=&quot;https://underscores.me/&quot;&gt;Underscores&lt;/a&gt;, which I continued to use as a starter theme for many years. Underscores has served me well, and I&#39;ve not really had any major gripes with it; but when something recently drew my attention to Sage it made me (re)consider what I / Underscores was potentially missing. In short the missing pieces are a bunch of developer experience stuff, that we&#39;ve become used to, especially working with other stacks. Specifically that means a templating engine, and a configured build script with concatenation, minification and live reloading. If these are things you tend to add to your Wordpress workflow, or like me, you&#39;d quite like to have but not sure it&#39;s worth the setup time, then read on.&lt;/p&gt;
&lt;p&gt;With my interest piqued I needed something Wordpressy to build. I decided to make a little shop; then set about designing a couple of pages, to give myself something to work towards.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/hc-home.jpg&quot; width=&quot;1080&quot; alt=&quot;Web page showing mug for sale. It is branded Hate Capitalism&quot; /&gt;
&lt;p&gt;If you want to skip to the end result, it can be found at &lt;a href=&quot;https://hatecapitalism.com/&quot;&gt;hatecapitalism.com&lt;/a&gt; (since the time of writing this has been converted to a static site, and no longer uses Wordpress).&lt;/p&gt;
&lt;p&gt;Setting up your project is pretty straight forward. Recently I&#39;ve been using &lt;a href=&quot;https://localbyflywheel.com/&quot;&gt;Local by Flywheel&lt;/a&gt; as my local Wordpress environment, and I continued to do so here. New Sage projects are created with &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt; (which I ran outside of Local).&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;# wp-content/themes/&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;$ composer create-project roots/sage my-theme-name&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;During the setup you can choose to include one of a selection of CSS frameworks, but I opted for a blank slate. In your new project you run &lt;code&gt;yarn&lt;/code&gt; to install dependancies, then when you&#39;ve got got things configured &lt;code&gt;yarn start&lt;/code&gt; to run the development server. When running the dev server, you&#39;ll want to switch the to the BrowserSync address (localhost:3000 by default), not only because this is where the live reloading happens, but once run, your updated assets do not exist in their build location. To build your assets, so they are available at my-new-site.local you need to run &lt;code&gt;yarn build&lt;/code&gt;. When you&#39;re ready to go live &lt;code&gt;yarn build:production&lt;/code&gt;. I suggest reading the &lt;a href=&quot;https://roots.io/sage/docs/&quot;&gt;docs&lt;/a&gt; before getting started. I found them to be pretty good, if maybe a little thin, given how much there is to cover. The &lt;a href=&quot;https://discourse.roots.io/&quot;&gt;forum&lt;/a&gt; does a good job of bolstering the docs, should you be left wanting.&lt;/p&gt;
&lt;p&gt;Once up and running I had a couple of little niggles with dependancies being out of date. I quickly found that I couldn&#39;t disable the Webpack specific Browsersync (in browser) notifications. There wasn&#39;t much recourse for this as the &lt;a href=&quot;https://github.com/qwp6t/browsersync-webpack-plugin&quot;&gt;plugin being used&lt;/a&gt; is no longer maintained. If this is the only problem that this plugin causes, then it&#39;s not too big of a deal (I can hide the notifications with CSS, I guess), but a bit of a concern. Less of a concern was Stylelint flagging stuff that it shouldn&#39;t be, like the &lt;code&gt;system-ui&lt;/code&gt; font-family keyword. Updating Stylelint resolved that problem.&lt;/p&gt;
&lt;p&gt;On to the good stuff - as I thought would be the case, having a templating language in place was nice. I&#39;ve never used a templating language in Wordpress before, frankly because I&#39;ve never really felt the need enough to warrant looking into it. Sage uses &lt;a href=&quot;https://laravel.com/docs/5.8/blade&quot;&gt;Laravel&#39;s Blade templates&lt;/a&gt; out of the box, so you get templating for free. The main benefit of using a templating language, such as Blade, is the ability to define, inherit and extend layouts. Many of us are used to working in this way, via various templating languages, in other environments, whether that be Liquid templates in Jekyll or Jinja templates in a Python project. A secondary advantage is less opening and closing of &lt;code&gt;PHP&lt;/code&gt; tags in your templates, specifically when echoing variables:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello &amp;lt;?php echo $name; ?&amp;gt;.&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Note from shiki-twoslash: the language blade was not set up for Shiki to use, and so there is no code highlighting --&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Hello {{ $name }}.&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Note from shiki-twoslash: the language blade was not set up for Shiki to use, and so there is no code highlighting --&gt;
&lt;p&gt;Blade also gives you &amp;quot;shortcuts&amp;quot; for common PHP control structures; for example you can put if statements and loops right in your templates.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;@if($products)
  &amp;lt;ul&amp;gt;
  @foreach($products as $i=&amp;gt;$product)
    &amp;lt;li&amp;gt;{{ $product-&amp;gt;name }}&amp;lt;/li&amp;gt;
  @endforeach
  &amp;lt;/ul&amp;gt;
@endif&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Note from shiki-twoslash: the language blade was not set up for Shiki to use, and so there is no code highlighting --&gt;
&lt;p&gt;When you need to, breaking into regular PHP is easy; you just wrap it like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;@php
  //php here
@endphp&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Note from shiki-twoslash: the language blade was not set up for Shiki to use, and so there is no code highlighting --&gt;
&lt;p&gt;I found myself doing this out of habit - I wrote a little switch statement (to handle the words that come before the price on the home page) before realising that Blade has its own syntax for this. If you&#39;re going to put such things in your templates though, I don&#39;t think using one syntax over the other will make a huge difference to the cleanliness of those templates.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;@php
  switch ($i) {
    case 1:
      First case...
      break;
    case 2:
      Second case...
      break;
    default:
      Default case...
      break;
  }
@endphp&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Note from shiki-twoslash: the language blade was not set up for Shiki to use, and so there is no code highlighting --&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;@switch($i)
  @case(1)
    First case...
    @break
  @case(2)
    Second case...
    @break
  @default
    Default case...
@endswitch&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Note from shiki-twoslash: the language blade was not set up for Shiki to use, and so there is no code highlighting --&gt;
&lt;p&gt;When it came to writing styles I felt at home working with CSS in Sage. First of all, this is probably the point when you appreciate that Sage has BrowserSync ready to go, out of the box. In addition to that, Sass and PostCSS are wired up in a Webpack configuration. If I were constructing this build process from scratch I would probably forgo Sass in favour of PostCSS plugins, and opt for  something less gnarly than Webpack, but I think the choices here are reasonable, and given that they are configured for us, I&#39;m perfectly happy to use them.&lt;/p&gt;
&lt;p&gt;The Sage build process really started to shine when it came to adding Javascript. Sage provides DOM-based routing, giving you an easy way to specify which scripts run on what pages. For example, if I wanted the Javascript for the slider on my homepage to only run the homepage, that can be achieved pretty much just by putting it in a file named &lt;code&gt;home.js&lt;/code&gt; (the is based on body classes, of which &lt;code&gt;home&lt;/code&gt; is one). Global Javascript, such as the slide-out navigation for example, lives in &lt;code&gt;common.js&lt;/code&gt;. From a developer experience point of view, I found this to be a really nice answer to the question of what to do with page specific Javascript. From a user experience point of view, the appropriateness of this technique will vary with each project. You will need to consider whether putting all the Javascript in a single file the best approach.&lt;/p&gt;
&lt;p&gt;Ironically, given that this was an exercise in exploring a Wordpress starter theme, I felt like I didn&#39;t spend much time engaging with Wordpress while working on this little &lt;a href=&quot;https://hatecapitalism.com/&quot;&gt;project&lt;/a&gt;. That is perhaps the biggest compliment I could give Sage, it puts a layer of modern tooling between you and Wordpress. I still had the odd Wordpress moment, like writing a PHP function in order to change the contents of the &lt;code&gt;title&lt;/code&gt; tag, but for the most part I felt free to focus on the sort of front-end stuff that I wanted to be focusing on. That was a breath of fresh air.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Use design tokens to customise Bootstrap</title>
		<link href="https://smth.uk/use-design-tokens-to-customise-bootstrap/"/>
		<updated>2020-01-12T00:00:00Z</updated>
		<id>https://smth.uk/use-design-tokens-to-customise-bootstrap/</id>
		<content type="html">&lt;p&gt;If you are creating a customised version of Bootstrap, and especially if you intend to use it for more than one website / app, I think design tokens can make for a nice authoring experience, as well as bring a bit of future-proofing along for free. This is the approach I took with a recent project; if you just want to see what I did, skip down to .. &lt;a href=&quot;https://smth.uk/use-design-tokens-to-customise-bootstrap/#what-i-did&quot;&gt;What I did&lt;/a&gt;. First, a little about how I arrived at this method.&lt;/p&gt;
&lt;p&gt;I was working on a project which involved updating the visual identity of two websites, which share that visual identity. The two codebases were pretty disparate, though they were both built on Bootstrap. A benefit of using a framework such as Bootstrap is that you can create a custom version then not only use it to build one site, but reuse it to build other sites with the same visual identity.&lt;/p&gt;
&lt;p data-quote=&quot;The problem is that this single source of truth is heavily tied into Bootstrap.&quot;&gt;There are various approaches to sharing a customised Bootstrap between sites. The worst case scenario (which was the case here) is that you rely on those maintaining the sites to make sure that they are visually consistent. Achievable but inefficient. Another approach I&#39;ve seen is to compile your bespoke Bootstrap then share that code between sites, probably via a CDN. There is value in the CDN here, but more often than not I think this will lead to you having to override your shared Bootstrap styles with site specific ones. This is where frameworks start creating more problems than they solve, in my opinion - causing bloated and overly complicated code. An approach I have favoured in the past is to just maintain a version of the Bootstrap SCSS variables file which can be included into each site&#39;s main SCSS file, along with a freshly NPM installed Bootstrap. This is a clean, simple, and flexible approach, but there is room for improvement. If you have taken this approach, you have potentially created a single source of truth for the brand&#39;s styles. Nice. The problem is that this single source of truth is heavily tied into Bootstrap. Even if you have taken the time make your &lt;code&gt;variables.scss&lt;/code&gt; more versatile with additional, less bootstrapy variables; you are still tied into SCSS at this point. The danger here is that if/when you build something without SASS, not only is your single source of truth going to be of limited use, you are probably going to stop caring about maintaining it.&lt;/p&gt;
&lt;h2 id=&quot;design-tokens&quot;&gt;Design tokens &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/use-design-tokens-to-customise-bootstrap/#design-tokens&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is where design tokens come in. Design tokens simply offer an agnostic way to store variables. That is to say, those variables can in theory be used in any project, regardless languages involved. A clear use-case for design tokens is to share variables (or tokens) between a web project and a native mobile project. It might sound like over-engineering to use design tokens just to generate Bootstrap variables, but the additional setup is small, and to me the workflow felt good.&lt;/p&gt;
&lt;h2 id=&quot;what-i-did&quot;&gt;What I did &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/use-design-tokens-to-customise-bootstrap/#what-i-did&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I used &lt;a href=&quot;https://amzn.github.io/style-dictionary&quot;&gt;Style Dictionary&lt;/a&gt; to transform my tokens into SASS variables. I created a new &lt;code&gt;package.json&lt;/code&gt; (&lt;code&gt;npm init&lt;/code&gt;) for my design tokens project, and added Style Dictionary as a dev dependancy:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npm install -D style-dictionary&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Style Dictionary has a &lt;a href=&quot;https://amzn.github.io/style-dictionary/#/quick_start?id=creating-a-new-project&quot;&gt;command to create a starter project&lt;/a&gt;, which you might find useful. Here though I will detail the project structure I used for this particular use-case. The first thing you need in your project is a &lt;code&gt;config.json&lt;/code&gt;. In this file you tell Style Dictionary what exactly you want outputted (and to where). Here&#39;s what you need for our purposes:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;json&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;source&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;properties/**/*.json&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;],&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;platforms&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;scss&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;transformGroup&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;scss&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;buildPath&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;build/scss/&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;files&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: [{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;destination&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;_variables.scss&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;format&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;scss/variables&quot;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      }]&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This tells Style Dictionary to look in the &lt;code&gt;properties&lt;/code&gt; folder (which we haven&#39;t made yet), convert the properties there to SCSS variables, in a file named &lt;code&gt;_variables.scss&lt;/code&gt;, at the path &lt;code&gt;build/scss&lt;/code&gt;. Tweak this as you please.&lt;/p&gt;
&lt;p&gt;Now for those properties. My preference here was to first create non-Bootstrap specific variables, then reference these in my Bootstrap variables. I like having a versatile and consistently named collection of variables (not limited by the constraints of Bootstrap), to use for any additional styles that need to be written. Style Dictionary comes with a suggestion about about how you structure your properties, and thus, what your variables will be named. You do not need to follow this suggestion, but doing so gives you access to some helpers. For example you can convert colour values from one format to another. I found the suggested structure to be sensible, and pretty close to what I would have naturally adopted for my non-Bootstrap variables. So I ran with it, without looking too much into the perks. The suggested property structure is &lt;code&gt;Category / Type / Item&lt;/code&gt;. A SASS variable following this structure would look like &lt;code&gt;$size-font-small&lt;/code&gt;, or &lt;code&gt;$color-blue-base&lt;/code&gt;. &lt;code&gt;size&lt;/code&gt; and &lt;code&gt;color&lt;/code&gt; being the &lt;em&gt;categories&lt;/em&gt;, &lt;code&gt;font&lt;/code&gt; and &lt;code&gt;blue&lt;/code&gt; being &lt;em&gt;types&lt;/em&gt;, and &lt;code&gt;small&lt;/code&gt; and &lt;code&gt;base&lt;/code&gt; being &lt;em&gt;items&lt;/em&gt;. If this is confusing or throws up questions, I suggest you either check out the &lt;a href=&quot;https://amzn.github.io/style-dictionary/#/properties?id=category-type-item&quot;&gt;docs&lt;/a&gt;, or just put it to the back of your mind. You don&#39;t really need to understand this structure to get going; I think it&#39;s worth mentioning though, so you know how I decided to structure my properties. With that said, let&#39;s create those properties. My &lt;code&gt;properties&lt;/code&gt; folder looked something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|-- bootstrap&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|   |-- color.json&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|   |-- headings.json&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|   |-- link.json&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|-- size&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|   |-- font.json&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|   |-- spacing.json&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|-- color.json&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;|-- font.json&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;The properties are stored in multiple files, and split into subdirectories for ease of maintenance (this is another reason why I like this design token approach). I don&#39;t believe there is any reason you couldn&#39;t store all your properties in a single JSON file, if you wanted to. Each JSON file follows the same format. Let&#39;s look at &lt;code&gt;color.json&lt;/code&gt; as an example:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;json&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;color&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;gray&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;#F6F6F6&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;#939598&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;900&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;#231f20&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;blue&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;base&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;#00D1FF&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;text&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;base&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;{color.gray.900.value}&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;decoration&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;{color.blue.base.value}&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Any object in the JSON that has a &lt;code&gt;value&lt;/code&gt; attribute is a &lt;em&gt;property&lt;/em&gt;. So &lt;code&gt;color.gray.100&lt;/code&gt; is a property, as is &lt;code&gt;color.blue.base&lt;/code&gt;. In terms of SASS variables, these will output as:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;scss&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #953800&quot;&gt;$color-gray-100: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;#f6f6f6&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #953800&quot;&gt;$color-blue-base: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;#00d1ff&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;You can see in the above example that you can reference other properties; so &lt;code&gt;$color-text-base&lt;/code&gt; will have the same value as &lt;code&gt;$color-gray-900&lt;/code&gt;. The &lt;code&gt;size&lt;/code&gt; directory can be thought of as a &lt;code&gt;size.json&lt;/code&gt; file split into two smaller files. Both the JSON files within that directory have &lt;code&gt;size&lt;/code&gt; as the top level object.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;json&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;font&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;sm&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;0.875&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;base&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;lg&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;1.125&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;json&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;size&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;spacing&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;sm&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;base&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;lg&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;1.5&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Note that these &lt;code&gt;size&lt;/code&gt; properties do not include units (px, rem etc). Because I am using the &lt;code&gt;size&lt;/code&gt; category, units get added by Style Dictionary. For SCSS, the default is &lt;code&gt;rem&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For my Bootstrap properties, I stopped thinking about the &lt;code&gt;Category / Type / Item&lt;/code&gt; structure and focused on generating the required variable names (I found &lt;a href=&quot;https://bootstrapvars.com/&quot;&gt;bootstrapvars.com&lt;/a&gt; to be a useful reference here). You can organise these properties how you like, I mostly named the JSON files after the first word in the variable name. For example &lt;code&gt;headings.json&lt;/code&gt; could contain properties for &lt;code&gt;$headings-font-family&lt;/code&gt;, &lt;code&gt;$headings-font-weight&lt;/code&gt;, &lt;code&gt;$headings-line-height&lt;/code&gt;	 etc. Because I had already created a comprehensive set of variables, no new values were included in these Bootstrap properties - they were all aliases of existing properties. This may not be the case for you, and if you are only interested in creating Bootstrap specific variables, you could skip straight to this part and include actual values here.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;json&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;headings&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;font&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;family&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;{font.family.base.value}&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;comment&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Bootstrap&quot;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      },&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;weight&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;{font.weight.black.value}&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;&quot;comment&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Bootstrap&quot;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;I used Style Dictionary&#39;s comment feature to add a comment to each Bootstrap property, so it could be recognised as such in the outputted &lt;code&gt;_variables.scss&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Once you have your properties defined, you can generate your SCSS file with:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npx style-dictionary build&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;That will generate the file at the path specified in your config. That file is now ready to be included in your Bootstrap builds. There are a few ways you could get it into your project. I included the whole design tokens repo as a Git subtree, so I could continue to build the variables from within the Bootstrap project, and push the changes back. I had my task runner watch the design tokens directory, and run the build command from there.&lt;/p&gt;
&lt;p&gt;What is primarily achieved by following this method is the ability to easily build your variables into a different format, CSS custom properties for example. Even without taking advantage of that though, I found the structure described above, and the JSON format made for a nice way to structure and keep track of the large number of variables that a customised Bootstrap tends to require.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Top static site generators of 2019</title>
		<link href="https://smth.uk/top-static-site-generators-of-2019/"/>
		<updated>2019-12-20T00:00:00Z</updated>
		<id>https://smth.uk/top-static-site-generators-of-2019/</id>
		<content type="html">&lt;p&gt;Recently someone commented that I seem to use a different static site generator (SSG) for every project. This prompted a conversation about the pros and cons of sticking with a familiar stack VS trying something new. I explained my position - for projects that are time sensitive (most projects) I prefer to use technologies that are familiar and predictable to me. However, for projects where I have more freedom, i.e personal projects, I like to try new things. And yes, I have a bit of a thing for SSGs. It&#39;s only through trying new things that you can find and familiarise yourself with those killer solutions, that you&#39;ll come to rely on later. I think SSGs are a great example of this. There are lots of products that we call static site generators, and they differ greatly. I like to keep my hand in with a few, so I know what to reach for when I don&#39;t have the luxury of time to experiment.&lt;/p&gt;
&lt;p&gt;I wrote a &lt;a href=&quot;https://smth.uk/welcome-to-jekyll/&quot;&gt;similar post&lt;/a&gt; to this back in early 2016; I thought an interesting way to frame this today might be to look at how the landscape and my preferences have changed since then. One of the points I made in that 2016 post was that I hadn&#39;t found a non-developer friendly way to manage content for static sites. Maybe I wasn&#39;t looking in the right places, but it feels like this is an area that has really improved since then. Headless CMSs are very much part of the &lt;a href=&quot;https://cdn-images-1.medium.com/max/1200/1*R65rmc0x432_s9EmAbGlOA.png&quot;&gt;JAMstack landscape&lt;/a&gt;, of which SSGs are now almost synonymous. This brings me to my first SSG mention:&lt;/p&gt;
&lt;h2 id=&quot;gridsome&quot;&gt;Gridsome &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/top-static-site-generators-of-2019/#gridsome&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Getting your data from an external source (such as a headless CMS) can be a little fiddly. Some SSGs are more focused on making this easier than others. I don&#39;t have a huge amount of experience with &lt;a href=&quot;https://gridsome.org/&quot;&gt;Gridsome&lt;/a&gt;, but enough to know that CMSs feel like first-class citizens here. It&#39;s early days, but the &lt;a href=&quot;https://gridsome.org/starters/&quot;&gt;&lt;em&gt;Starters&lt;/em&gt; page&lt;/a&gt; at least sets out a direction for ready-made integrations with a really good selection of content / data sources. To try this out, I recreated a &lt;a href=&quot;https://smth.uk/reviews/&quot;&gt;simple site&lt;/a&gt; I had previously made with &lt;a href=&quot;https://nuxtjs.org/&quot;&gt;Nuxt&lt;/a&gt;. Like Nuxt, Gridsome is &lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; based, which made this migration quick and easy. It&#39;s worth mentioning that the two versions are different in that the Nuxt version was server side rendered, while Gridsome creates pre-rendered HTML. That said, the code required to fetch and query the data felt much simpler with Gridsome, thanks to the CMS specific plugin, and the leveraging of GraphQL. If you&#39;re into JavaScript frameworks, and in particular Vue, this is a SSG to keep an eye on.&lt;/p&gt;
&lt;p&gt;While I wasn&#39;t strictly integrating CMSs with static sites in 2016, I was pulling data from APIs. This is a staple of JAMstack today, but just a few years ago the ability to pre-render HTML from remote APIs didn&#39;t feel like a common SSG feature. In fact, one of the SSGs I mentioned in the 2016 post, I chose purely for this feature. That SSG was &lt;em&gt;Roots&lt;/em&gt;, which is no longer under active development. At the time I used it to build my &lt;a href=&quot;https://samsmith.name/&quot;&gt;portfolio site&lt;/a&gt;. Today I use my next SSG mention:&lt;/p&gt;
&lt;h2 id=&quot;hugo&quot;&gt;Hugo &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/top-static-site-generators-of-2019/#hugo&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt;, much like many modern SSGs offers the ability to work with remote data. It does so via its &lt;code&gt;getJSON&lt;/code&gt; and &lt;code&gt;getCSV&lt;/code&gt; functions. What perhaps sets Hugo apart from other SSGs is that this, and other common features are ready to use, out of the box. So whether you want taxonomies, shortcodes, word count, theming - these things are all ready to go in your freshly created Hugo site. For a lot of use cases, you only need to concern yourself with templating. About those templates though, Hugo uses Go&#39;s templating language, so unless you are familiar with Go, templating logic will take a bit of getting used to. I didn&#39;t find this to be too much of a pain, I do however think the templating in Hugo is the thing most likely to put me off reaching for it. Not so much because you need to work with the ways of Go, but because I&#39;ve found myself tending to put a lot of logic and variables in these templates at times, which while gets the job done, leads to messy and complicated templates. If I&#39;m going to pinpoint what is most likely to put me off using Hugo, I should say what is most attractive about it. Besides being feature rich and capable, I think the community might be the biggest attraction. The Hugo website has a dedicated and active forum, where in my experience, your questions will be answered. I much prefer the forum format over something like a Discord or Gitter, which seem to be popular with other projects.&lt;/p&gt;
&lt;p&gt;In 2016 I mentioned two other SSGs, Jekyll, which was powering my &lt;a href=&quot;https://smth.uk/&quot;&gt;blog&lt;/a&gt; at the time, and Middleman, which I identified as my go-to SSG. These two have in common their dependancy on Ruby. This commonality is a significant factor in why I no longer use them. After using Jekyll for many years, a macOS update broke Jekyll on my machine. I was only maintaining one Jekyll site (my blog) by this time, so after spending a significant amount of time troubleshooting I decided it would be quicker to just rebuild my blog with a different SSG. I don&#39;t imagine this extreme scenario is common, but I think some consideration should be given to whether you want to setup / maintain a Ruby development environment, just for static sites. This is probably in part why out of the top ten SSGs on &lt;a href=&quot;https://www.staticgen.com/&quot;&gt;staticgen.com&lt;/a&gt; eight are written in JavaScript. As it turns out, since moving away from Jekyll I haven&#39;t looked back. The SSG that now powers my blog, has become my new go-to SSG (so I guess its a sort of winner). That SSG is:&lt;/p&gt;
&lt;h2 id=&quot;eleventy&quot;&gt;Eleventy &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/top-static-site-generators-of-2019/#eleventy&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Coming back to my point about trying new things - finding an excuse to try &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;Eleventy&lt;/a&gt; was really worthwhile. Not only did I find it to be a good drop-in replacement for Jekyll, but having made a few sites with it I found it to be very versatile. Versatility runs right through Elevently. If you are making something simple, it can get out of the way, with zero configuration; making something more complex, it can be very powerful. The options available for working with data I&#39;ve found to be particularly powerful. JavaScript data files mean you can prepare your data in any way that JavaScript allows, and make it available to your templates. The versatility extends to the templating language too, you can configure Eleventy to use the languages you want. No more putting up with what the SSG dictates. What I think Eleventy generally does really well is allow you to bend and shape it to your needs. It doesn&#39;t really presuppose anything about your code. I would say this is less true of other SSGs, to varying degrees. Something like Gridsome is dictating a lot, you are definitely building a Vue app in that case. Hugo on the other hand doesn&#39;t necessarily dictate the code that reaches the browser, but your templates will probably be less concise, as you jump though Hugos hoops. If you don&#39;t mind doing your own wiring, and you value elegance and simplicity, then Eleventy should be on your shortlist of SSGs.&lt;/p&gt;
&lt;h2 id=&quot;honorable-mention&quot;&gt;Honorable mention &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/top-static-site-generators-of-2019/#honorable-mention&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A lot has changed in SSG land in a past few years, including my preferred tools. I was wondering if there are any SSGs I was using in 2016 that I would still use today. I could think of one: &lt;a href=&quot;https://www.getlektor.com/&quot;&gt;Lektor&lt;/a&gt;. I don&#39;t think Lektor has changed much over those years, and it feels kind of pre JAMstack. That said, the value it had to me in 2016 it still has now. Lektor is a static content management system, it only deals with flat-file data. What makes Lektor interesting is while most SSGs tend to be centred around Markdown files with metadata, Lektor has its own file format which allows any number of fields. It&#39;s like the difference between Wordpress with and without &lt;a href=&quot;https://www.advancedcustomfields.com/&quot;&gt;Advanced Custom Fields&lt;/a&gt;. You even get an admin GUI to edit the content once the fields are configured. I find the idea of a very simple setup for a site where pages can be configured to have any combination of fields to be quite liberating; I can see myself using Lektor again in the future.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Building a swipeable card stack</title>
		<link href="https://smth.uk/building-a-swipeable-card-stack/"/>
		<updated>2019-10-07T00:00:00Z</updated>
		<id>https://smth.uk/building-a-swipeable-card-stack/</id>
		<content type="html">&lt;p&gt;I&#39;ve been waiting for an opportunity to dip my toe into some &lt;a href=&quot;https://svelte.dev/&quot;&gt;Svelte&lt;/a&gt; for a while. Faced with a little free time, I decided to create that opportunity. For anyone who hasn&#39;t heard of Svelte, it is a JavaScript / component framework, along the lines of React and Vue, but with an added compile step at build time. So what did I decide to use it for? Inspired by &lt;a href=&quot;https://css-tricks.com/swipeable-card-stack-using-vue-js-and-interact-js/&quot;&gt;this post by Mateusz Rybczonek&lt;/a&gt;, I set myself the challenge of building a swipeable card stack interface. You can see the result &lt;a href=&quot;https://36q.app/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this article I will explain the steps I took in building the above interface, and detail some of the approaches I took.&lt;/p&gt;
&lt;h2 id=&quot;step-1%3A-sapper&quot;&gt;Step 1: Sapper &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/building-a-swipeable-card-stack/#step-1%3A-sapper&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I really like static site generators (SSG), and will usually reach for one if a project has static content (such as this one). Fortunately there is a Svelte based SSG; its called &lt;a href=&quot;https://sapper.svelte.dev/&quot;&gt;Sapper&lt;/a&gt;. The &lt;a href=&quot;https://github.com/sveltejs/sapper-template&quot;&gt;Sapper template&lt;/a&gt; makes a pretty good starting point for a project like this, and comes in Rollup and Webpack variants. I went for Rollup, getting up and running like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npx degit &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;sveltejs/sapper-template#rollup&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; my-app&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; my-app&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npm install&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npm run dev&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;There were a few things in this template that I didn&#39;t need, which were either deleted or repurposed. The &lt;code&gt;about&lt;/code&gt; and &lt;code&gt;blog&lt;/code&gt; routes were removed, but not before repurposing &lt;code&gt;blog/_posts.js&lt;/code&gt;, &lt;code&gt;blog/index.json.js&lt;/code&gt; and &lt;code&gt;blog/index.svelte&lt;/code&gt; to deliver the content for my app.&lt;/p&gt;
&lt;p&gt;I used the included &lt;code&gt;Nav&lt;/code&gt; component as a guide to creating my first Svelte component, the only component in this app. I&#39;ll get back to that in a moment.&lt;/p&gt;
&lt;h2 id=&quot;step-2%3A-(optional)-postcss&quot;&gt;Step 2: (optional) PostCSS &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/building-a-swipeable-card-stack/#step-2%3A-(optional)-postcss&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like processing my styles with &lt;a href=&quot;https://postcss.org/&quot;&gt;PostCSS&lt;/a&gt;, I tend to use &lt;a href=&quot;https://preset-env.cssdb.org/&quot;&gt;preset-env&lt;/a&gt; to enable nesting and autoprefixing. I used &lt;a href=&quot;https://github.com/langbamit/sapper-postcss-tailwind-rollup/commit/9d436a85530fca654882c8f9ece8ace7778aa22b&quot;&gt;this Tailwind template&lt;/a&gt; as a guide to set this up with Sapper. Installing the required/desired packages, editing the Rollup config, and importing the CSS file into &lt;code&gt;server.js&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npm install --save-dev postcss postcss-import rollup-plugin-postcss svelte-preprocess postcss-preset-env cssnano&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// rollup.config.js&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; getPreprocessor &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;svelte-preprocess&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; postcss &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;rollup-plugin-postcss&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; path &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;path&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;postcssPlugins&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; [&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;postcss-import&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;)(),&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;postcss-preset-env&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;)({&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    features: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;nesting-rules&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;true&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }),&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;cssnano&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;)()&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;preprocess&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;getPreprocessor&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;({&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	transformers: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		postcss: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			plugins: postcssPlugins&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;});&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;default&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #953800&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;client: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		plugins: [&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;postcss&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;({extract: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;svelte&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;({&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				preprocess&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			}),&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		],&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	}&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #953800&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;server: {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		plugins: [&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;postcss&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;({&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				plugins: postcssPlugins,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				extract: path.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(__dirname, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;./static/global.css&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			})&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		],&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	}&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #953800&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #953800&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;(Add styles to &lt;code&gt;src/css/main.css&lt;/code&gt;)&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;js&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// src/server.js&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;./css/main.css&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// ...&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Its worth noting that using this particular approach means you won&#39;t be taking advantage of Sapper&#39;s code splitting when it comes to CSS, but given that this would be a single page app, I didn&#39;t see that as being an issue.&lt;/p&gt;
&lt;h2 id=&quot;step-3%3A-creating-the-card-component&quot;&gt;Step 3: Creating the Card component &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/building-a-swipeable-card-stack/#step-3%3A-creating-the-card-component&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There will be multiple cards in this interface, so it makes sense to create a component for them. This simply needs to be a template with some props, like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;svelte&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- components/Card.svelte --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; isCurrent;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; cardContent;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;card&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-dragging&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-status&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;{&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;isCurrent &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;current&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;waiting&#39;}&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;card_content&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;{cardContent}&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;I&#39;ve given the card a class so it can be styled as such, plus a couple of data attributes to hold some contextual information that will become useful later. All three attributes could be handled with classes, but I like to use a different syntax for contextual stuff to &lt;a href=&quot;https://c3css.com/&quot;&gt;make my CSS easier to read&lt;/a&gt;. You might also think that the JavaScript to handle the dragging etc should live in this file. When I tried this I found that the script would run for each instance of the component (which is not what I wanted). There&#39;s probably a way of making it behave as I wanted, but as I had a layout template not really being used for much, I decided to put all the logic there.&lt;/p&gt;
&lt;p&gt;If you were writing your CSS inside the component, it would live in a &lt;code&gt;style&lt;/code&gt; tag within this file. My CSS lives in a good old CSS file. Its pretty simple so I won&#39;t go over it here. Essentially I have a fixed size &lt;code&gt;card&lt;/code&gt; component, absolutely positioned.&lt;/p&gt;
&lt;h2 id=&quot;step-4%3A-putting-your-cards-on-the-table&quot;&gt;Step 4: Putting your cards on the table &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/building-a-swipeable-card-stack/#step-4%3A-putting-your-cards-on-the-table&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;code&gt;index.svelte&lt;/code&gt; I add instances of the &lt;code&gt;Card&lt;/code&gt; component to the page. As mentioned earlier, I made use of the blog code to store the content of each card in an array, which I then iterated over like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;svelte&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;{#&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; cards &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; card, i}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;Card&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cardContent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={card.content} &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;isCurrent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={i &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;{/&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Setting &lt;code&gt;isCurrent&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; for the first item in the array. For simplicity you might just want to put the cards directly into this page:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;svelte&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;Card&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cardContent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;One&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;isCurrent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;Card&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cardContent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Two&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;isCurrent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;Card&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;cardContent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;Three&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;isCurrent&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;={&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;In either case, you also need to import the component into the page:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;svelte&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; Card &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;../components/Card.svelte&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h2 id=&quot;step-5%3A-draggable-cards&quot;&gt;Step 5: Draggable cards &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/building-a-swipeable-card-stack/#step-5%3A-draggable-cards&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now for the fun stuff, the interactivity. I put all the interactivity logic in my &lt;code&gt;_layout.svelte&lt;/code&gt; file, which until this point was pretty much empty. The dragging relies on &lt;a href=&quot;https://interactjs.io/&quot;&gt;interact.js&lt;/a&gt; which we need to add to our project before importing into our template.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;shell&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;npm install --save-dev interactjs&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;The basis for the below code is the dragging example given on the interact.js website. The alterations and additions I will outline here. First thing to note is in Svelte anything that relies on the DOM being ready goes inside an &lt;code&gt;onMount&lt;/code&gt; function. To use this function, we first need to &lt;code&gt;import { onMount } from &#39;svelte&#39;&lt;/code&gt;. I took the concept of &amp;quot;interact threshold&amp;quot; and how that relates to rotation from Mateusz Rybczonek&#39;s article. &lt;code&gt;interactThreshold&lt;/code&gt; represents how far a card needs to be dragged before it is considered dismissed. The interact.js example stores the draggable objects position in data attributes, and adds inline styles to transform its position. Preferring to keep the styles in the style sheet, I used CSS custom properties to store these variables, which are referenced in the CSS. To access the custom properties in the JavaScript, I used &lt;a href=&quot;https://hankchizljaw.com/wrote/get-css-custom-property-value-with-javascript/#heading-the-getcsscustomprop-function&quot;&gt;Andy Bell&#39;s getCSSCustomProp function&lt;/a&gt;. Finally, inside the &lt;code&gt;onend&lt;/code&gt; function, we check whether the card has moved a sufficient amount to dismiss. If so we remove its &lt;code&gt;current&lt;/code&gt; status and give it to the next card. We also move it off the screen to the left or right, depending on whether its &lt;code&gt;x&lt;/code&gt; coordinate is positive or negative. If the card has not moved a sufficient amount, we reset its position and rotation custom properties.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;svelte&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;context&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; interact &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;interactjs&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; { onMount } &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;svelte&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;interactThreshold&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;interactMaxRotation&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// https://hankchizljaw.com/wrote/get-css-custom-property-value-with-javascript/#heading-the-getcsscustomprop-function&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;getCSSCustomProp&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;propKey&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;element&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; document.documentElement, &lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;castAs&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;string&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; response &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;getComputedStyle&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(element).&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;getPropertyValue&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(propKey);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// Tidy up the string if there&#39;s something to work with&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (response.&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			response &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; response.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;replace&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;&#92;&#39;&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;/&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// Convert the response into a whatever type we wanted&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;switch&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (castAs) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;number&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;int&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(response, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;float&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;parseFloat&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(response, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;boolean&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;case&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;bool&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; response &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;true&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; response &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;1&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// Return the string response by default&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; response;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	};&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;dragMoveListener&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; target &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; event.target&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// keep the dragged position in the custom properties&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;getCSSCustomProp&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-x&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, target, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;float&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; event.dx&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		y &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;getCSSCustomProp&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-y&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, target, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;float&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; event.dy&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// add rotation based on card position&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; interactMaxRotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; interactThreshold);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; interactMaxRotation) rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; interactMaxRotation;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;interactMaxRotation) rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;interactMaxRotation;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// update styles&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		target.style.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-x&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;px&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		target.style.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-y&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, y &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;px&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		target.style.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-r&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;deg&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;onMount&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// get viewport width&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;vw&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; document.documentElement.clientWidth;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// create an off canvas x coordinate&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; offX &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (vw &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			offX &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; vw;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// interact.js&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;interact&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;.card[data-status=&quot;current&quot;]:not(:last-child)&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;draggable&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;({&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;onstart&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: () &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// signify dragging&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				event.target.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;data-dragging&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			},&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// call this function on every dragmove event&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			onmove: dragMoveListener,&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// call this function on every dragend event&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;onend&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: (&lt;/span&gt;&lt;span style=&quot;color: #953800&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// signify dragging stopped&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				event.target.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;data-dragging&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// calculate how far card moved&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; moved &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;Math&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;sqrt&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;Math&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(event.pageX &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; event.x0, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;Math&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;pow&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(event.pageY &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; event.y0, &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;));&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (moved &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; interactThreshold) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// remove card&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					event.target.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;data-status&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;transition&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;						x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; offX;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					} &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;						x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; (offX &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// mark as done after CSS transition&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					event.target.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;transitionend&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, () &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;						event.target.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;data-status&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;done&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					});&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// activate next card&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					event.target.nextElementSibling.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;data-status&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;current&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// reset vars&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					y &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// update rotation&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;					event.target.style.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-r&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, rotation &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;deg&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				&lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;// update x and y pos&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				event.target.style.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-x&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, x &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;px&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;				event.target.style.&lt;/span&gt;&lt;span style=&quot;color: #8250DF&quot;&gt;setProperty&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;--card-y&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;, y &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&#39;px&#39;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;			}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;		});&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	});&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;slot&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;slot&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s a big chunk of code, but pretty self explanatory I hope.&lt;/p&gt;
&lt;h2 id=&quot;step-6%3A-details-and-finessing&quot;&gt;Step 6: Details and finessing &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/building-a-swipeable-card-stack/#step-6%3A-details-and-finessing&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the functionality in place, there remains some refining to do. For example, you&#39;re probably going to want to include some transitions in your CSS, to make the moving and rotations smooth. An important point to consider is that having a transition on the card while it is being dragged will cause problems. That&#39;s why we added the &lt;code&gt;data-dragging&lt;/code&gt; attribute that is toggled to true when a card is being dragged. It means you can safely add something like this to your CSS:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.card&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-dragging&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;] {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;transition&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: transform &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;I also added a small rotation to the next card in the stack, to indicate that there is a card below. There are many ways you could design this though, I&#39;ll leave that to you.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Layout with CSS frameworks</title>
		<link href="https://smth.uk/layout-with-css-frameworks/"/>
		<updated>2019-07-19T00:00:00Z</updated>
		<id>https://smth.uk/layout-with-css-frameworks/</id>
		<content type="html">&lt;p&gt;If the suggestion is made to add a CSS framework to a project I&#39;m working on, my first response is always to try to understand why we would do that. To be honest, no answer to this question has ever &lt;em&gt;really&lt;/em&gt; convinced me. That said, the same question asked on a large scale throws up a lot of answers, and some valid reasons, such as speed and documentation.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;A question: if you have chosen to use a CSS framework (Bootstrap, Foundation etc.) for your project, what were the main reasons for doing so?&lt;/p&gt;&amp;mdash; Rachel Andrew (@rachelandrew) &lt;a href=&quot;https://twitter.com/rachelandrew/status/1052133688614576128?ref_src=twsrc%5Etfw&quot;&gt;October 16, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;One of the other big reasons, and one that I&#39;ve heard myself, is &amp;quot;we want a grid system&amp;quot;. I think a lot of people actually equate CSS frameworks such as Bootstrap and Foundation to a way of delivering layout. Ironically, I think the biggest shortcomings of CSS frameworks are those of layout. I say this for two reasons.&lt;/p&gt;
&lt;p&gt;The nature of a framework is to distill and homogenise. While this &lt;em&gt;might&lt;/em&gt; make sense for components, it has proven to be unsatisfactory for layout.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;which one of the two possible websites are you currently designing? &lt;a href=&quot;https://t.co/ZD0uRGTqqm&quot;&gt;pic.twitter.com/ZD0uRGTqqm&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jon Gold (@jongold) &lt;a href=&quot;https://twitter.com/jongold/status/694591217523363840?ref_src=twsrc%5Etfw&quot;&gt;February 2, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Using the word &amp;quot;grid&amp;quot; to describe the layout systems of CSS frameworks, at least the traditional ones, is to over sell them. Layout here can be distilled down to: How many columns do you want, and how wide should they be? Layout in Bootstrap for example is essentially the &lt;code&gt;.col-&lt;/code&gt; class. Well, it&#39;s not just &lt;code&gt;.col-&lt;/code&gt;, it is also &lt;code&gt;.col-sm-&lt;/code&gt;, &lt;code&gt;.col-md-&lt;/code&gt;, &lt;code&gt;.col-lg-&lt;/code&gt;, and &lt;code&gt;.col-xl-&lt;/code&gt;. Which brings me to my second reason.&lt;/p&gt;
&lt;p&gt;Layout is where most of the responsibility for handling screen size resides. For the past decade this has meant working with the techniques of &amp;quot;Responsive Web Design&amp;quot;. These techniques being: flexible widths, flexible images, and media queries. The first two of these techniques can be handled by a framework, without the user having to think too much about them. Media queries on the other hand don&#39;t really fit with the framework philosophy of hiding the workings behind a class; and so we get this situation where every class created needs multiple counterparts that represent a handful of media queries. As I&#39;ve discussed &lt;a href=&quot;https://smth.uk/abstraction-or-isolation/&quot;&gt;before&lt;/a&gt;, this type of approach has to add complexity that is hard to reason about, and/or limit the scope of design choices. So, going back to Bootstrap as an example, layout is probably about as complex as the developers would like to make it, yet all that is being facilitated is the ability to have a different amount of columns at a select few ranges of screen size. It wouldn&#39;t be fair though to say that this is solely a problem of the framework, to an extent this is part of the philosophy of &lt;em&gt;mobile first&lt;/em&gt; and &lt;em&gt;responsive web design&lt;/em&gt;. I do think however, that the act of distilling this philosophy down to a few classes exacerbates the issue.&lt;/p&gt;
&lt;h2 id=&quot;intrinsic-web-design&quot;&gt;Intrinsic web design &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/layout-with-css-frameworks/#intrinsic-web-design&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The good news perhaps, is that we appear to be in the middle of a paradigm shift. If this is the case, the shift will mark the end of &amp;quot;Responsive Web Design&amp;quot;, and the beginning of what Jen Simmons last year named &amp;quot;Intrinsic Web Design&amp;quot;. Intrinsic Web Design essentially encapsulates the new layout techniques that are facilitated by the similarly new additions to CSS - &lt;code&gt;display: flex&lt;/code&gt; and &lt;code&gt;display: grid&lt;/code&gt;. More specifically, letting the browser do a lot more figuring out of how to best use available space, based in part on the intrinsic nature of the content. One of the results of this is layouts that respond to screen size, without the use of media queries. This &lt;a href=&quot;https://labs.jensimmons.com/2017/01-011C.html&quot;&gt;responsive Mondrian by Jen Simmons&lt;/a&gt; uses no media queries, for example.&lt;/p&gt;
&lt;p&gt;It&#39;s not purely the absence of media queries that is striking about the above example, the code is also strikingly simple. When thinking about this stuff through the lens a framework, my first thought was &amp;quot;people don&#39;t need a framework for layout anymore&amp;quot;. For this reason I initially decided that layout would not be a part of the &lt;a href=&quot;https://whiteprint.mintcanary.com/&quot;&gt;framework / component library&lt;/a&gt; I was building. As I started to make some &lt;a href=&quot;https://whiteprint.mintcanary.com/examples/&quot;&gt;test pages&lt;/a&gt;, having to write additional CSS to arrange the components made the process feel less useful than something like Bootstrap, where you can get a long way without writing any CSS at all. The point where you have to start writing additional CSS is actually where I feel the use of a framework starts to become more of a hindrance than a help. It is where the code starts to diverge and become difficult to keep track of. Part of what I wanted to test with my framework was how far you can get within the confines of that framework; so I decided that layout should be a part of it.&lt;/p&gt;
&lt;p&gt;Fortunately, in the world of intrinsic web design, layout feels much more compatible with the framework way of working. I&#39;m thinking again about the moderately abstract frameworks here, like Bootstrap and Foundation. I call them moderately abstract because the components are just abstract enough to be generic, but not so abstract that components need to be constructed, as would be the case with a (totally abstract) utility first framework. With moderately abstract frameworks, a component looks something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;card&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;card-body&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;I&#39;m a card.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;So perhaps a layout should look something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;sidebar&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;sidebar-side&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;I&#39;m a sidebar.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;sidebar-body&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;I&#39;m the content.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;The abstraction and complexity here is about the same as that of the component above. This is now a viable approach with intrinsic sizing; without the need to explicitly describe breakpoints in the selectors. In theory, a few simple primitives like this could be used in combination to create a variety of page layouts. This is in fact beginning to be demonstrated by the excellent work being done by Heydon Pickering and Andy Bell in &lt;a href=&quot;https://every-layout.dev/&quot;&gt;Every layout&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In its simplest form, the sidebar in the above example would be however wide it needs to be for the content within it. You may of course want to specify this width explicitly, which adds a slight complication for a framework. This could be addressed in a number of ways. In my framework the approach would be the same as for components, in that the component (or layout) is an instance generated from a template and configuration file. You might have one instance of the sidebar layout called &lt;code&gt;has-subnav&lt;/code&gt;, configured with a specific sidebar width, and another instance called &lt;code&gt;has-meta&lt;/code&gt; which is configured with a different width and perhaps switches the sidebar to the right.&lt;/p&gt;
&lt;p&gt;Using layout from a framework like this wouldn&#39;t be appropriate for every use case, but using a framework isn&#39;t either. This way of packaging up layout feels to me in keeping with the general scope of a framework; and potentially offers more bang for your buck (versatility for your complexity).&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Utility classes</title>
		<link href="https://smth.uk/utility-classes/"/>
		<updated>2019-06-29T00:00:00Z</updated>
		<id>https://smth.uk/utility-classes/</id>
		<content type="html">&lt;p&gt;In my recent writing on how I think CSS is best written, a core tenet of my methods has been keeping presentational information out of markup. Essentially, the reason for this preference is that it makes restyling problematic, including dynamic restyling, in response to screen size. In contemporary practice, the epitome of presentational information in markup is perhaps the &amp;quot;utility class&amp;quot;. A utility or helper class in CSS typically applies a single rule to an element, though it can include a set of rules to achieve one simple objective. Here are a couple examples from the &amp;quot;utility first&amp;quot; framework &lt;a href=&quot;https://smth.uk/first-impressions-of-tailwind/&quot;&gt;Tailwind&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.text-lg&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;1.125&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.bg-black&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;	&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;#000&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;These obviously embrace the idea of styling information in HTML, and so, in an ideal world, not a strategy I would adopt. This approach can be appealing though, for at least a couple of reasons. One big reason is that utility classes can serve to minimise the amount of time you spend writing CSS. If using a framework such as Tailwind, this time could be reduced to zero. Attractive if you don&#39;t like writing CSS, but personally, I&#39;m not sure that not liking CSS is a valid justification for this compromise. That&#39;s not to say however that I don&#39;t see value in utility classes.&lt;/p&gt;
&lt;h2 id=&quot;the-case-for-utility-classes&quot;&gt;The case for utility classes &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/utility-classes/#the-case-for-utility-classes&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s look at an example page - the Bootstrap example pricing page.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/bs-pricing-example.png&quot; alt=&quot;Screenshot from getbootstrap.com/docs/4.3/examples/pricing&quot; /&gt;
&lt;p&gt;Each &amp;quot;card&amp;quot;, representing a price point, contains two text elements that are deemed to be key pieces of information, and so are treated to larger font sizes. The card title get&#39;s its font size by way of being an &lt;code&gt;h4&lt;/code&gt;. This problematic; in the hierarchy of the page, those should be &lt;code&gt;h2&lt;/code&gt;. Things get worse when you realise that the price get&#39;s it&#39;s large font size by way of the &lt;code&gt;h1&lt;/code&gt; tag. This is now very clearly not &lt;a href=&quot;https://webaim.org/techniques/semanticstructure/&quot;&gt;semantic structure&lt;/a&gt;.&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/bs-pricing-example-wave.png&quot; alt=&quot;WAVE report of pricing example&quot; /&gt;
&lt;p&gt;If you are unsure as to why this is problematic, you are probably only considering the perspective of someone experiencing the page purely visually. As is explained by the accessibility evaluation tool, &lt;a href=&quot;http://wave.webaim.org/report#/https://getbootstrap.com/docs/4.3/examples/pricing/&quot;&gt;WAVE&lt;/a&gt;, document structure facilitates navigation by users of assistive technologies. For these assistive technologies to work in a meaningful way, they need to understand the page. A meaningful content structure is part of what makes this possible.&lt;/p&gt;
&lt;p&gt;So how could the Bootstrap pricing example have been better achieved? One way would be to create some context specific selectors, something like (keeping with the slightly abstract naming convention) &lt;code&gt;card-title&lt;/code&gt; and &lt;code&gt;card-callout&lt;/code&gt;, and attach the desired styling to those classes. This would allow the structure to be corrected, and in most cases would probably be a decent solution. This was the approach I started to take in my own &lt;a href=&quot;https://whiteprint.mintcanary.com/&quot;&gt;framework&lt;/a&gt;, but quickly came to the conclusion, that this approach is too limiting for a framework. The options are limited to those imagined and cantered for by the author of the framework. A better approach, I feel, is to consider the wider challenge - in this case the desire to use different font sizes for different scenarios. This is where utility classes come in. Having utility classes &lt;code&gt;text-large&lt;/code&gt; and &lt;code&gt;text-extra-large&lt;/code&gt; would solve the same problem, but in a more versatile way. The title could be larger than the call-out, for example. We are now of course back in the possibly undesirable world of presentationaly named classes. In the context of a framework though, with versatility being so desirable, this compromise feels a little more reasonable. There is another issue in this scenario though. With a mix of components and a utility classes, styling information is being scattered around in a manner that might be difficult for someone working with the code to keep track of and reason about.&lt;/p&gt;
&lt;h2 id=&quot;a-possible-alternative&quot;&gt;A possible alternative &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/utility-classes/#a-possible-alternative&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When facing the above challenge, my second approach was indeed the utility class, but with a little shift in thinking, it became something else. The author of the above Bootstrap example was (ill-advisedly) leveraging the heading hierarchy to achieve the visual appearance. The &lt;code&gt;h1&lt;/code&gt; element in Bootstrap (and typically on the Web) is styled to have a large font size, and the heading sizes decrease through the heading levels, down to &lt;code&gt;h6&lt;/code&gt;. Modern web pages / apps are more complex than simply headings and paragraphs, that&#39;s why we end up with component libraries and CSS frameworks. It struck me that a useful part of such a framework might be a visual text hierarchy. So similar to an &lt;code&gt;h1&lt;/code&gt;, you would have &lt;code&gt;.text1&lt;/code&gt;, which would in some way be more visually prominent than &lt;code&gt;.text2&lt;/code&gt;. Although the styles attached to one of these classes might be the same as you&#39;d find attached to a utility class, there are significant differences here. &lt;code&gt;.text1&lt;/code&gt; is not strictly about font size, it&#39;s a hook for some possible styling. This styling might be a large font size, but in another context, a smaller screen for example, it might not be. I think it would be more accurate to consider this a component (albeit a very small one), rather than a utility.&lt;/p&gt;
&lt;p&gt;For this use-case, I think text hierarchy components are a good alternative to font size utility classes. It remains to be tested whether semantically named micro-components could be useful alternatives to utility classes more broadly.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Form over colour</title>
		<link href="https://smth.uk/form-over-colour/"/>
		<updated>2019-06-11T00:00:00Z</updated>
		<id>https://smth.uk/form-over-colour/</id>
		<content type="html">&lt;p&gt;I started &lt;a href=&quot;https://smth.uk/a-css-framework-with-custom-selectors/&quot;&gt;imagining a different kind of CSS framework&lt;/a&gt;, one where multiple isolated components could be created from a base template. These components would be highly configurable, so that sibling components could differ in appearance. This got me thinking about what a component should look like, if it is intended to be customised. Probably the customisations with the biggest impact are going to be changes to colours. Leaning on colour in the base / default components then could be kicking some problems down the road, for the user to deal with. Having to unravel meaning wrapped up in colours, then translate that meaning into the visual language of a brand can be tricky. For example, if the framework relies on two shades of a colour, but the visual identity to be applied only uses bold colours, then either the visual identity has to change, or some meaning will be lost.&lt;/p&gt;
&lt;p&gt;Let&#39;s take these three Bootstrap components:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/bs-components.png&quot; width=&quot;457&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;There are a few characteristics that distinguish one from another. It should be noted that context helps with this, and is missing here. I would suggest though that the most significant distinguishing feature is colour. It&#39;s easy to imagine a customised version of the above looking like this:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/bs-components-2.png&quot; width=&quot;457&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;or this:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/bs-components-3.png&quot; width=&quot;457&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;or even this:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/bs-components-4.png&quot; width=&quot;457&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;You would be correct to say that these would be bad design choices, and not the fault of the framework. I think it would be equally correct however to say that the framework is not providing much support here. When it comes to making components identifiable, it is offering little more than a colour palette. If designing a framework to be customised, you have to assume that the palette is going to be thrown out. So perhaps the ideal colour palette would include no colours - be black and white.&lt;/p&gt;
&lt;p&gt;This would make a lot of sense to me, as a starting point. If I&#39;m designing a logo, I don&#39;t jump right in with colour, I focus first on getting it to work in single colour. I started working in this way a long time ago, when logos were designed to be printed, and printing in single colour was cheaper. Thanks to the Web, and to digital printing, having a single colour logo is perhaps less crucial than it used to be. But even if I could guarantee that a single colour version of a logo was never going to be needed, I would still work in this way. I find that designing in black and white helps create a solid foundation to build upon. In a similar way, I believe a single colour component library could make the best base for a bespoke user interface.&lt;/p&gt;
&lt;p&gt;Another potential advantage of a single colour component library would be that, &amp;quot;out of the box&amp;quot; it would behave more like a wireframe. That is to say that before customisation, it could be used to plan layout and content, without the distraction of look and feel. I like to use &lt;a href=&quot;https://balsamiq.com/wireframes/&quot;&gt;Balsamiq&lt;/a&gt; for wireframes, for this reason; the obviously unfinished aesthetic forces everyone involved to focus on content and layout. Having a CSS framework that you can use to create wireframes, then evolve into a finished product feels like an attractive proposition to me, but one I haven&#39;t seen realised.&lt;/p&gt;
&lt;p&gt;So what would be required to design components that do not rely on colour? I think just like with a logo, it would be designing something with a recognisable form. For some components, this work has been done. The more established web components are recognisable. A solid rectangle with label in the centre of it = a button.. or is it a &amp;quot;&lt;a href=&quot;https://getbootstrap.com/docs/4.3/components/badge/&quot;&gt;badge&lt;/a&gt;&amp;quot;. The challenge here then is to create a collection of design patterns that can retain meaning, while being flexible enough to absorb a visual identity. Here are some examples that I have been working on:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/components.svg&quot; width=&quot;897&quot; alt=&quot;&quot; /&gt;
</content>
	</entry>
	
	<entry>
		<title>First impressions of Tailwind</title>
		<link href="https://smth.uk/first-impressions-of-tailwind/"/>
		<updated>2019-06-09T00:00:00Z</updated>
		<id>https://smth.uk/first-impressions-of-tailwind/</id>
		<content type="html">&lt;p&gt;I &lt;a href=&quot;https://smth.uk/a-css-framework-with-custom-selectors/&quot;&gt;recently speculated&lt;/a&gt; that the more abstract CSS frameworks would probably offer a better framework experience, than their moderately abstract counterparts. &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; is the standout option when it comes to abstract frameworks; I recently had a chance to give it a try.&lt;/p&gt;
&lt;p&gt;I was apprehensive about the idea of creating a mess of classes in my HTML. I suspect most people feel the same. I tried to keep this in perspective however, as I know this is in part an aesthetic concern.. It did feel pretty horrible though.&lt;/p&gt;
&lt;p data-quote=&quot;Why consider the utility first approach, what was the appeal of Tailwind?&quot;&gt;So why consider the utility first approach, what was the appeal of Tailwind? The biggest part of that question is &amp;quot;why use a framework?&amp;quot;. For this project it was desirable to be able to extend the product, without writing CSS. I would say this is essentially the appeal of any CSS framework - to be able to make stuff with minimal understanding of CSS. The problem with traditional CSS frameworks is that they don&#39;t get you very far before that dream starts to fade away. The advantage Tailwind has here, is that the atomic nature of the classes gives you much more power to create something bespoke. In my experience, Tailwind was pretty successful in this regard. This was the first time I felt that I was able to realise a design, while working more or less in the spirit of a framework.&lt;/p&gt;
&lt;p&gt;One of the practical concerns I had about the Tailwind approach, was having to change classes in multiple places when making a global change. I found that even before getting to that point, a related issue arose. Just applying those classes consistently in the first place, and keeping track of them is a considerable burden. Tailwind gives you classes for various amounts of spacing, for example. This is integral to the power to create bespoke designs, but of course with that power comes the responsibility to create consistency yourself. To make this process easier, I ended up creating my own less abstract spacing classes. In addition to (or potentially in place of) &lt;code&gt;m-1&lt;/code&gt; &lt;code&gt;m-2&lt;/code&gt; etc, I added &lt;code&gt;m-gutter&lt;/code&gt; (&#39;m&#39; standing for margin here). Tailwind makes this easy to do, via its config file.&lt;/p&gt;
&lt;p&gt;There&#39;s a balance to be found here. These classes that control things like spacing and font size, need to encompass everything you need for your project, while not being so many in number that the framework dissolves away. Despite the granular approach of Tailwind, I think its most valuable aspect is these variable-like classes, which offer some degree of commonality. Without this element of opinion, the framework would just be a proxy for CSS. This is in fact the case for a large chunk of Tailwind. For example, you use the &lt;code&gt;block&lt;/code&gt; class, as a proxy for writing &lt;code&gt;display: block&lt;/code&gt; in CSS, and the &lt;code&gt;absolute&lt;/code&gt; class for &lt;code&gt;position: absolute&lt;/code&gt;. This is required to serve that CSS averse user I previously identified. To someone without an aversion to CSS however, writing this pseudo CSS can feel perverse.&lt;/p&gt;
&lt;p data-quote=&quot;If you know CSS, the Tailwind classes will be quite intuitive; if you don&#39;t know CSS, you will spend a lot of time learning Tailwind.&quot;&gt;You could make an argument that learning a new (pseudo) language, to do what you can do with the standard language of CSS, is not the best use of time. If you know CSS, the Tailwind classes will be quite intuitive; if you don&#39;t know CSS, you will spend a lot of time learning Tailwind. That time might be better spent learning CSS?&lt;/p&gt;
&lt;p&gt;While Tailwind acts as a proxy for CSS, the full language is not fully represented. There is no CSS grid, no concept of siblings, no pseudo-elements, no transitions.. So you are probably going to find yourself back in a stylesheet at some point. Perhaps this is inevitable with any CSS framework. The question then is of how the relationship between utility classes, and custom CSS is managed. Tailwind has a useful feature which allows you to use its class names inside your CSS, like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.my-selector&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  @&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;apply&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;font-bold&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;py-&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;2 &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;px-&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;4 &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;rounded&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This is a nice way to make use of those variable-like classes; it mitigates the feeling of having abandoned the framework. This does raise questions though. Because having a mixture of component and utility classes could be confusing, the temptation might be to extract everything into components. Having done so, you might want to exclude the Tailwind classes (to reduce file size). At which point, you might as well have not used the framework to begin with. This would probably not be in the spirit of Tailwind though. You are more likely going to end up with a mix of utility and component classes. For me, this is not ideal, it adds some doubt about where styling is coming from. When you do need to leverage the power of real CSS, reasoning about what to extract and what to keep inline I found not to be a trivial task. Once you start writing real CSS for a component, do you then put all the styles for that component in the CSS, or keep as much as you can in the template? The &lt;code&gt;@apply&lt;/code&gt; feature in a sense allows you to customise the level of abstraction. This could be considered problematic, as once you start using it, you are then wrestling with question of &amp;quot;how abstract do I want this to be?&amp;quot;.&lt;/p&gt;
&lt;p&gt;My biggest concerns going into this was the inability to style a component differently in different &lt;a href=&quot;https://c3css.com/context/&quot;&gt;contexts&lt;/a&gt;, and the complexity involved in redesigning. Nothing has made me feel any better about this while using Tailwind.&lt;/p&gt;
&lt;p&gt;Despite the issues I have pointed out here, Tailwind felt like a framework of more value than others I have used. As someone happy to write CSS, I am never going to be the primary beneficiary of a CSS framework. The real test will be how the CSS averse find it.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>A CSS framework with custom selectors</title>
		<link href="https://smth.uk/a-css-framework-with-custom-selectors/"/>
		<updated>2019-05-30T00:00:00Z</updated>
		<id>https://smth.uk/a-css-framework-with-custom-selectors/</id>
		<content type="html">&lt;p&gt;In my recent posts, I have been exploring the line between useful conventions and enforced dogma in coding. I (I think) &lt;a href=&quot;https://smth.uk/identified-coding-practice/&quot;&gt;coined&lt;/a&gt; the terms &lt;em&gt;introjected coding practice, identified coding practice&lt;/em&gt;, and &lt;em&gt;integrated coding practice&lt;/em&gt;. These terms essentially describe the extent to which a coder believes in the rules that they follow.&lt;/p&gt;
&lt;p&gt;The outcome of this thinking has been a new &lt;a href=&quot;https://c3css.com/&quot;&gt;CSS methodology&lt;/a&gt;, which provides me with rules that I believe in, whilst addressing the potential problems of maintainability and scalability. This problem feels solved for me at this point. During this process I thought a lot about the two routes I could take towards this solution, &lt;a href=&quot;https://smth.uk/abstraction-or-isolation/&quot;&gt;abstraction or isolation&lt;/a&gt;. Nothing in the end compelled me to move away from my existing preference towards isolation, but perhaps one of the more compelling arguments is the CSS framework.&lt;/p&gt;
&lt;p data-quote=&quot;Successful approaches to CSS sit at either extreme of the line between abstraction and isolation.&quot;&gt;The position on the line between abstraction and isolation differs from one framework to another. You have some that I would say are somewhere in the middle, like &lt;em&gt;Bootstrap&lt;/em&gt;, and &lt;em&gt;Foundation&lt;/em&gt; with moderately abstract selectors, such as &lt;code&gt;.nav,&lt;/code&gt; or &lt;code&gt;.callout&lt;/code&gt;. Then there are frameworks that sit at the abstract end, such as &lt;em&gt;Tailwind&lt;/em&gt; and &lt;em&gt;Tachyons&lt;/em&gt;. These frameworks have selectors such as &lt;code&gt;.w-1&lt;/code&gt; to specify a width, or &lt;code&gt;.pa1&lt;/code&gt; to specify padding. My experience with CSS frameworks has been of those that occupy that middle ground. Perhaps as a result, I&#39;m not a huge fan of frameworks. In my experience, you always hit a limit of how far you can bend it to your needs before you are forced to break it. Either that or accept the limitations and make something very generic. The hypothesis that successful approaches to CSS sit at either extreme of the line between abstraction and isolation would suggest that the frameworks that sit at the abstract end offer a more scalable solution. I think that is a reasonable assumption to make. What I&#39;m currently wondering about though, is that other extreme.&lt;/p&gt;
&lt;p data-quote=&quot;Could a CSS framework exist at the isolation end of the line?&quot;&gt;Could a CSS framework exist at the isolation end of the line? I don&#39;t know of any frameworks that set out to do this. The reason for a lack of this kind of framework seems pretty obvious. Frameworks are all about reusable parts, the opposite of isolation. That said, people do work with frameworks in this way. Some CSS frameworks allows you to access its components via mixins, which opens up the possibility to apply them to multiple, isolated selectors. The problem historically with this was that there was limited scope for working in this way. As I recall only few aspects of Bootstrap, for example, were available as mixins. I can speculate as to why this would be. A mixin is useful for applying the same set of styles to multiple elements; they are simple to use in this way, and don&#39;t really require additional documentation. Once you get into complex components, comprised of multiple elements however, then working in this way would suddenly require a lot more knowledge of the framework. To recreate a component, using your own custom selectors would not only require a mixin for each element of that component, but the knowledge of how they relate to each other. You&#39;d not so much be using a framework at this point as refactoring it. I spoke to a colleague who had recently used Bootstrap in this way. The support for mixins is now much better, but his experience confirmed my speculation. You need an intimate knowledge of the framework to use its mixins extensively.&lt;/p&gt;
&lt;p&gt;The usefulness of a CSS framework is dependent on how configurable it is. I&#39;d suggest that the further away from abstraction the framework is, the more crucial this becomes. Configuration might be a more viable way to allow for the use of components with custom, isolated selectors. If we wanted to use a moderately abstract component, such as the Bootstrap &lt;em&gt;Card&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;card&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;card-body&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;To apply the styles from this to a less abstract custom selector, let&#39;s say &lt;code&gt;.article-preview&lt;/code&gt;. You could provide some sort of configuration that maps the abstract selectors to the custom ones.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;.article-preview = .card&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;.article-preview_body = .card-body&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This would act as a template for creating the new component, and might be a relatively painless way to gain control over the level of abstraction. Is doing this useful though? To that end, I&#39;m not sure. You could conceivably have &lt;code&gt;.card&lt;/code&gt; applied to multiple isolated selectors, say &lt;code&gt;.article-preview&lt;/code&gt; and &lt;code&gt;.author-bio&lt;/code&gt;, then have them diverge later in the cascade, but that&#39;s not ideal. I think what you would want is to configure the variables of the component at the time of creating the instance of it. So you would have a config for &lt;code&gt;article-preview&lt;/code&gt;, which would define the selector names, as well as the &lt;code&gt;card&lt;/code&gt; variables. So if one of the features of &lt;code&gt;card&lt;/code&gt; was a border, and you wanted the article previews to have a blue border, you would configure that here. The result would be a new component, essentially isolated to the extent that the core component (card) is configurable. This starts to feel potentially useful, and an interesting idea to explore..&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>C3 in practice</title>
		<link href="https://smth.uk/c3-in-practice/"/>
		<updated>2019-05-19T00:00:00Z</updated>
		<id>https://smth.uk/c3-in-practice/</id>
		<content type="html">&lt;p&gt;While my &lt;a href=&quot;https://c3css.com/&quot;&gt;CSS methodology (C3)&lt;/a&gt; derives from my own style of writing CSS, developed over many years, it was, at the time of &lt;a href=&quot;https://smth.uk/my-css-methodology/&quot;&gt;formalising it&lt;/a&gt;, pretty untested. For two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Until now I&#39;d never considered myself to be using a methodology. There were no rules in place, so my approach would have meandered, depending on circumstance.&lt;/li&gt;
&lt;li&gt;While the ruleset I am developing has been largely shaped by my practice, it has also been informed by theoretical musings, prompted by this current task of formalising the way I work. The combination of all this had yet to be put back into practice.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To put the new methodology to the test, I worked reflectively on a series of test cases.&lt;/p&gt;
&lt;h2 id=&quot;test-case-one&quot;&gt;Test case one &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/c3-in-practice/#test-case-one&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I first went back and refactored some of the code behind this blog. The code was several years old, and offered a lot of scope for the refactoring. For the most part this was a satisfying but uneventful test, with the new methodology only being helpful. I noticed on reflection however, that in one place I had deviated slightly from my rules. The old codebase had the following selector:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.post-header&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.post-image.halftone&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This was used to style some of the post header images to look a bit like a halftone print. Each of my blog posts has a large featured image, for this I will generally either create a bespoke illustration, or grab a Creative Commons photo, and stylise it. The latter is when the &lt;code&gt;halftone&lt;/code&gt; class gets applied. In my refactored code, the above became:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.post-header_image&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-image-effect&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;halftone&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;] {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Structurally this brings the selector inline with C3, but it&#39;s still breaking one rule - it is describing appearance. This could be rectified pretty easily in this case, by changing it to something like:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.post-header_image&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-type&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;raw&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;] {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;I think the reason I held off from this initially was to leave open the possibility of having multiple effect options. If I wanted to to be able to give post X the halftone effect, and post Y a glitch effect, for example. According to my new rules, rather than do this&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.post-header_image&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-image-effect&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;halftone&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;] {}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.post-header_image&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-image-effect&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;glitch&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;] {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;you would need to include some metadata, that does not describe the appearance, but that could be used as a hook for it. This feels potentially a little unreasonable, if not unrealistic. I can imagine ways this could work, based on perhaps thematic tags attached to the post, but there are certainly limitations here. Would it be unreasonable to want to choose an effect on a whim, or because it looks good for a reason you can&#39;t put into a word or two? You might argue that the pragmatic answer here would be &amp;quot;there will be situations when you need to bend the rules&amp;quot;, but if part of what I&#39;m trying to achieve is the ability to change appearance without touching any HTML, then having any exception surely undermines the effort.&lt;/p&gt;
&lt;p&gt;I needed to step back at this point and recognise that the ideology that I am pursuing is bigger than a naming convention. I think what the above example demonstrates is that for the methodology to be effective, its principles need to be applied consistently throughout the project. In the image effect scenario the &amp;quot;problem&amp;quot; starts with the fact that visual characteristics are being transferred from the content to the stylesheet (via the data attribute). This information existing in the metadata is OK, but when it gets passed into the content, it becomes at odds with the principles of the methodology; the direction of travel for styles should only be from CSS to HTML. This means that a description of an image effect, has no business being in the data attribute in the first place. So the answer to the above quandary (for the purists, at least), would be to go with something like the &lt;code&gt;[data-type=&amp;quot;raw&amp;quot;]&lt;/code&gt; solution; and if you want multiple effects, they should be initiated in the stylesheet (based on something like the post title, or category), or output as CSS directly. By outputting as CSS I mean something like adding a style tag to the template, or perhaps a link to an additional style sheet.&lt;/p&gt;
&lt;h2 id=&quot;test-case-two&quot;&gt;Test case two &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/c3-in-practice/#test-case-two&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Even having just thrown up one selector for scrutiny, the testing felt fruitful. For the next test I wanted to build something in an environment that might have its own ideas about how CSS should be written. I turned to a JavaScript framework. I decided to build a Vue.js app, using Nuxt.js. When using frameworks such as Vue, styles are typically coupled with markup, to form self contained components. I wanted to make sure that my C3 notion of components was compatible. Vue can also add useful classes for you, for things like transitions, for example. How would this fit with my methodology?&lt;/p&gt;
&lt;p&gt;I had recently started keeping a record of gigs I went to. To ensure a minimal burden, I limited myself to a two word summary of each gig (in hindsight, this added the burden of trying to avoid constant puns). I decided to use this as content. Each gig could be a component, that appears on its own page, and also on an index page. I could add some sort of animation between each page, to test the transition classes. That&#39;s what I built, you can see the result at &lt;a href=&quot;https://smth.uk/reviews/&quot;&gt;smth.uk/reviews&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The concept of component in Vue and in C3 worked perfectly together, I felt no conflict of opinions between the two. The page transitions on the other hand were slightly problematic. First of all, Vue requires that the transition selectors be classes. Transitions are part of &lt;em&gt;Context&lt;/em&gt; in C3 parlance, and to this point were required to be declared as attributes. So something like &lt;code&gt;data-transition=&amp;quot;enter&amp;quot;&lt;/code&gt;. My rule on this was clearly too restrictive. I needed to add a new class syntax to be used for context (because every class needs to be recognisable as &lt;em&gt;Component, Child&lt;/em&gt;, or &lt;em&gt;Context&lt;/em&gt;). I decided to extend the existing paradigm of key (attribute) and value into a class syntax. This will take the form of  &lt;code&gt;key--value&lt;/code&gt;, for example &lt;code&gt;transition--enter&lt;/code&gt;. I was considering specifying that when I class is used for context, it should still be written in the CSS using the attribute syntax: &lt;code&gt;[class=&amp;quot;transition--enter&amp;quot;]&lt;/code&gt;, but abandoned this idea when discovering that Vue transitions don&#39;t work with this syntax (presumably due to some required regular expression).&lt;/p&gt;
&lt;h2 id=&quot;test-case-three&quot;&gt;Test case three &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/c3-in-practice/#test-case-three&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There&#39;s nothing to focus the mind like a real live project, so the next case was a small client site. By this point the methodology felt solid, but on reflection I did find one aspect that could be refined. I was setting and overriding some element styles, in the global style sheet, something like:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #116329&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* global paragraph styles */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  @&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;nest&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;page-footer&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &amp; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* styles for paragraph in footer */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;I think it sometimes makes sense to do this, but it occurred to me that it was introducing some uncertainty about in which style sheet that style would be found. It could only be in one of two places (the global style sheet or the footer style sheet), but in my opinion, having to look in two places is significantly worse than knowing exactly where it will be. For this reason I created a rule that specifies the context always be added in the component style sheet, unless the element in question cannot have a class applied to it. For example a &lt;code&gt;p&lt;/code&gt; generated from Markdown. In this case context is added to the global element code block. This way, when looking at the element in HTML, you know, due to the class name or lack of, exactly where to look for the style.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Identified coding practice</title>
		<link href="https://smth.uk/identified-coding-practice/"/>
		<updated>2019-05-11T00:00:00Z</updated>
		<id>https://smth.uk/identified-coding-practice/</id>
		<content type="html">&lt;p&gt;In my thoughts about formalising my CSS methodology, I preempted the question &amp;quot;Why not just use an established method?&amp;quot;, saying there are two answers. I gave one &lt;a href=&quot;https://smth.uk/abstraction-or-isolation/&quot;&gt;answer&lt;/a&gt; at the time; here I want to give the other.&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;Understanding code reveals ethical questions, both in terms of our relationship to ourselves as autonomous beings, but also the framing and homogenisation of ideas and practice - heteronomy versus autonomy&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption class=&quot;blockquote_attribution&quot;&gt;— Berry, D. (2011). &lt;em&gt;The philosophy of software: Code and mediation in the digital age&lt;/em&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This struck a chord with me, and made me reflect on why autonomy in my work is important. I think intuitively it makes sense that we would feel more satisfaction, when we have more autonomy. Looking at this in the broader sense, &lt;a href=&quot;https://www.birmingham.ac.uk/news/latest/2017/04/autonomy-workplace.aspx&quot;&gt;research&lt;/a&gt; bears it out.&lt;/p&gt;
&lt;p&gt;I&#39;m thinking here though specifically about how we write code. This is about choosing to do something one way rather than another; and the motivation for doing so. How autonomous are these motivations? Why does it matter?&lt;/p&gt;
&lt;p&gt;In self determination theory (SDT), the idea of autonomy in this context is closely related to the concept of intrinsic and extrinsic motivations. When you are intrinsically motivated you are acting on your volition, e.g. doing something because you enjoy it. You are propelled by interest in the activity itself, as apposed to an extrinsic motivation. Extrinsic factors such as money or competition have been found to be detrimental to creativity, cognitive flexibility, and problem solving. Pretty key processes for this line of work, which are said to be associated with intrinsic motivation&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://smth.uk/identified-coding-practice/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The motivation to follow a coding methodology or framework is probably going to be extrinsic. It&#39;s a means to an end. The feeling of autonomy while following a methodology however, can vary greatly. To the extent that it makes your life easier, or your work better, you are going to enjoy using it, thus feel like you are doing so because you want to. If on the other hand there are aspects of the methodology that you only follow because someone says you should, then you are beginning to act less on your own volition. So to be happy, motivated, and creative while following a methodology, you need to believe in it. To &amp;quot;buy into&amp;quot; it. In SDT, this idea of buy-in is broken into three levels: introjection, identification, and integration.&lt;/p&gt;
&lt;h2 id=&quot;introjection&quot;&gt;Introjection &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/identified-coding-practice/#introjection&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Introjection describes the state of a regulation that has been adopted by a person, but not accepted as their own. So for example, you follow the rule because you understand that it is the correct thing to do, but that concept of &amp;quot;correct&amp;quot; is someone else&#39;s.&lt;/p&gt;
&lt;h2 id=&quot;identification&quot;&gt;Identification &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/identified-coding-practice/#identification&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An identified regulation is one that you feel reflects your own goals. You can follow this rule and still feel that you are acting on your own volition.&lt;/p&gt;
&lt;h2 id=&quot;integration&quot;&gt;Integration &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/identified-coding-practice/#integration&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A regulation is said to be integrated when it becomes autonomous. You do not feel like you are following a regulation, but acting in a self-determined way.&lt;/p&gt;
&lt;p&gt;While these are all technically extrinsic motivations, they graduate towards autonomous motivations.&lt;/p&gt;
&lt;p&gt;I think you can draw a useful parallel for coding practices.&lt;/p&gt;
&lt;h2 id=&quot;introjected-coding-practice&quot;&gt;Introjected coding practice &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/identified-coding-practice/#introjected-coding-practice&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&#39;re using Bootstrap, so I&#39;m following its conventions; but it feels a bit horrible.&lt;/p&gt;
&lt;h2 id=&quot;identified-coding-practice&quot;&gt;Identified coding practice &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/identified-coding-practice/#identified-coding-practice&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;BEM makes perfect sense to me, and is a great fit for this project.&lt;/p&gt;
&lt;h2 id=&quot;integrated-coding-practice&quot;&gt;Integrated coding practice &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/identified-coding-practice/#integrated-coding-practice&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I need to make this code perform the agreed function.&lt;/p&gt;
&lt;p&gt;In terms of something like a CSS methodology, it&#39;s probably not useful to think about integration. Part of the point is being aware of the rules. We certainly need to be aware of them in order to decide whether they are appropriate for a given project. I think it is useful however to consider the rules in terms of introjected and identified. Aiming for an identified methodology should result in happier coders, after all. So how can we make identification more likely? One way, surely, is to have wider selection of methodologies to choose from; and if nothing fits, make something that does.&lt;/p&gt;
&lt;p&gt;Any steps towards heteronomy in coding practice comes from reasonable, and practical objectives. So steps towards autonomy will probably bring tradeoffs. If everybody who wrote code, followed the same practices and methodologies, that would probably be optimal for maintenance and collaboration. It would however, I suspect, be terrible for creativity and diversity.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Gagné, M. and Deci, E. (2005). &lt;em&gt;Self-determination theory and work motivation&lt;/em&gt;. Journal of Organizational Behavior, 26(4), pp.331-362 &lt;a href=&quot;https://smth.uk/identified-coding-practice/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
	</entry>
	
	<entry>
		<title>Context, not modifier</title>
		<link href="https://smth.uk/context-not-modifier/"/>
		<updated>2019-04-30T00:00:00Z</updated>
		<id>https://smth.uk/context-not-modifier/</id>
		<content type="html">&lt;p&gt;I am continuing to examine how I am arriving at my CSS methodology. Having established the direction towards isolation (&lt;a href=&quot;https://smth.uk/abstraction-or-isolation/&quot;&gt;as opposed to abstraction&lt;/a&gt;), how does my approach sit with other approaches that take this path?&lt;/p&gt;
&lt;h2 id=&quot;bem&quot;&gt;BEM &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/context-not-modifier/#bem&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I &lt;a href=&quot;https://smth.uk/my-css-methodology/&quot;&gt;stated previously&lt;/a&gt; that my approach (which I&#39;m calling &lt;a href=&quot;https://c3css.com/&quot;&gt;C3&lt;/a&gt;) maps to an extent to the Block, Element, Modifier (BEM) approach. The significant departure comes at the third &#39;C&#39; in C3 - &lt;em&gt;Context&lt;/em&gt;. As &lt;em&gt;Component&lt;/em&gt; and &lt;em&gt;Child&lt;/em&gt; take the place of &lt;em&gt;Block&lt;/em&gt; and &lt;em&gt;Element&lt;/em&gt;, &lt;em&gt;Context&lt;/em&gt; is sort of a &lt;em&gt;Modifier&lt;/em&gt; replacement.&lt;/p&gt;
&lt;p&gt;The BEM modifier is all about appearance. It is where you are permitted to describe appearance in a class name. Having rejected abstraction, I don&#39;t see any need to ditch semantics in my approach. Modifier is arguably non-semantic by design. Context is semantic by design.&lt;/p&gt;
&lt;p&gt;While you could consider context a semantic only modifier, there is a conceptual shift that should be made. Context is not about modifying a component to extend its use. It is about the component appearing in different contexts, requiring changes to the appearance. You could think of it as reuse, without abstraction. This is a subtle distinction, but it is intended to allow for some pragmatic reuse of components, without wandering down the &lt;a href=&quot;https://smth.uk/abstraction-or-isolation/&quot;&gt;line between isolation and abstraction&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Context can be broken down into:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;State&lt;/strong&gt;: A component is active, for example.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metadata&lt;/strong&gt;: Similar to state, but could be persistent. For example, how many items are in a list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parent&lt;/strong&gt;: A component that is a parent (at any level) of the component in question. So, if this component is in a sidebar, for example.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Media&lt;/strong&gt;: The screen size, orientation etc of the device.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While this list is probably not exhaustive, it does hopefully demonstrate the difference to modifiers. BEM modifiers can which can be things like &lt;code&gt;element_large&lt;/code&gt;, &lt;code&gt;element_red&lt;/code&gt;, which do not fit into the above list.&lt;/p&gt;
&lt;p&gt;Modifiers and context are also different in how they are named. Modifiers are coupled with the element they are modifying, they contain the name of that element, in the name of the modifier.&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;button button_size_l&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* make it look like a button */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.button_size_l&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* make it large */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;This is in keeping with BEM&#39;s low specificity approach. In C3 I allow for some specificity when it comes to context, as I find this to be more flexible; and as &lt;a href=&quot;https://css-tricks.com/abem-useful-adaptation-bem/&quot;&gt;Daniel Tonon puts it&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Specificity != bad.&lt;br /&gt;
Uncontrolled specificity that has run wild = bad.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The C3 equivalent of the above BEM example might be:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;call-to-action&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.call-to-action&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* make it look like a button */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  @&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;nest&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-role&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&quot;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;hero&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&quot;] &amp; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* make it large */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;In the working style sheet, context is identified by it being nested in a code block. The outputted selector for the large &amp;quot;button&amp;quot; in this example being &lt;code&gt;[data-role=&amp;quot;hero&amp;quot;] .call-to-action&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;enduring-css&quot;&gt;Enduring CSS &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/context-not-modifier/#enduring-css&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Enduring CSS (ECSS) is the methodology set out in &lt;a href=&quot;https://benfrain.com/&quot;&gt;Ben Frain&lt;/a&gt;&#39;s book of the same name. This book was a big influence on how I write CSS, and so it&#39;s method is pretty close to mine. My approach could be seen as a less hardcore (I&#39;d like to think more pragmatic) variation of ECSS in some respects. For example, there isn&#39;t the strict name-spacing convention, which I felt could be a bit confusing. Another notable difference comes back to how we modify a component. The absence of a &amp;quot;modifier&amp;quot; in ECSS creates a strict practice of creating a new component for any variation. My concept of &lt;em&gt;context&lt;/em&gt; allows for a degree of reuse. It should be noted that in the &amp;quot;The Ten Commandments of Sane Style Sheets&amp;quot; at the end of Enduring CSS, the notion of &lt;em&gt;overrides&lt;/em&gt; is introduced. These overrides are mechanically the same as how I handle &lt;em&gt;context&lt;/em&gt;. If overrides are intended to be an integral part of ECSS (it was not clear to me), then this would bring it even closer to my methodology.&lt;/p&gt;
&lt;h2 id=&quot;maintainable-css&quot;&gt;Maintainable CSS &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/context-not-modifier/#maintainable-css&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Maintainable CSS&lt;/em&gt; is a recent book by interaction designer &lt;a href=&quot;https://adamsilver.io/&quot;&gt;Adam Silver&lt;/a&gt;. The approach outlined in this book comes from the same semantic favouring standpoint as my approach; and also uses a BEM-like naming convention. As a result, Adam and myself have arrived at similar methodologies, but again there are some differences. Maintainable CSS retains the modifier notion from BEM. While the use of a modifier is presumably intended to be restricted by the explicit mention of semantics (elsewhere in the book) it feels like a grey area, open to interpretation. More generally, relying on a specific understanding of semantics, in regards to CSS is problematic. I think this is highlighted in a 2012 blog post titled &lt;a href=&quot;http://nicolasgallagher.com/about-html-semantics-front-end-architecture/&quot;&gt;About HTML semantics and front-end architecture&lt;/a&gt;, in which Nicolas Gallagher argued that class names &amp;quot;cannot be unsemantic&amp;quot;, pointing out that not all semantics need to be content-derived. Rather than try to guide the use of modifiers with a philosophy of semantics, what I am attempting to do with &lt;em&gt;context&lt;/em&gt; is narrow the scope so that the (internal) debate about semantics need not occur.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Abstraction or isolation</title>
		<link href="https://smth.uk/abstraction-or-isolation/"/>
		<updated>2019-04-20T00:00:00Z</updated>
		<id>https://smth.uk/abstraction-or-isolation/</id>
		<content type="html">&lt;p&gt;Following on from my &lt;a href=&quot;https://smth.uk/my-css-methodology/&quot;&gt;post&lt;/a&gt; setting out a direction for my &lt;a href=&quot;https://c3css.com/&quot;&gt;CSS methodology&lt;/a&gt;, I want to go into a little more detail about how I am arriving at my solution.&lt;/p&gt;
&lt;p&gt;Fundamentally, I am, as I mentioned in that post, in pursuit of a way to write CSS that is easily maintained and scaled. This is an issue that I think most people who write CSS have felt at some point. If you&#39;ve ever had someone tack a style onto the end of your style sheet, because they didn&#39;t know where else to put it, or were afraid of breaking something, then you are one of those people. This is also an issue that has been addressed, and probably fair to say, solved, multiple times. So why reinvent the wheel? There are broadly two answers to that. One is a philosophical one, about wanting agency in the way I work. The other is more pragmatic. I&#39;m going to focus on the latter here.&lt;/p&gt;
&lt;p&gt;If you go back maybe ten years, CSS was a much less scrutinised language. It was a place where some magic happened, and people would do, in that CSS document, whatever it took to make that magic happen. The endless possibilities that came with this were, and are incredibly exciting to me. They also resulted in documents that only the author could understand (and even they would probably struggle if they came back to it a few months later). Two concepts emerged that sought to bring some sanity to style sheets. These map to the methods (or ideologies) that I identified in the previous post: &lt;em&gt;CSS determined by HTML&lt;/em&gt;, and &lt;em&gt;HTML determined by CSS&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;One solution is abstraction (HTML determined by CSS). When you follow this method, you abstract your styles to the point that they become highly reusable, and generic enough to avoid unpredictable or unintended side effects. Essentially the idea here is that you write less CSS. You instead offload the complexity into the HTML, and create the desired visual effect there. This is the essence of a CSS framework, such as Bootstrap. &lt;a href=&quot;https://tachyons.io/&quot;&gt;Tachyons&lt;/a&gt; however, would be a better example of a framework that takes this approach to its logical extreme.&lt;/p&gt;
&lt;p&gt;Abstract selectors example:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;background-red hover-background-dark-red text-white font-size-6 font-bold paddingY-2 paddingX-4&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  Remove item from shopping cart&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;The other solution takes the opposite approach. Instead of aiming for reusability, it aims for isolation. Styles only effect specific, targeted elements (CSS determined by HTML); there is minimal inheritance. The aim here is to prevent any &amp;quot;leaking&amp;quot; of styles, meaning that someone editing the code can do so with the confidence that nothing but the specific element they want to effect will be effected. Equally, finding the right line of code to edit should be more intuitive. This approach relies upon some form of scoping. Perhaps the most simple form is a naming convention for the selectors. &lt;a href=&quot;https://en.bem.info/&quot;&gt;BEM&lt;/a&gt; is a popular CSS naming convention, and can serve this purpose, however it is not specifically geared towards isolation, and could be used with abstract class names, to some extent.&lt;/p&gt;
&lt;p&gt;Isolated selector example:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;shopping-cart__remove-button&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  Remove item from shopping cart&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;The extent of abstraction is a key point when weighing up these approaches. It can be tempting to chart a course somewhere between the two approaches. Some moderate abstraction here, a little bit of isolation there. There&#39;s a danger here though of not preventing the problems that these approaches are designed to prevent. Someone who has spent a lot of time thinking about this stuff is Ben Frain, author of &lt;em&gt;Enduring CSS&lt;/em&gt;. He would seemingly agree with this assessment. On the &lt;a href=&quot;https://shoptalkshow.com/episodes/336/&quot;&gt;Shoptalk Show podcast&lt;/a&gt; he described a line with abstraction at one end, and isolation at the other; and suggested that the approaches that end up working are at either end of that line. Going so far as to say &amp;quot;There&#39;s nothing in the world that makes me believe you can mix the two and have a successful approach&amp;quot;.&lt;/p&gt;
&lt;p&gt;In &lt;em&gt;Enduring CSS&lt;/em&gt; Ben describes his method of working with CSS, which sits at isolation end of the line. At the other end of the line is Adam Wathan, the author of utility first framework &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt;. He makes the case for abstraction in the brilliant blog post &lt;a href=&quot;https://adamwathan.me/css-utility-classes-and-separation-of-concerns/&quot;&gt;CSS Utility Classes and &amp;quot;Separation of Concerns&amp;quot;&lt;/a&gt;. The post details Adam&#39;s journey from semantic classes to utility classes. While this didn&#39;t convince me that abstraction was the approach for me, it did give additional weight to the argument for choosing an extreme.&lt;/p&gt;
&lt;p&gt;Of these two approaches, isolation is the better fit for the way I like to work, and for the types of projects I tend to work on. I could conceive of a scenario where abstraction would feel like a better option, but to my mind it would be rare that a project would benefit enough to justify the downside. The downside, as I see it, is that abstraction has to sacrifice a long standing benefit of CSS. That is the separation of style and content. Being able to restyle a page, without changing the HTML, was once a kind of gold standard for CSS. This idea was at the heart of the once popular &lt;a href=&quot;http://www.csszengarden.com/&quot;&gt;CSS Zen Garden&lt;/a&gt;. It was also presumably at least part of the thinking behind this W3C guideline:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] authors are encouraged to use values that describe the nature of the content, rather than values that describe the desired presentation of the content.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Over time, this idea has become less valued, and apparently easy to abandon. Given the benefits of abstraction, this is understandable. In reality, the ability to redesign a website, and not touch the markup has been of limited use. You might ask &amp;quot;Who actually does that?&amp;quot;. I&#39;d like to offer two examples of where this hypothetical CSS only redesign is actually useful.&lt;/p&gt;
&lt;h2 id=&quot;scenario-one&quot;&gt;Scenario one &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/abstraction-or-isolation/#scenario-one&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I used to work for an organisation that spent a lot of time, essentially re-skinning a particular web application, for clients. This software had no real concept of &amp;quot;themes&amp;quot;, so re-skinning was actually the type of redesign that Zen Garden prophesied. There was not the zen-like separation of content and style here though (the software was built on Bootstrap). This meant that when applying my new designs I had two options. Option one, apply styles contrary to their selectors; for example tell a class named &lt;code&gt;span9&lt;/code&gt; to be full width (yuck). Option two, edit all the templates, to change the classes. Option two is the saner option here, but it still felt pretty crazy. Not only did it add complexity to what should have been simple changes, it also added complexity to the code base. Adding plugins became more complex, as they introduced their own template modifications (which might follow the same naming conventions). Updating the software was potentially more complex as there were now loads of files that differed from the core. Sure, the way that this software handles customisation could be improved, but the reality was that in this not-for-profit environment, there was not the time/money available to make these improvements. Much like the hypothetical redesign, hypothetical complexity gets trumped by the quickest path to getting the thing shipped.&lt;/p&gt;
&lt;h2 id=&quot;scenario-two&quot;&gt;Scenario two &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/abstraction-or-isolation/#scenario-two&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you read scenario one and thought &amp;quot;yeah but, that&#39;s an edge case&amp;quot;, scenario two is for you. There are micro redesigns happening to millions of website right now. We don&#39;t call them redesigns though, we call them responsive designs. If you are reading this on a large screen, and resize the browser, you&#39;ll likely see the page get a new layout, to better make use of the available space. This practice is ubiquitous, and I would argue, at odds with the presentational or utility classes that abstraction requires.&lt;/p&gt;
&lt;p&gt;Responsive design is obviously possible with abstraction. You can do something like this:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;small-screen-font-size-6 medium-screen-font-size-8 large-screen-font-size-10&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  Remove item from shopping cart&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;While this exact example might not exit in the real world, I think it demonstrates what is required to make something responsive with utility classes. Even in this simplified example it&#39;s already getting complicated to think about. Imagine you wanted this button to be different in many ways, at many different screen sizes. Imagine then you wanted to respond to other variables. Orientation, ambient lighting? This all points to a pretty undesirable scenario in my opinion.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Opened the DevTools on a friend&amp;#39;s website to check something and these are all CSS classes. Are all squarespace sites like this?? &lt;a href=&quot;https://t.co/qCGbhYFqof&quot;&gt;pic.twitter.com/qCGbhYFqof&lt;/a&gt;&lt;/p&gt;&amp;mdash; 🌙 Stephanie (Stimac) Drescher ✨ (@seaotta) &lt;a href=&quot;https://twitter.com/seaotta/status/1109141914832404480?ref_src=twsrc%5Etfw&quot;&gt;March 22, 2019&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;This method either has the effect moving complexity from one place to another (undermining the objective of the exercise), or restricting design choices (which could be considered a good thing in some scenarios). I want a system (that I&#39;m going to use for the majority of my work) to start from that fabled place of endless possibilities.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>My CSS methodology</title>
		<link href="https://smth.uk/my-css-methodology/"/>
		<updated>2019-02-17T00:00:00Z</updated>
		<id>https://smth.uk/my-css-methodology/</id>
		<content type="html">&lt;p&gt;First up, an admission: I&#39;ve never (fully) adopted a CSS methodology. In recent years, it has felt like any self respecting front-end dev should pick a side and embrace one of the popular approaches, whether that be &lt;a href=&quot;https://bem.info/&quot;&gt;BEM&lt;/a&gt;, &lt;a href=&quot;https://smacss.com/&quot;&gt;SMACSS&lt;/a&gt;, &lt;a href=&quot;https://css-tricks.com/lets-define-exactly-atomic-css/&quot;&gt;Atomic CSS&lt;/a&gt;.. (the list goes on). Of course it&#39;s not really about picking a side, a lot of these approaches overlap or compliment each other. That being said, I think there are a couple of overarching ideologies at play, which, depending on to which you subscribe, rule in or rule out particular methodologies. These can be boiled down to &lt;em&gt;CSS determined by HTML&lt;/em&gt;, and &lt;em&gt;HTML determined by CSS&lt;/em&gt;. The former is a slightly abstract expression of the idea that content lives in HTML; and you style the content in CSS. The counterpart describes the newer idea of creating &amp;quot;utility classes&amp;quot; in CSS then adding them to your HTML (to style your content) as required. I mention this just to set out my stall, my default position is a strong preference towards &lt;em&gt;CSS determined by HTML&lt;/em&gt;. I could make practical arguments for this (and I will in &lt;a href=&quot;https://smth.uk/abstraction-or-isolation/&quot;&gt;my next post&lt;/a&gt;), but in truth, people find success with approaches from both schools of thought. Some people love Bootstrap; &lt;a href=&quot;http://www.csszengarden.com/&quot;&gt;Zen Garden&lt;/a&gt; still has a special place in my heart.&lt;/p&gt;
&lt;p&gt;The methodologies most compatible with my ideals still contained enough undesirable stuff to put me off fully embracing them. I did however recognise a goal common to all of them - scalable, maintainable CSS. Over time I adopted elements from various methodologies, in particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A class naming convention&lt;/li&gt;
&lt;li&gt;Limited cascades&lt;/li&gt;
&lt;li&gt;A single code block per selector&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&#39;ve found this approach of adopting solutions, as and when a benefit became tangible much more appealing than a wholesale adoption of something that didn&#39;t feel quite right for me. I can however, see a real benefit in using an established methodology (and I&#39;m not ruling out ever doing so), in that other people working on the code know what to expect, and what is expected of them. For this reason I want to start the process of formalising and documenting my current approach to CSS. Here&#39;s my first pass.&lt;/p&gt;
&lt;h2 id=&quot;the-three-&#39;c&#39;s&quot;&gt;The three &#39;C&#39;s &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#the-three-&#39;c&#39;s&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My approach revolves around what I call the three &#39;C&#39;s - &lt;em&gt;Component&lt;/em&gt;, &lt;em&gt;Child&lt;/em&gt;, and &lt;em&gt;Context&lt;/em&gt;. Let&#39;s call it C3. For those familiar with BEM, it&#39;s worth making an immediate comparison here, as I have borrowed a lot. In terms of definitions, Component and Child map directly to Block (B) and Element (E) of BEM.&lt;/p&gt;
&lt;h3 id=&quot;component&quot;&gt;Component &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#component&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A stand-alone, possibly reusable part of a page. Represented by a class. Class is named after what the component is (for), never what it looks like, or its state. Class names are formed of lowercase words, separated by a hyphen (-), though the only crucial rule is that underscores (_) are not permitted. Components can be nested within one another (in the markup, not in CSS).&lt;/p&gt;
&lt;h4 id=&quot;example&quot;&gt;Example &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#example&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- valid component class --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- invalid, we don&#39;t describe appearance here --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;horizontal-menu&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h3 id=&quot;child&quot;&gt;Child &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#child&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Could more accurately be described as a &lt;em&gt;Component Child&lt;/em&gt;, a Child is a constituent part of a Component, not intended to be used separately from it. Just like Components, Children are represented by a class, named after their purpose, and never their appearance or state. Class names are formed of the parent Component name, an underscore, and Child name (lowercase words, separated by a hyphen). Children can also be nested within one another (in the markup, not in CSS).&lt;/p&gt;
&lt;h4 id=&quot;example-2&quot;&gt;Example &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#example-2&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- Component --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu_item&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- Child --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu_link&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;&amp;lt;!-- Child --&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;h3 id=&quot;context&quot;&gt;Context &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#context&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Describes the context of a Component or Child. Context is represented by attribute selectors and/or media queries. Context describes circumstances, not appearance. In terms of media queries, this will be information about the viewport; attributes are used for things like state, role, or any arbitrary variable. WAI-ARIA should be used where appropriate, otherwise data attributes are used. Cascading is permitted here.&lt;/p&gt;
&lt;h4 id=&quot;example-3&quot;&gt;Example &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#example-3&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu_item&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu_link&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;aria-current&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;page&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu_item&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;menu_link&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Context is where my method most differs from others (that I&#39;ve seen), so worth giving some comparative examples. When it comes to states, C3CSS is not far removed from BEM. The selector for the above active menu link would be: &lt;code&gt;.menu_link[aria-current]&lt;/code&gt;. While in BEM it might be &lt;code&gt;.menu__link--active&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The significant difference is that Context does not describe appearance, so things like colour and size require a different way of thinking. Take for example this BEM button:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;html&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #116329&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;button button--green button--large&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;We have a button class, and we want a green variation of it, and a large variation of it. The C3CSS approach here is to ask &amp;quot;Why?&amp;quot;. Perhaps the button is green because this is a positive action, in which case, our selector might be:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-type&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;positive&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;] {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Maybe the button is large because its inside a banner/hero. In which case we might use:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-role&lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #0A3069&quot;&gt;&quot;hero&quot;&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s worth mentioning tooling here. In practice I would be using PostCSS and writing the above examples like so:&lt;/p&gt;
&lt;pre class=&quot;shiki github-light&quot; style=&quot;background-color: #ffffff; color: #24292f&quot;&gt;&lt;div class=&quot;language-id&quot;&gt;css&lt;/div&gt;&lt;div class=&quot;code-container&quot;&gt;&lt;code&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;.button&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* styles */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &amp;[&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;data-type&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;=&quot;&lt;/span&gt;&lt;span style=&quot;color: #0550AE&quot;&gt;positive&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt;&quot;] {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* styles */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #CF222E&quot;&gt;@nest&lt;/span&gt;&lt;span style=&quot;color: #24292F&quot;&gt; [data-role=&quot;hero&quot;] &amp; {&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #6E7781&quot;&gt;/* styles */&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;line&quot;&gt;&lt;span style=&quot;color: #24292F&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/code&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;Note: Everything about &lt;code&gt;.button&lt;/code&gt; can be found in this code block.&lt;/p&gt;
&lt;h4 id=&quot;why-attributes-over-classes%3F&quot;&gt;Why attributes over classes? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#why-attributes-over-classes%3F&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This is just a style choice, chosen for consistency with ARIA, and to make it easy to identify each of the three &#39;C&#39;s: &lt;code&gt;component&lt;/code&gt;, &lt;code&gt;_child&lt;/code&gt;, &lt;code&gt;[context]&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;don&#39;t-you-repeat-a-lot-of-code%3F&quot;&gt;Don&#39;t you repeat a lot of code? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/my-css-methodology/#don&#39;t-you-repeat-a-lot-of-code%3F&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Yes and no. In terms of the code I&#39;m writing, no; I make use of variables and occasional mixins to ensure consistency. There is potential for some repetition in outputted code; this is a conscious compromise. There are essentially two reasons why I am willing to make it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rewriting templates to make stylistic changes is an unnecessary abstraction.&lt;/li&gt;
&lt;li&gt;Describing appearance in HTML is fundamentally at odds with responsiveness.&lt;/li&gt;
&lt;/ol&gt;
</content>
	</entry>
	
	<entry>
		<title>An end to app fragmentation?</title>
		<link href="https://smth.uk/an-end-to-app-fragmentation/"/>
		<updated>2017-12-16T00:00:00Z</updated>
		<id>https://smth.uk/an-end-to-app-fragmentation/</id>
		<content type="html">&lt;p&gt;As a Web maker, in a time when phones and tablets are increasingly common devices on which to connect, making an &amp;quot;app&amp;quot; has started to feel like an evolutionary step. This is a strange phenomenon, the Web is also accessible from mobile devices after all; and I&#39;ve never felt the need to make a desktop application. For those of us in this space, there is always learning ahead, but there is also a decision to be made about what it is exactly that we want or need to learn. Before talking about apps any further, let&#39;s clarify what I mean by an &amp;quot;app&amp;quot;? It&#39;s obviously an abbreviation of &amp;quot;application&amp;quot;, but I believe that in common parlance &amp;quot;app&amp;quot; has come to mean an application that is installed on your mobile device. This is the definition I will be using here. More broadly, apps can be described as belonging to one of three types: &lt;em&gt;Native&lt;/em&gt;, &lt;em&gt;Web&lt;/em&gt;, or &lt;em&gt;Hybrid&lt;/em&gt;. &lt;em&gt;Native&lt;/em&gt; being apps built for a specific operating system (such as Android or iOS); &lt;em&gt;Web&lt;/em&gt; being built to run on web technologies; and &lt;em&gt;Hybrid&lt;/em&gt; being Web apps inside a native app. Progressive Web Apps (PWAs), a hot topic in the tech world at the moment, are a specific kind of Web app with a range of enhancements to integrate further with the device. These enhancements include for example, the ability to install the app onto the device, (bringing the app in-line with my definition).&lt;/p&gt;
&lt;p&gt;With PWAs seemingly gaining traction they are an attractive prospect; for someone such as myself, who already builds for the Web, and perhaps more importantly, has a love for its principles. I believe that part of the decisions around what we want and need to learn should be about investing in the infrastructures that we want to see succeed. This for me is where PWAs start to feel like a very different proposition to the app options that have come before. Since the emergence of smart phones, or more specifically, their app stores, I have been uncomfortable with the trend towards there being &amp;quot;an app for that&amp;quot;. It felt like a step backwards, when considering the changes that the Web has brought to how we use our computers. I have feared that this trend could become the new model of how we use the internet, depriving the Web of resources, innovation and voices. To quote Tim Berners-Lee - &amp;quot;these closed, “walled gardens,” no matter how pleasing, can never compete in diversity, richness and innovation with the mad, throbbing Web market outside their gates. If a walled garden has too tight a hold on a market, however, it can delay that outside growth&amp;quot;. The antithesis of the walled garden of the app store, is the openness of the Web. Perhaps the defining characteristic of openness in this context is the absence of a controlling party. In the app store paradigm, a controlling party, such as Apple, can decide what apps they allow users access to. The impact of this on developers can range from having to wrestle with an opaque and seemingly arbitrary approval systems, to censorship. For users this can obviously mean a lack of access.&lt;/p&gt;
&lt;p&gt;As a user, and a maker, I&#39;m joining a growing circle of keen PWA onlookers, and hoping that there will be more Web in the apps of the future. Will we see this future realised? What obstacles might stand in the way? Here I will look some recent events in the app world, and what they might suggest about the future.&lt;/p&gt;
&lt;h2 id=&quot;there&#39;s-a-(native)-app-for-that&quot;&gt;There&#39;s a (native) app for that &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#there&#39;s-a-(native)-app-for-that&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the realm of mobile devices, apps have come to dominate our usage. According to a &lt;a href=&quot;https://www.smartinsights.com/mobile-marketing/mobile-marketing-analytics/mobile-marketing-statistics/&quot;&gt;2017 report&lt;/a&gt; 80-90% of the time we spend on our mobile devices is in an app other than a Web browser. Putting to one side whether the slightly grey area of progressive Web apps would be considered app use or Web use, this statistic tells us that users are, for the vast majority of their time, working within a native experience. It also tells us that while users are probably using the Internet during this time, they are not using the Web. This probably won&#39;t come as a surprise to anyone, I think we can all relate; we get our email in an app, we watch videos in an app, probably have several apps for social media etc. It&#39;s worth noting that this is in contrast to how we use our PCs, where we often do those activities on the Web. This distinction, might on the surface seem like a semantic one; one would say they &amp;quot;use Gmail&amp;quot; whether they are referring to an app, the website, or both. The implications though, of a move from the Web (back) to native software are huge, at least in the eyes of those of us who value the openness of the Web. Back in 1997 Wired Magazine ran the headline &amp;quot;Kiss your browser goodbye: The radical future of media beyond the Web&amp;quot;. Since then, others have made similar predictions, for example the 2014 Wall Street Journal article headlined: &amp;quot;The Web Is Dying; Apps Are Killing It&amp;quot;. In this article, not only did Mims make the argument that apps are killing the Web, but also echoed my concerns about the implications of this. The end of the Web would mean the end of the openness that allowed it to grow into what we know and love today.&lt;/p&gt;
&lt;p&gt;So how did we get here, to a place where Facebook, YouTube, and Amazon are no longer just websites? Why did phones not pickup from where the Web browser had taken us? From a technical perspective, which is usually the perspective from which this question is discussed, there are a couple of simple and widely accepted answers.&lt;/p&gt;
&lt;h3 id=&quot;performance&quot;&gt;Performance &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#performance&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Native apps are &lt;a href=&quot;http://opensourceforu.com/2017/08/native-vs-hybrid-apps-key-points-help-decide-best-way-forward&quot;&gt;considered&lt;/a&gt; to be faster, and more efficient. While our mobile devices are getting ever more powerful, they have not been in the same league as our desktop computers. As such, any gain in performance can make the difference between a smooth and sluggish user experience.&lt;/p&gt;
&lt;h3 id=&quot;persistence&quot;&gt;Persistence &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#persistence&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We want the data on our phones to be persistent, that is to say that we like our apps to work whether we are connected to WIFI, 3G, or have no connection at all. As Galen Gruman wrote in &lt;a href=&quot;https://www.infoworld.com/article/3012146/web-applications/native-apps-have-crushed-web-apps.html&quot;&gt;InfoWorld&lt;/a&gt; &amp;quot;I want my airline boarding pass locally stored on my smartwatch or smartphone, not available only on demand via the Web&amp;quot;. This is not how Web browsers, and so Web apps have worked thus far.&lt;/p&gt;
&lt;p&gt;These are the most compelling arguments commonly cited for the native app model, along with perhaps comments about closer hardware and software integration (which I find less relevant, as they are not exclusive to mobile devices). Looking at this case from another perspective, namely a business one, there is another obvious driver for the native app paradigm. Operating within the capitalist system that they do, companies are going to be pretty happy to encourage a model that gives them control over the market, as the app store model has done for Apple and Google. The Web has perhaps been the exception, rather than the rule, in terms of seeing companies working towards a common, standardised platform.&lt;/p&gt;
&lt;h2 id=&quot;there&#39;s-not-an-app-for-that&quot;&gt;There&#39;s &lt;em&gt;not&lt;/em&gt; an app for that &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#there&#39;s-not-an-app-for-that&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Despite the dominance of apps in our mobile usage, there are circumstances where &lt;em&gt;There&#39;s an app for that&lt;/em&gt; doesn&#39;t ring true.&lt;/p&gt;
&lt;p&gt;Perhaps the simplest scenario for this is when nobody has made the app, or more specifically, nobody has made the app for your device. The significant investment it takes to create apps for multiple platforms often leads to apps being unavailable to a lot of potential users. A 2013 &lt;a href=&quot;https://www.canalys.com/newsroom/half-top-ipad-apps-either-unavailable-or-not-optimized-android&quot;&gt;report&lt;/a&gt; found that 30% of the top 50 iPad apps in Apple’s US App Store were not available in Google&#39;s Play store. A huge advantage of Web apps of course is that they can exist on a single platform (the Web), but be available to everyone. Take for example &lt;em&gt;Topple Trump&lt;/em&gt;, an app not available in the Apple or Google stores, but is available on their respective platforms via the Web&#39;s own distribution method, the URL: &lt;a href=&quot;https://parall.ax/hub/topple-trump&quot;&gt;https://parall.ax/hub/topple-trump&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I spoke to the developers of &lt;em&gt;Topple Trump&lt;/em&gt;; the reasons they gave for taking the Web app route were around accessibility, and sharing; stating that &amp;quot;this is a lot easier to do using a website than a native app, as convincing someone to check out a web page is a lot easier as there&#39;s nothing to download&amp;quot;. If we speculate a little about how else the project might have differed as a native app, there is evidence to suggest that there would have been additional barriers. For an app to be made available in either of the two big app stores, it needs to be approved by Apple / Google. There is a history of these stores rejecting politically opinionated apps. Apple for example initially rejected the &lt;em&gt;iSinglePayer&lt;/em&gt; app for being &amp;quot;politically charged&amp;quot;; and &lt;em&gt;Metadata+&lt;/em&gt; (previously &lt;em&gt;Drones+&lt;/em&gt; - an app that alerts the user when a drone strike takes place), due to &amp;quot;objectionable content&amp;quot;. More closely related to &lt;em&gt;Topple Trump&lt;/em&gt;, &lt;em&gt;Obama Trampoline&lt;/em&gt; was reportedly rejected because &amp;quot;Apple does not approve of ridiculing public figures&amp;quot;.&lt;/p&gt;
&lt;p&gt;In all this talk of iOS and Android, we shouldn&#39;t forget that there are other mobile operating systems; here again, we may find that there is in fact not &amp;quot;an app for that&amp;quot;. For example, Windows Phone users do not have an app for the popular image messaging service &lt;em&gt;Snapchat&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The last scenario I want to mention here is when an app might exist for your platform, but you don&#39;t install it. There are some frictions that might be enough to stop you from installing an app; you need to commit the time it takes to download it, and possibly more significantly, commit to the storage space that it is going to occupy. Storage space can be at a premium on mobile devices, and native apps require a relatively large chunk of that space, especially compared to Web apps. This can be demonstrated by looking at a couple of recent Web app releases, that also have native app counterparts. According to the &lt;a href=&quot;https://formidable.com/work/starbucks-progressive-web-app/&quot;&gt;developers&lt;/a&gt; of the new Starbucks Web app, the iOS version requires 148MB of storage space to install, making the Web app 99.84% smaller at 233KB. There&#39;s a similar story for the Pinterest app; to see your home feed on Android you&#39;ll need 9.6MB, on iOS 56MB, and on Web 150KB.&lt;/p&gt;
&lt;h2 id=&quot;there&#39;s-a-web-app-for-that&quot;&gt;There&#39;s a web app for that &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#there&#39;s-a-web-app-for-that&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Perhaps the most notable Web app launched this year would be &lt;em&gt;Twitter Lite&lt;/em&gt;. Presumably taking its name from its aim to use less data, and take up less storage space, Twitter Lite, like other Web apps mentioned, has a much smaller footprint; being &lt;a href=&quot;https://blog.twitter.com/engineering/en_us/topics/open-source/2017/how-we-built-twitter-lite.html&quot;&gt;1-3%&lt;/a&gt; the size of its native counterparts. Despite the &amp;quot;Lite&amp;quot; moniker, the app feels fully fledged. I&#39;ve been using it in place of the native app on my phone for the past couple of months and have not found the experience to be diminished in any way, other than some interface design decisions, which I don&#39;t believe to be platform related. The app makes use of new Web features that make it feel like an app in the ways that we expect; for example it can be added to your home screen via a prompt when first used, has push notification support, and can be used offline, without feeling broken. This app seems to demonstrate that the historical arguments for native over Web, that I referred to as &amp;quot;performance&amp;quot; and &amp;quot;persistence&amp;quot;, no longer apply. Like any other Web app, Twitter Lite also avoids some of the frictions highlighted earlier, and even for Twitter this could be significant, as it continues to expand into emerging markets. Potential users who might be on slow internet connections can connect without the big download. Users who might for whatever reason not have an account with Apple or Google can connect without needing to go through an app store.&lt;/p&gt;
&lt;h2 id=&quot;looking-forward-to-a-mobile-web...-or-is-it-back%3F&quot;&gt;Looking forward to a mobile Web... or is it back? &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#looking-forward-to-a-mobile-web...-or-is-it-back%3F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The likes of Twitter and Pinterest embracing the latest Web technologies for their mobile experiences is encouraging, for those of us who would like to see the ratio of Web to native apps on our phones comparable to that of our PCs. To me, this sounds likes an exciting future. It also sounds like a recent past. This idea feels a lot like the one promised by Mozilla with their release of FireFox OS, back in 2013. FireFox OS was a mobile operating system, built on this premise of a Web app ecosystem. Towards the end of its life, the FireFox OS project seemed to move away from this original goal, but considering that the year that has given us the Twitter PWA is also the year that Mozilla &lt;a href=&quot;http://opensourceforu.com/2017/02/mozilla-shifts-connected-devices-firefox-os-team&quot;&gt;officially put FireFox OS to bed&lt;/a&gt;, it seems like a good time to reflect on the Mozilla project, and look at how it relates to the emergence of the progressive web app. I spoke to Benjamin Francis, a Software Engineer at Mozilla, and asked if he thought my comparison of FireFox OS and PWAs was a fair one. He said he thought that it was, and added that the long term goal of the project was to &amp;quot;create new web standards to make the web just as capable as native app platforms&amp;quot;. The OS brought with it the vision that I have been referring to, of freeing mobile use from the confines of app stores. As Benjamin put it &amp;quot;to make the open web the third app platform on mobile&amp;quot;. It would seem that the vision was not realised however, FireFox OS is not today competing with iOS and Android. I would suggest though that the vision is still in the process of being realised, despite there no longer being a team at Mozilla working on it. The apps emerging today could be argued to be a continuation of the work started by Mozilla. Benjamin gave an example of how closely related FireFox OS was to what we today are calling progressive Web apps, pointing out that a version of the software included the concept of &amp;quot;pinned apps&amp;quot;, the same as, but predating, what we see today with PWAs. So can Web apps thrive on mobile, where FireFox OS struggled? We should first recognise that this is not an apples and apples comparison, its like comparing the Web emerging on desktops with an emerging desktop operating system. While the Web has never quite become an operating system, FireFox OS is just one of several attempts that have failed to get traction, on our desktops the Web browser has become a platform that sort of resembles one, a place from where we run a lot of our applications. The same cannot be said for mobile. So perhaps the question should be, was there something inherent in mobile devices, that stifled Mozilla&#39;s efforts? The prevailing opinion seemed to be &amp;quot;sort of&amp;quot;; not inherent technical aspects, but rather the foothold that Apple and Google have on that market. Benjamin offers an alternative view, suggesting that rather than FireFox OS being too late to market, it was actually too early, ahead of its time.&lt;/p&gt;
&lt;h2 id=&quot;in-the-spirit-of-the-web%2C-let&#39;s-collaborate&quot;&gt;In the spirit of the Web, let&#39;s collaborate &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#in-the-spirit-of-the-web%2C-let&#39;s-collaborate&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Whether you believe that Mozilla was too early or too late to the mobile OS party, I think it&#39;s safe to say, given that Apple and Google also (probably not coincidentally) dominate the mobile browser market, mobile Web stands a better chance of thriving if these dominating forces are pushing it forward. The fact is that Google at least, is already very much doing this, being a driving force for the progressive app concept, and adding support for it in Chrome for Android. Apple on the other hand has been reluctant to get behind the technology at the heart of PWAs, though there are signs that their position might be &lt;a href=&quot;https://m.phillydevshop.com/apples-refusal-to-support-progressive-web-apps-is-a-serious-detriment-to-future-of-the-web-e81b2be29676&quot;&gt;shifting&lt;/a&gt;. The differing positions of Apple and Google comes as no surprise, when you consider their differing business models (one makes electronic devices, the other collects data), but as long as Apple resists implementing the features that define progressive Web apps, some developers will be reluctant to embrace the Web as a legitimate alternative to native mobile apps. I&#39;m somewhat optimistic on this issue however, I think we can draw a parallel with an earlier phase of browser evolution. When Web designers really started to push the boundaries of what a website could look like, Internet Explorer was dragging its feet in terms of its rendering capabilities. One could argue that Microsoft was forced to play catch up when users started switching their browser to the likes of FireFox. This of course relied on Web designers and developers pushing the boundaries, not letting them be drawn by Microsoft.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/an-end-to-app-fragmentation/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;2017 has been a significant year in the story of how we interact with our mobile devices, how developers build the applications that make them useful, and ultimately how we interface with the internet. The release of a mobile Web app by Twitter gave credibility to the idea that we may be at the dawn of a new era of mobile app. For those of us excited by this idea though, the disbanding of the FireFox OS team reminded us that we had been here before, and gave us pause for thought. While we may not see a wholesale replacement of the app ecosystem, such as a Web based OS, any time soon; in my assessment, the Web will continue to evolve to meet our mobile needs, just as it did our desktop needs. That is to say that the Web on mobile devices will become more sophisticated, more integrated, and more utilised. Just as with the earlier Web evolutions, there remains a need for creation and adoption of cross browser standards, to keep the platform viable, and to avoid a situation where developers replace native app development with some sort of OS dependant Web development. At this time, one of the biggest question-marks on the future of mobile Web appears to be Apple&#39;s adoption of the emerging developments. I believe though that if the Web community keeps pushing the boundaries of the platform, then Apple will adopt the standards, rather than have Safari become the next Internet Explorer. We should make no mistake though, an open Web is something that we increasingly need to fight for; the push-back against the app store paradigm is just one of the battles.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Data-cards</title>
		<link href="https://smth.uk/data-cards/"/>
		<updated>2017-08-14T00:00:00Z</updated>
		<id>https://smth.uk/data-cards/</id>
		<content type="html">&lt;p&gt;It can be useful to recognise patterns in the challenges we face, and in our responses to those challenges. In doing this, we can build a library of solutions, a useful resource when similar challenges arise in the future. When working on innovative projects, as is often the case at OKI, creating brand new challenges is inevitable. With little or no historical reference material on how best to tackle these challenges, paying attention to your own repeatable solutions becomes even more valuable.&lt;/p&gt;
&lt;p&gt;From a user interface design point of view, these solutions come in the form of design patterns - reusable solutions to a commonly occurring problems. Identifying, and using design patterns can help create familiar processes for users; and by not reinventing the wheel, you can save time in production too.&lt;/p&gt;
&lt;p&gt;In our work on &lt;a href=&quot;http://frictionlessdata.io/data-packages/&quot;&gt;Data Packages&lt;/a&gt;, we are introducing a new task into the world - creating those data packages. This task can be quite simple, and it will ultimately be time saving for people working with data. That said, there is no escaping the fact that this is a task that has never before been asked of people, one that will need to be done repeatedly, and potentially, from within any number of interfaces.&lt;/p&gt;
&lt;p&gt;It has been my task of late to design some of these interfaces; I’d like to highlight one pattern that is starting to emerge - the process of describing, or adding metadata to, the columns of a data table. I was first faced with this challenge when &lt;a href=&quot;https://github.com/mintcanary/os-mockups&quot;&gt;working&lt;/a&gt; on &lt;a href=&quot;https://openspending.org/packager/&quot;&gt;OS Packager&lt;/a&gt;. The objective was to present a recognisable representation of the columns, and facilitate the addition of metadata for each of those columns. The adding of data would be relatively straight forward, a few form fields. The challenge lay in helping the user to recognise those columns from the tables they originated. As anyone who works with spreadsheets on a regular basis will know, they aren’t often predictably or uniformly structured, meaning it is not always obvious what you’re looking at. Take them out of the familiar context of the application they were created in, and this problem could get worse. For this reason, just pulling a table header is probably not sufficient to identify a column. We wanted to provide a preview of the data, to give the best chance of it being recognisable. In addition to this, I felt it important to keep the layout as close as possible to that of say Excel. The simplest solution would be to take the first few rows of the table, and put a form under each column, for the user to add their metadata.&lt;/p&gt;
&lt;img src=&quot;https://blog.okfn.org/files/2017/08/illustration1.png&quot; width=&quot;968&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;This is a good start, about as recognisable and familiar as you’re going to get. There is one obvious problem though, this could extend well beyond the edge of the users screen, leading to an awkward navigating experience. For an app aimed at desktop users, horizontal scrolling, in any of its forms, would be &lt;a href=&quot;https://www.nngroup.com/articles/horizontal-scrolling/&quot;&gt;problematic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, in the spirit of the good ol’ webpage, let’s make this thing wrap. That is to say that when an element can not fit on the screen, it moves to a new “line”. When doing this we’ll need some vertical spacing where this new line occurs, to make it clear that one column is separate from the one above it. We then need horizontal spacing to prevent the false impression of grouping created by the rows.&lt;/p&gt;
&lt;img src=&quot;https://blog.okfn.org/files/2017/08/illustration2.png&quot; width=&quot;680&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;The &lt;em&gt;data-card&lt;/em&gt; was born. At the time of writing it is utilised in OS Packager, pretty closely resembling the above sketch.&lt;/p&gt;
&lt;img src=&quot;https://blog.okfn.org/files/2017/08/packager.jpg&quot; width=&quot;670&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;Data Packagist is another application that creates data packages, and it faces the same challenges as described above. When I got involved in this project there was already a working prototype, I saw in this prototype data cards beginning to emerge.&lt;/p&gt;
&lt;img src=&quot;https://blog.okfn.org/files/2017/08/potential-card.jpg&quot; width=&quot;656&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;It struck me that if these elements followed the same data card pattern created for OS Packager, they could benefit in two significant ways. The layout and data preview would again allow the user to more easily recognise the columns from their spreadsheet; plus the grid layout would lend itself well to drag and drop, which would mean avoiding multiple clicks (of the arrows in the screenshot above) when reordering. I incorporated this pattern into the design.&lt;/p&gt;
&lt;img src=&quot;https://blog.okfn.org/files/2017/08/packagist.jpg&quot; width=&quot;513&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;Before building this new front-end, I extracted what I believe to be the essence of the data-card from the OS Packager code, to reuse in Data Packagist, and potentially future projects. While doing so I thought about the current and potential future uses, and the other functions useful to perform at the same time as adding metadata. Many of these will be unique to each app, but there are a couple that I believe likely to be recurring:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reorder the columns&lt;/li&gt;
&lt;li&gt;Remove / ignore a column&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These features combine with those of the previous iteration to create this stand-alone data-card project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://mintcanary.com/data-cards/&quot;&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mintcanary/data-cards&quot;&gt;Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Time will tell how useful this code will be for future work, but as I was able to use it wholesale (changing little more than a colour variable) in the implementation of the &lt;a href=&quot;http://mintcanary.com/packagist/&quot;&gt;Data Packagist front-end&lt;/a&gt;, it came at virtually no additional cost. More important than the code however, is having this design pattern as a template, to solve this problem when it arises again in the future.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Rip it up and start again</title>
		<link href="https://smth.uk/rip-it-up-and-start-again/"/>
		<updated>2017-06-23T00:00:00Z</updated>
		<id>https://smth.uk/rip-it-up-and-start-again/</id>
		<content type="html">&lt;p&gt;As a designer, your job could be described, fundamentally, as &amp;quot;to find/create the best solution(s) to a given set of challenges&amp;quot;. Within that function are the tasks of recognising, and responding to a solution that is not working out. You&#39;ll find people on your team, and further afield that help you with the &lt;em&gt;recognising&lt;/em&gt; part, but the response part, that probably rests squarely on your shoulders.&lt;/p&gt;
&lt;p&gt;Your response will fall into one of two categories: 1) Adapt/tweak/iterate. 2) In the &lt;a href=&quot;https://open.spotify.com/track/1eamsmwcYYhJwTgMFdQ6YN&quot;&gt;immortal words of Edwyn Collins&lt;/a&gt; - rip it up and start again. The first option will usually be the way to go, but sometimes the second option is the best path forward, however daunting.&lt;/p&gt;
&lt;p&gt;If you&#39;re working in an environment that is genuinely in pursuit of good design/solutions, then time will not be the dominant factor in your decision making. Chances are though, more often than not, it&#39;s going to be a pretty big one. Making the decision to start over can feel like a step backwards; taking a step backwards can feel counterproductive with a deadline looming. I prefer though to think of it as a step forward; a step forward for the design, as opposed to a step backwards on the timeline. After all, time is a secondary concern here, right? There can also be a reluctance that stems from the time invested in the thing you are about to &amp;quot;throw away&amp;quot;. This is an understandable concern, but you shouldn&#39;t let it tempt you down the wrong path. If you are confident that you can get to where you want to be, without using the stuff you&#39;ve already made, with the resources you have left, then this has to be a valid option. There&#39;s a limited window here, there will usually come a point in a project where starting again is just not feasible. As much as I argue for quality over speed, a timeline is a real, and important aspect of any project. The further along that timeline you find yourself, the more difficult it is going to be to make the decision to go back to the drawing board. In my experience, the counterintuitive path can actually be a more efficient route to where you want to be. The alternative can mean sinking a lot of time and energy into trying to tweak your way to a completely new solution.&lt;/p&gt;
&lt;p data-quote=&quot;You need to obtain and understand the game changing insights as early as possible.&quot;&gt;To keep the &lt;em&gt;rip it up&lt;/em&gt; option alive, you need to obtain and understand the game changing insights as early as possible. There are established processes in the design world, built for this purpose, such as getting feedback to wireframes/schematics before spending time on comprehensive designs. In any such process that allows you to gain insight from a minimal investment of time, there is a balance to be found between time invested in something that will not form part of the finished product and time potentially wasted working on the &lt;em&gt;wrong&lt;/em&gt; finished product. This is an accepted principle in the design industry, most web designers will be happy to spend the &amp;quot;extra&amp;quot; time on schematics, in order to minimise the chance of more costly reworkings further down the line. Decisions of this nature are made throughout a project and effect the options available to you when those game changing insights surface. The right decisions are going to differ from project to project, from designer to designer, but I believe it is essentially about striking a balance between allowing yourself freedom to experiment and get things wrong, and committing to an idea when the time is right. For example, a decision I make when designing a webpage is whether to design in an image editing application or in code. There are many good arguments for the latter, and there are people who will argue that if your not designing in code then you are doing it wrong, but I typically like to incorporate a phase of static designs, because I feel it gives me more of the aforementioned freedom (this probably also means getting designs in front of stakeholders more quickly, so they can give you the feedback that they should have given you when looking at the wireframes). I don&#39;t do this because I prefer designing statically per se. To be clear, I&#39;m someone who spends a lot of time designing in code, and believe it is the right way to go, but only once the initial experimentation (and possibly getting things wrong) is done. Code (at least good code that you intend to be used in the live project) represents a significant investment, one that can be difficult to discard. So I go out of my way to design in the old-school way in order to maintain the freedom to make big changes.&lt;/p&gt;
&lt;p&gt;We probably all like to believe that we&#39;ll get things right first time, especially in matters that we consider ourselves expert. I &lt;a href=&quot;https://manifesto.smth.uk/#2&quot;&gt;advocate&lt;/a&gt; for recognising when we don&#39;t. In order to get things right on the next attempt, we need to give ourselves the freedom to rip it up and start again.&lt;/p&gt;
&lt;p&gt;Wait, what&#39;s all this about moving to the other end of the country? I&#39;m currently one third of the way through a Masters degree, at my first choice of university for this course - Norwich University of the Arts. In practice it hasn&#39;t felt quite like the right fit for for me. I feel I am in that critical period where starting over still feels feasible. So having considered both the &lt;em&gt;tweak&lt;/em&gt; and &lt;em&gt;rip it up&lt;/em&gt; options, I&#39;m taking my own advice and seeking a new solution. I&#39;m very excited to have accepted a place on a Masters at Edinburgh Collage of Art.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Shock</title>
		<link href="https://smth.uk/shock/"/>
		<updated>2017-03-31T00:00:00Z</updated>
		<id>https://smth.uk/shock/</id>
		<content type="html">&lt;p&gt;Following on from my post about &lt;a href=&quot;https://smth.uk/challenging-norms&quot;&gt;challenging norms&lt;/a&gt;, I want to look at one of the techniques used to do this. Shock is as a common ingredient found in campaigns challenging established thinking. Whether that be the confrontation with a dying person in anti-smoking campaigns or the UK Government&#39;s modern slavery campaign, featuring the revelation of slavery taking place in a typical UK street. When confronting norms, it stands to reason that some form of shock be required, given the tendency of norms to be treated as facts of life, or &amp;quot;just the way things are&amp;quot;. When it comes to following norms, we are on autopilot.&lt;/p&gt;
&lt;p&gt;Shock can be derived in different ways. In perhaps its most obvious form, it can be found as brutal or gory imagery. Examples of this include the Art Workers&#39; Coalition&#39;s anti Vietnam war poster, depicting massacred victims; and more recently PETA&#39;s anti fur trade campaign, featuring celebrities holding dead, skinned animals. Shock can also be derived from juxtaposing improbable elements, a technique often used by German Communist designer &lt;a href=&quot;http://www.tate.org.uk/art/artists/john-heartfield-8341&quot;&gt;John Heartfield&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://news.bbcimg.co.uk/media/images/51595000/jpg/_51595459_bhf2005fattyarteriescampaign.jpg&quot; alt=&quot;Artery, British Heart Foundation, 48 sheet poster&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The fat filled cigarettes of the UK Government&#39;s anti-smoking campaign is an example of juxtaposition working to great effect. The success here - &amp;quot;43% of respondents spontaneously mentioned &#39;smoking clogs/makes fat stick in your arteries&#39;&amp;quot; - was not of course a result of the viewer merely being shocked, the accompanying messaging was crucial.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cpb-eu-w2.wpmucdn.com/blogs.brighton.ac.uk/dist/1/1680/files/2015/10/and-babies-1up7273.png&quot; alt=&quot;And Babies? And Babies, Art Workers’ Coalition, 1970, poster&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Shock itself should not be seen as the catalyst for change. Shock, I would argue, is best placed to prompt the viewer to disengage autopilot; or to put it another way, engage their mind. A campaign for positive change should be born of a fundamental truth, or at least an idea that will resonate with the viewer&#39;s values - &amp;quot;smoking is harmful to health&amp;quot;, &amp;quot;unnecessary killing is cruel&amp;quot;. The truth at the heart of the Art Workers&#39; Coalition poster was that a decision to go to war, is a decision to kill innocent people; a decision that is brought into question with the text &amp;quot;And babies? And babies&amp;quot;. It is in this truth, I would argue, that the power resides.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://082ab06849c4789c32c5-03005553b1375ef1efc4f384a5c102cb.ssl.cf3.rackcdn.com/d2/f6/85086_a7b6384a54904355aa38f1c4e7cb5de4.jpg&quot; alt=&quot;It’s Not Happening Here, But It’s Happening Now, Amnesty International, 2013, poster&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As D&amp;amp;AD wrote of the Amnesty International &lt;em&gt;It&#39;s Not Happening Here, But It&#39;s Happening Now&lt;/em&gt; campaign, &amp;quot;What was needed here was the simplest truth being told in the simplest way. Something no one can argue with is harder to ignore.&amp;quot;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Challenging norms</title>
		<link href="https://smth.uk/challenging-norms/"/>
		<updated>2017-01-14T00:00:00Z</updated>
		<id>https://smth.uk/challenging-norms/</id>
		<content type="html">&lt;p&gt;I have recently been working on a couple of projects aimed at questioning current thinking, one around addiction, another focused on animal agriculture. A similarity exists in the ideas that emerged from these; both anticipate a voice of reason winning out, were it not for the normalisation of current thinking. I think this is a theory worth dwelling on, one I liken this to paths through a forest. Most people will follow the path most well worn, because this is a logical indication that this path tracks the best route. Another path, which takes in the more beautiful scenery, may have fallen out of use. This could be for good reason, perhaps a tree had fallen and blocked the path. What if that tree has since been removed however? Then walkers are missing out on the view, simply because that is what everyone else is doing. There is great potential here for the more scenic route to become at least as well trodden, but it requires two things. Firstly, someone to investigate the path and report their findings. Secondly someone to spread the word, or signpost the path. While some of my work in recent years has been in aid of the first task, it is the second that I am interested in here.&lt;/p&gt;
&lt;p data-quote=&quot;A policy considered too radical to be popular with the public, can, by shifting the Overton Window, become mainstream, and even considered common sense.&quot;&gt;It should be stated here that the reality is more complicated than one idea being more intuitive than another. While &lt;a href=&quot;http://publicinterest.org.uk/download/values/Common%20Cause%20Handbook.pdf&quot;&gt;research&lt;/a&gt; has shown than humans have a consistently occurring set of values, we also have to consider what it means to have prescriptive social norms. In the world of politics, there exists an idea known as the ‘Overton Window’. The Overton Window, a term coined in homage to Joseph P. Overton, late vice-president of a political think tank, describes what is considered politically possible or reasonable at any given time, while remaining within the political mainstream. This is obviously a useful tool for a political leader; ensuring that new policies sit within this window prevents them from being labelled as extreme or absurd. The important aspect of the Overton Window to consider here though is its movability. A policy considered too radical to be popular with the public, can, by shifting the Overton Window, become mainstream, and even considered common sense. &lt;/p&gt;
&lt;p&gt;Back in the world of advertising, one of the key findings of the UK Government&#39;s anti-smoking campaign, when looking at international best practice, was the success of California in disabusing smokers of their beliefs about smoking. Beliefs fostered by the smoking industry. The UK campaign identified and confronted such beliefs, for example &amp;quot;You might as well smoke, because you&#39;ve got as much chance as being run over by a bus, as dying from smoking.&amp;quot;. We find these irrational thought patterns elsewhere too, where norms have been established that defy reason. Interviewees in Melanie Joy&#39;s &lt;em&gt;Why We Love Dogs, Eat Pigs, and Wear Cows&lt;/em&gt; are left sounding irrational, when prompted to talk about their meat eating choices, for example. To encourage the questioning of common sense, I suggest that we need to do more prompting.&lt;/p&gt;
&lt;p&gt;Voltaire wrote: “Those who can make you believe absurdities can make you commit atrocities.” I find this not only to be a good description of, but an explanation for, the social issues that I am thinking about here. These are issues with logical and reasonable solutions, but solutions that require a shift in thinking. I believe that artists and designers are well placed to facilitate this thinking, via their ability to disrupt the established narrative, just long enough to reveal the hidden truth. I suggest, as a compliment to the Voltaire quote: Those who can make you question absurdities, can help you to prevent atrocities.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>QR Codes in 2016</title>
		<link href="https://smth.uk/qr-codes-in-2016/"/>
		<updated>2016-10-23T00:00:00Z</updated>
		<id>https://smth.uk/qr-codes-in-2016/</id>
		<content type="html">&lt;p&gt;The relationship between traditional and online media is an ongoing area of interest to me. The two have their own strengths and weaknesses when it comes to communication, they also have the potential to compliment and support each other. I believe that this potential can only be realised if the reader/viewer/user is able to transition from one form of media to another. In terms of making this transition from print media to a webpage, Quick Response (QR) codes seemed to offer us a way to facilitate this.&lt;/p&gt;
&lt;p&gt;It must have been around ten years ago when I first learned of QR codes, I was working for a marketing agency back then. At this time it seemed like a no-brainer to include these codes in the magazine ads and the like that I was working on. I mean, an interactive call to action. How cool is that? As I write this in 2016, to be honest, I’m still excited about QR codes. It feels more like a guilty pleasure these days though. Outside of personal, experimental work, I can’t remember the last time I included a QR code in something I was working on. The reason for this can be partly explained quite simply: Outside of personal, experimental work, I can’t remember the last time I &lt;em&gt;scanned&lt;/em&gt; a QR code.&lt;/p&gt;
&lt;p&gt;The QR code experience, or at least the expectation of it, has become one so unfulfilling that it doesn’t even warrant the effort it takes to open an app and raise your arm. Jumped upon by marketeers, seeing it as another way to drive traffic to their webpages (that I think it’s safe to say, during the time of the QR code ascendancy, were probably unusable on a mobile device), QR became something to be ignored on a regular basis.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&quot;http://www.ijbhtnet.com/journals/Vol_4_No_6_December_2014/1.pdf&quot;&gt;study&lt;/a&gt; published in &lt;em&gt;International Journal of Business, Humanities and Technology&lt;/em&gt;, December 2014, sought to understand the extent of QR code adoption by consumers, using the adoption model:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;knowledge, persuasion, decision/implementation, and confirmation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The results showed that &lt;strong&gt;knowledge&lt;/strong&gt; of QR codes was very high  within the sample.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;93% of the respondents reported that they had seen QR codes somewhere.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Due to mobile devices not generally coming with native QR readers, &lt;strong&gt;persuasion&lt;/strong&gt; comes in the form of users having to download an app before being able to scan any codes. The study found that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;59% of all individuals surveyed have downloaded a QR code reader on their smart phone&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In terms of &lt;strong&gt;decision/implementation&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The percentage of all sample respondents who tried a QR code was 46%&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So perhaps unsurprisingly, most people who downloaded a reader app, went on to scan a code. Why 13% of the sample downloaded a reader but never tried it is unclear. A suggestion that comes to mind is that they liked the concept, but were never compelled but a specific invitation to use it.&lt;/p&gt;
&lt;p&gt;To test &lt;strong&gt;confirmation&lt;/strong&gt;, respondents who had tried QR codes at least once were asked if “they planned to continue to use them”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;53% said that they were likely to continue to use the codes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also, importantly&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;82% felt that QR code technology had worked satisfactorily.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While it’s difficult to draw conclusions about those people who had never used a QR code - maybe they didn’t know how, maybe they weren’t compelled, a picture does emerge of those people who had used them. As a large majority of people reported that the “technology had worked satisfactorily”, we must conclude that for most of the 47% of people unlikely to continue to use QR codes, the experience/content provided by the publisher of the code was not worth the effort of the user.&lt;/p&gt;
&lt;p&gt;While it’s easy to understand why QR usage &lt;a href=&quot;http://picturesofpeoplescanningqrcodes.tumblr.com/&quot;&gt;might not have lived up to the hype&lt;/a&gt; (yet), I believe it still has a place in communication design. Given a compelling reason to scan, and an appropriate resulting experience, there’s still scope for rewarding experiences with QR codes.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Define Value</title>
		<link href="https://smth.uk/define-value/"/>
		<updated>2016-09-30T00:00:00Z</updated>
		<id>https://smth.uk/define-value/</id>
		<content type="html">&lt;p&gt;Yesterday I received feedback on my &lt;a href=&quot;https://manifesto.smth.uk/&quot;&gt;Manif.es/to&lt;/a&gt; v1.0 from a group of my peers. The feedback came in the form of post-it notes. Many were very complimentary:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/manifesto-postit-love.jpg&quot; width=&quot;640&quot; alt=&quot;Collaborate exchange ideas and knowledge. Add value to society. Love love love!&quot; /&gt;
&lt;p&gt;there were some I’d like to follow up on:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/manifesto-postit-work-with.jpg&quot; width=&quot;590&quot; alt=&quot;Very bold. You clearly believe. I fully respect that. I hope to learn from and work with you.&quot; /&gt;
&lt;p&gt;The most valuable to me however was this one:&lt;/p&gt;
&lt;img src=&quot;https://smth.uk/img/manifesto-postit-value.jpg&quot; width=&quot;610&quot; alt=&quot;Define value&quot; /&gt;
&lt;p&gt;Referring to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;.06/ Elevate that which will add &lt;strong&gt;value&lt;/strong&gt; to society. Do not waste effort manufacturing demand for that which is worthless.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This note neatly highlights where I have failed in at least one of my manifesto items. Most obviously:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;.08/ Perspective shift. Avoid privileging your own perspective. Seek other perspectives. Iterate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To be fair, I did deliberately include the word “iterate” here, as a prediction that there will always be missing perspectives.&lt;/p&gt;
&lt;p&gt;I could continue to defend myself by arguing that this is a personal manifesto, and so “value” means whatever I believe “value” to mean at a given time, and in a given context. By extension, anyone adopting this manifesto should consider what they believe to be valuable here.&lt;/p&gt;
&lt;p&gt;While I think that this is a valid response, that it comes down to the conscience of the artist/designer, I don’t feel that it quite cuts it. As I think the commenter was alluding to, “value” is such a broad, complicated, and subjective term that it becomes almost meaningless in isolation.&lt;/p&gt;
&lt;p&gt;I’d like to literally follow the suggestion on the post-it, and (attempt to) define “value”, in the context I was thinking about  it at the time of writing. The second line in my statement is crucial here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do not waste effort manufacturing demand for that which is worthless.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The idea being, that if you find yourself having to manufacture demand or consent for something, then that thing is probably not adding &lt;em&gt;value&lt;/em&gt; to the lives of your audience. At least not enough value, in those people’s opinions. So my definition of value here is very much tied to what the potential audience feel is beneficial, in some sort of instinctual way. As opposed to being sold something.&lt;/p&gt;
&lt;p&gt;This is by no means a flawless definition. It immediately raises questions around, for example, who’s opinions you are seeking, the value of a majority vs minority view, people “instinctively” knowing what’s best for them. Not to mention the value to the person creating the work. It also assumes that the value of something is predictable and measurable. These are all points that I feel deserve further questioning, and hope to return to individually. Perhaps eventually explicitly referencing in the manifesto. When thinking about all this in the context of the manifesto though, I find myself returning to my earlier defence. These are questions entrusted to whoever is creating the work, those people are uniquely positioned to address them in the context that they are presented.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Manifesto</title>
		<link href="https://smth.uk/manifesto/"/>
		<updated>2016-09-09T00:00:00Z</updated>
		<id>https://smth.uk/manifesto/</id>
		<content type="html">&lt;p&gt;There is a long tradition of artists and designers setting out what they believe is right, both in terms of their profession and more broadly, society. From &lt;em&gt;The Bauhaus Manifesto&lt;/em&gt; to &lt;em&gt;First Things First&lt;/em&gt; to &lt;em&gt;The Riot Grrrl Manifesto&lt;/em&gt;, these public declarations of the intent have at the very least brought paradigms into sharp focus.&lt;/p&gt;
&lt;p&gt;I am hovering at the edge of the illustrious group that came before me, by creating my own, personal, design manifesto. I call it &lt;a href=&quot;https://manifesto.smth.uk/&quot;&gt;Manif.es/to&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;MANIF.ES/TO&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Question everything. Never blindly accept a premise. Solutions should be sought to problems, not to existing solutions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Believe in the idea, or find a new one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Research. Do not assume that the best answers are to be found in your own mind.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Prioritise socially driven enterprises and projects that you believe will bring about positive change.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Be honest. Never seek to manipulate or deceive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Elevate that which will add value to society. Do not waste effort manufacturing demand for that which is worthless.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Collaborate. Exchange ideas and knowledge. Strive to involve and evolve the wider community.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Perspective shift. Avoid privileging your own perspective. Seek other perspectives. Iterate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Respect human effort. Make any experience one worthy of the user’s time.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://manifesto.smth.uk/&quot;&gt;Manif.es/to&lt;/a&gt; v1.0&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Slack as a CMS</title>
		<link href="https://smth.uk/slack-as-a-cms/"/>
		<updated>2016-08-06T00:00:00Z</updated>
		<id>https://smth.uk/slack-as-a-cms/</id>
		<content type="html">&lt;p&gt;I recently undertook the task of redesigning a couple of key pages for the Open Knowledge International website. A primary objective here was to present ourselves as people, as much as an organisation. After all, it’s the (incredible) people that make Open Knowledge International what it is. One of the pages to get some design time was the &lt;em&gt;team&lt;/em&gt; page. Here I wanted to show that behind this very static page, were real people, doing real stuff. I started to explore the idea of status updates for each staff member. This would, if all goes to plan, keep the content fresh, while hopefully making us a little more relatable.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mir-cdn.behance.net/v1/rendition/project_modules/max_1200/19906b41443863.57a62ff62b7be.jpg&quot; alt=&quot;Mockup&quot; /&gt;&lt;/p&gt;
&lt;p&gt;My work here wasn’t done. In this scenario, my colleagues become “users”, and if this idea had any chance of working it needed a close to effortless user experience. Expecting anyone other than a few patient techies to interact with the website’s content management system (CMS) on regular basis just isn’t realistic. As it happens, my colleagues and I were already creating the content I was looking for. We chat daily using an internal instant messaging app (we use Slack). As well as discussing work related issues, people often share water-cooler items such as an interesting article they have read, or a song that captures how they are feeling. Sharing stuff like this can be as easy as copy and pasting a link. Slack will grab the title of the page and present it nicely for us. So what if at that moment of sharing, you could choose to share more widely, via the website? After some discussions, we introduced a system that facilitated just this, where if you add one a a few specific hashtags to your your Slack message, it would get pushed to the website and become your most recent status. The implementation still needs a little polishing, but I’m happy to say that after a few weeks of use, it seems to be working well, in terms of uptake at least. Whether anyone visiting the site really cares, remains to be proven.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mir-cdn.behance.net/v1/rendition/project_modules/max_1200/c8f7ac41443863.57a62ff62bc90.jpg&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I really like this solution. I like that it achieves its objective of not requiring additional effort, of course. Moreover, I like that it doesn’t introduce any barriers. It doesn’t assume that anyone wanting to contribute have a certain amount of knowledge (outside of what is already proven) or are happy to learn a new tool. It doesn’t ask anyone to change their way of working. It makes me wonder, how far could you take this model? It’s a big leap, but could we expand on this to the point where the interface being interacted with is that of whatever application the content creator sees fit? Just as the (slightly modified) action of sending a message in Slack became enough to make this small content change, could/should the action of saving a Word document to your local drive be enough to publish a blog post? (That particular example is not difficult to imagine, if you assume it’s happening within a walled-off Microsoft infrastructure, but that of course would be contrary to what I’m pondering here.)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Welcome to Jekyll</title>
		<link href="https://smth.uk/welcome-to-jekyll/"/>
		<updated>2016-04-16T00:00:00Z</updated>
		<id>https://smth.uk/welcome-to-jekyll/</id>
		<content type="html">&lt;p&gt;For those of you who are familiar with Jekyll, no, I didn’t forget to delete the default post. For those who aren’t, Jekyll is a ‘Static site generator’, probably the most well known example of such a thing. It certainly has the most Github stars of all the static site generators on &lt;a href=&quot;https://www.staticgen.com/&quot;&gt;staticgen&lt;/a&gt;. It is also what I used to build this site.&lt;/p&gt;
&lt;p&gt;I’m a huge fan of static site generators. As a designer / front-end dev I find them a great solution for mocking up sites, ahead of a back-end being integrated. That’s selling these tools short, for sure. Sites created from these generators can certainly be used for full production builds. In my experience though, there is as yet no non-technical solution for content editing that matches the experience of a content management system. My personal sites (like this one) rarely need to be dynamic, and only I (someone who is happy to work in code) need to be able to administrate them. So this is another good use case for me.&lt;/p&gt;
&lt;p&gt;Jekyll is a great tool, with some good selling points. The biggest of which is probably its integration with Github Pages. Ultimately though I chose Jekyll for this site because it is very blog centric. While I wanted to give it a little shout out here, Jekyll is by no means my de facto site generator of choice.&lt;/p&gt;
&lt;p&gt;I’m a firm believer in having the right tool for the job. I don’t just mean having a screwdriver in your toolbox, I mean having a range of different screwdrivers. This analogy falls down pretty quickly. Once you’ve mastered the use of a screwdriver, you can pretty comfortably use any screwdriver you lay your hand on. Static site generators on the other hand tend to have their own unique learning curves. Having to learn the nuances of many different static site generators probably wouldn’t be a good use of anybody’s time, I do really value though, having a few favourites to choose from. I’d like to mention a couple of others, while I’m here.&lt;/p&gt;
&lt;h3 id=&quot;middleman&quot;&gt;Middleman &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/welcome-to-jekyll/#middleman&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://middlemanapp.com/&quot;&gt;Middleman&lt;/a&gt; is up there with Jekyll when it comes to established static site generators. To me, it is to websites, what Jekyll is to blogs. If I’m free from constraint, Middleman is my default choice. I find that out of the box, it gives me a good boilerplate for website projects. It’s versatile, unintrusive, and just works. I use Middleman to build my &lt;a href=&quot;https://smth.uk/photos/&quot;&gt;photography site&lt;/a&gt; for example. It’s a simple single page, essentially a list of images with captions. Middleman is there, primarily, to give me the separation of content and code, so I’m not duplicating code every time I add a photo. As you might come to expect from a static site generator, Middleman has some bonus features that make editing even easier. There’s LiveReload integration, which just needs to be switched on during initiation. There’s also a nice deployment plugin, allowing you to upload your files from your command line.&lt;/p&gt;
&lt;h3 id=&quot;roots&quot;&gt;Roots &lt;a class=&quot;direct-link&quot; href=&quot;https://smth.uk/welcome-to-jekyll/#roots&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I have relatively little experience with this one. It seems to me though that &lt;a href=&quot;https://github.com/jescalan/roots&quot;&gt;Roots&lt;/a&gt; is spoken about less (in these kind of posts) than the two aforementioned tools, and I feel it deserves a mention here. Roots has a few distinct pros and cons for me, a lot of these come down to personal preference though, so I wont’t go into them all here (I’m sure you can find in depth reviews of all these applications elsewhere). I would like to mention though, the one thing that lead me to Roots, and that’s &lt;a href=&quot;https://github.com/carrot/roots-records&quot;&gt;Roots Records&lt;/a&gt;. This extension essentially enables Roots to load remote (JSON) data, into your project, and make it available to your templates. This is something I specifically wanted for my &lt;a href=&quot;https://samsmith.name/&quot;&gt;design portfolio&lt;/a&gt; site. All the content already existed on my &lt;a href=&quot;https://www.behance.net/sam-smith&quot;&gt;Behance&lt;/a&gt; profile. Being able to pull that content into my site, without having to worry about the API going down, or hitting its usage limits, was the ideal situation for me. Beyond this use case though, I find this quite an exciting concept. It begins to truly separate content from the codebase. Meaning content editors could be interacting with an interface designed specifically for them, it’s only prerequisite being that it has to produce a JSON file. Meanwhile, us techies can continue to enjoy our static site generators :)&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Guess Who?</title>
		<link href="https://smth.uk/guess-who/"/>
		<updated>2015-12-17T00:00:00Z</updated>
		<id>https://smth.uk/guess-who/</id>
		<content type="html">&lt;p&gt;A couple of months ago, our Open Knowledge colleague &lt;a href=&quot;https://twitter.com/trickvi&quot;&gt;Tryggvi Björgvinsson&lt;/a&gt; left Open Knowledge to take a position with the Icelandic government (lucky people).&lt;/p&gt;
&lt;p&gt;Tryggvi brought many things to Open Knowledge, including an in depth knowledge and understanding of agile methodologies,&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;You will leave such a space when you depart, who&#39;s going to keep us all agile?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption class=&quot;blockquote_attribution&quot;&gt;— Michelle Heydon&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;some great retrospectives,&lt;/p&gt;
&lt;figure class=&quot;blockquote&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;The Icelandic government is lucky to have you. I hope they&#39;re prepared for apartment block and ice-cream van retrospectives!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figcaption class=&quot;blockquote_attribution&quot;&gt;— Brook Elgie&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;and board-games! I think it’s fair to say, that it didn’t take much imagination on our part to decide that his parting gift should be some form of game. After batting a few ideas around, I suggested that we make him a personalised version of the popular guessing game &lt;em&gt;Guess Who?&lt;/em&gt; “Replacing the faces with illustrations of us” I said (setting myself up for many a night illustrating). The idea was a hit, and so, armed with words of encouragement, and financial donations from the team, I set about creating a fitting gift.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Some time later&lt;/em&gt;, here I am, having completed the task, about to ship the game to our friend. We hope you like it Tryggvi :)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://smth.uk/img/guesswho1.jpg&quot; alt=&quot;Purchased a copy of the game&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://smth.uk/img/guesswho2.jpg&quot; alt=&quot;Start drawing my colleagues&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://smth.uk/img/guesswho3.jpg&quot; alt=&quot;Get finished illustrations printed&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://smth.uk/img/guesswho4.jpg&quot; alt=&quot;Cut into individual cards&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://smth.uk/img/guesswho5.jpg&quot; alt=&quot;Ready to go&quot; /&gt;&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Let’s not lose the human from our interactions</title>
		<link href="https://smth.uk/lets-not-lose-the-human-from-our-interactions/"/>
		<updated>2015-11-06T00:00:00Z</updated>
		<id>https://smth.uk/lets-not-lose-the-human-from-our-interactions/</id>
		<content type="html">&lt;p&gt;For me, one of the most fascinating, beautiful and.. human characteristics of our species, is our use of language. Be it looking at a painting, reading an essay, or a lover asking how you slept. We humans share such an array of information, in ways often unique. In ways that can help define us as individuals and build our relationships. Crucially, it works too, right? We can deliver opinion, fact and feeling in as much clarity as we desire. We can make abstract suggestions on a canvas, precisely present our views in an essay, or say “Hey, I notice you” with a seemingly trivial question about someone’s sleeping pattern.&lt;/p&gt;
&lt;p&gt;Apparently not everyone has such a crush on the nuances of language though. There seems to be a move to simplify the processes involved. To reduce them to neatly packaged (some might say “commodified”) algorithms. I first became aware of, and uncomfortable with, said phenomenon earlier this year, when attending a work summit. We had an outside organisation come in to run a session, teaching my colleagues and I the “correct” way to give and receive feedback. The proposed technique basically takes that lovely moment when a co-worker tells you you’ve done a good job, runs it through an algorithm, applies a template to it, and makes it feel utterly fake. At least that was my take on it.. I could probably improve this feedback..&lt;/p&gt;
&lt;p&gt;More recently, we’ve been hearing about how Gmail users will “benefit” from what Google is calling “Smart Reply”. In brief, this is a form of artificial intelligence that will analyse your email and suggest some responses. The pitch is that you can quickly and easily respond to an email, on the go, without typing a word. Neat huh? I’m not so sure. Even if I put to one side any concerns I may have about all my email being “read” by a bot, this brings up similar feelings to the ones I had at the “how to give feedback” session.&lt;/p&gt;
&lt;p&gt;While I’m sure Google’s AI would do an impressive job of learning to mimic how I communicate, it would still be replacing that layer of humanity. We’ve seen this to varying degrees before. We’ve all responded to a heartfelt, eloquent post with a thumbs-up or &lt;s&gt;star&lt;/s&gt; heart icon. While there is a debate to be had about whether the use of icons or emoji debases our conversations, for me there are some distinctions here. An obvious distinction is disclosure, if someone sends me an emoji, I can be pretty confident that they have not taken the time to draw it themselves. Which is fine. More to my point though, while emoji add to the tools available to the user, “Smart Reply” sets out to, at least in part, replace the user. I find this a little depressing. What’s the end-game here? It doesn’t take much imagination (depending on what films you watch, perhaps) to see the human removed from the equation entirely.&lt;/p&gt;
&lt;p&gt;Are we moving towards a world where our interactions happen without our involvement? Would we still ask a loved one how they slept, if their phone had already sent an email saying “fine thanks :)”?&lt;/p&gt;
</content>
	</entry>
</feed>
