<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Farai Gandiya</title>
    <description>The latest articles on DEV Community by Farai Gandiya (@faraixyz).</description>
    <link>https://dev.to/faraixyz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F125156%2F94b6893e-15de-4901-a5ab-9340e7487a55.jpeg</url>
      <title>DEV Community: Farai Gandiya</title>
      <link>https://dev.to/faraixyz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/faraixyz"/>
    <language>en</language>
    <item>
      <title>Improving Netlify's Default HTTP Cache-Control Headers for Immutable Assets</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Mon, 14 Feb 2022 13:06:33 +0000</pubDate>
      <link>https://dev.to/faraixyz/improving-netlifys-default-http-cache-control-headers-for-immutable-assets-1h9</link>
      <guid>https://dev.to/faraixyz/improving-netlifys-default-http-cache-control-headers-for-immutable-assets-1h9</guid>
      <description>&lt;p&gt;I decided to use the &lt;a href="https://recursive.design/"&gt;Recursive font&lt;/a&gt; on my site once again and when it went live, they kept popping in between subsequent reloads. Looking into it, it turns out that this was due to how &lt;a href="https://www.netlify.com/blog/2017/02/23/better-living-through-caching/"&gt;Netlify caches things&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does Netlify do?
&lt;/h2&gt;

&lt;p&gt;In essence, they include this header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;cache-control: public, max-age=0, must-revalidate
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As they put it, the header says &lt;q&gt;please cache this content, and then do not trust your cache&lt;/q&gt;. This is useful for assets that change frequently as the browser will always check if an asset has changed before fetching it by verifying the &lt;code&gt;ETag&lt;/code&gt; header.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seems ok. What’s the problem?
&lt;/h2&gt;

&lt;p&gt;The issue I had was that certain assets on this site (like CSS, JS, and font files) have cache busted URLs where the URL either has a hash or version number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;stylesheet&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;/fonts.1baec3efa7adb966c2c5c92e8258e75a350c5151d2679de09650f4536b185be8.css&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;stylesheet&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;/main.ba62e1ad92ea86749a3f67394100f75f0044a087c2101678a42e21ddffdaaa3f.css&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note the hashes in the hrefs. That corresponds to the file’s hash. If the underlying file changes, the hash would as well.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There’s no need to constantly revalidate such an asset as it will never change. If the asset did change, it would have a new URL that would be cached on its own. As fast as Netlify’s CDN is and however much they want to include an &lt;code&gt;ETag&lt;/code&gt;, revalidation is still pointless overhead for fingerprinted URLs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Fix This
&lt;/h2&gt;

&lt;p&gt;To fix this, I used the &lt;code&gt;immutable&lt;/code&gt; cache-control header which tells the browser that the asset will not be updated as long as it’s fresh. Note that the maximum caching age is a year which is about 31,536,000 seconds).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Cache-Control: public, immutable, max-age=31536000
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To do this, you need to &lt;a href="https://docs.netlify.com/routing/headers/"&gt;provide custom headers&lt;/a&gt;. I used an &lt;code&gt;_headers&lt;/code&gt; file which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*.woff2
    Cache-Control: public, max-age=31536000, immutable
/*.css
    Cache-Control: public, max-age=31536000, immutable
/*.js
    Cache-Control: public, max-age=31536000, immutable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works on my site since CSS and JS files will always be fingerprinted&lt;sup id="fnref:1"&gt;1&lt;/sup&gt;, and the &lt;code&gt;.woff2&lt;/code&gt; font files contain the version in the URL so if the font is updated, so will the URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;After doing this, the site loaded a bit faster and the pop-in didn’t go away. It’s an improvement, though I need to quantify it at some point. That’s a benefit of going beyond the defaults. I know I put Netlify here, but I’m sure you can apply this to any host that let’s you change HTTP headers&lt;/p&gt;

&lt;p&gt;This is all possible thanks to &lt;a href="https://gohugo.io/hugo-pipes/introduction/"&gt;Hugo which comes with a good asset pipeline&lt;/a&gt;. If Hugo didn’t have this, or I decided not to use cache busted URLs, sticking to &lt;code&gt;must-revalidate&lt;/code&gt; would be fine.&lt;/p&gt;

&lt;p&gt;Interestingly, a few days after I solved this, I found a guide by Simon Hearne which goes into &lt;a href="https://simonhearne.com/2022/caching-header-best-practices/#the-solution"&gt;caching headers best practices&lt;/a&gt; which covers other scenarios.&lt;/p&gt;

&lt;p&gt;The next performance optimization I want to do after this is preloading assets. The last time I tried it nothing changed but I hope it’ll be different this time.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Even if I include a library through NPM, I’d still cache bust it. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>webperf</category>
      <category>netlify</category>
      <category>http</category>
    </item>
    <item>
      <title>Goodbye 2021, Hello 2022</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Sat, 15 Jan 2022 16:59:30 +0000</pubDate>
      <link>https://dev.to/faraixyz/goodbye-2021-hello-2022-205d</link>
      <guid>https://dev.to/faraixyz/goodbye-2021-hello-2022-205d</guid>
      <description>&lt;p&gt;As 2021 ends and 2022 begins I want to reflect on how things went on my Codelab as well as my programming "career" along with my goals for 2022. In general, despite my many commitment issues, I managed to get some things done and I hope to get more done in 2022.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing
&lt;/h2&gt;

&lt;p&gt;In 2021, I published &lt;strong&gt;just 4 posts&lt;/strong&gt; on this blog (excluding links and contributions on other sites) which is far less than I have in previous years. The posts are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://codelab.farai.xyz/posts/pros-use-google/"&gt;"Imagine if Doctors Relied on Google As Much As Programmers Do"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codelab.farai.xyz/snippets/hugo-breadcrumbs/"&gt;Breadcrumbs In Hugo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codelab.farai.xyz/snippets/quick-dark-illustrations/"&gt;Give Your Illustrations Dark Mode With This Simple Trick&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codelab.farai.xyz/posts/color-scheme/"&gt;You Can Give A Website Dark Mode With Just One CSS Property&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given that I don't have analytics, I don't know how well any of these posts did, but I think &lt;b&gt;"Imagine if Doctors Relied on Google As Much As Programmers Do"&lt;/b&gt; got the most traction, probably more than a mega guide I published that same day (more on that in a bit). I've thought about this statement for years, but I put it into writing because some guy decided to be the main character again, arguing that we shouldn't take pride in looking shit up for our jobs.&lt;/p&gt;

&lt;p&gt;Besides these posts, I've also &lt;a href="https://dev.to/links/"&gt;captured links of interesting content I found around the web&lt;/a&gt;, most interesting of which was a video on &lt;a href="https://codelab.farai.xyz/links/collaborative-funding-adventures/"&gt;Igalia's fundraising model&lt;/a&gt;. It's a bit ironic that you need to fundraise to implement features in browsers managed by million, billion, and trillion-dollar companies, but once you hear their explanation it makes sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  Posts On Other Websites
&lt;/h3&gt;

&lt;p&gt;In 2021, I started to contribute content on other websites, specifically CSS Tricks. I remember reading how these online web development publications allow people to write on their sites, regardless of experience as long as it can help many other people. I took this up for two reasons.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To gain experience in writing for others under the eye of an editor, rather than just whatever I feel like. I got this suggestion from Cal Newport who suggests that you should do things that require a gatekeeper as it will teach you more about how to do something rather than doing your own thing and hoping people will notice.&lt;/li&gt;
&lt;li&gt;They pay. I've been unemployed for nearly 4 years and I need to start making money. This is the easiest option I have now.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I tried to contribute a couple of articles in 2021, but they were rejected. Third (and fourth) time's the charm as I managed to contribute two posts on CSS Tricks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/working-with-web-feeds-its-more-than-rss/"&gt;Working With Web Feeds: It’s More Than RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codelab.farai.xyz/elsewhere/unexpected-web-features/"&gt;Web Features That May Not Work As You'd Expect&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These posts took far longer than they should have to write and while they aren't as good as they could be, I'm glad I was able to get something published on the site I use as a reference. The post on web feeds is something I hope will get more traffic in the coming years even if it didn't spread as much as I'd hope.&lt;/p&gt;

&lt;p&gt;Now that I know I can get published elsewhere, I want to do it more in 2022, mostly for money and experience. I'm working on another post right now and I have a few other ideas so now it's a matter of executing them, preferably in under a month apiece.&lt;/p&gt;

&lt;h3&gt;
  
  
  Newsletter
&lt;/h3&gt;

&lt;p&gt;I also started a &lt;a href="https://buttondown.email/faraiscodelab/"&gt;newsletter&lt;/a&gt;. Honestly, I don't know what I'm supposed to do with it. If you have any suggestions, let me know.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Many Unpublished Posts
&lt;/h3&gt;

&lt;p&gt;There aren't as many posts on this site as there were in previous years, and that's because I had a lot of unpublished posts in 2021. By unpublished I mean two things,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;unpublished as in not published, and&lt;/li&gt;
&lt;li&gt;unpublished as in I published it but then I removed it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Concerning the posts I never got to publish, there are so many of them covering topics from image formats to armchair data analysis on RSS feeds. Some managed to get quite far even. The reason they didn't get published is similar to why my contributed posts took so much time—I'm lazy and I fell down the rabbit hole and ended up &lt;a href="https://en.wikipedia.org/wiki/Law_of_triviality"&gt;bikeshedding&lt;/a&gt; things which resulted in me &lt;a href="https://projects.csail.mit.edu/gsb/old-archive/gsb-archive/gsb2000-02-11.html"&gt;yak shaving&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The topics I wanted to cover are far more complicated than they looked at first and rather than accepting that I can always fix things if they aren't perfect, I gave up and did nothing for weeks on end.&lt;/p&gt;

&lt;p&gt;As for the posts I unpublished, I archived them on &lt;a href="https://2021.codelab.farai.xyz"&gt;2021.codelab.farai.xyz&lt;/a&gt;. I do this to clean this site and tame my content folders. They're still reachable through a 301 redirect as &lt;a href="https://www.w3.org/Provider/Style/URI"&gt;Cool URIs don't change&lt;/a&gt; but if the content you want, isn't let me know.&lt;/p&gt;

&lt;p&gt;That's it for writing, now onto things I programmed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming
&lt;/h2&gt;

&lt;p&gt;Programming-wise, I haven't made much. Actually, I programmed a lot, I just don't have much to show for it. Besides endless redesigns of my personal websites&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, I must have made the same projects over and over again without actually publishing them.&lt;/p&gt;

&lt;p&gt;The reason I struggle with actually publishing and iterating off that is that I'm worried about what prospective employers will think. As much as they say they like personal projects, I feel like putting the source code out there will invite a lot of nitpicking about how I did everything. Each redesign I keep hoping that things will be different, but they rarely are. In 2022, I hope to bias towards shipping and fixing things as I go.&lt;/p&gt;

&lt;p&gt;While I haven't got a portfolio to my name per se, I've learned a lot given all the experimentation I did. It's Farai's Codelab after all! From web workers to canvas, I've tinkered a lot. Just look at all the &lt;a href="https://codepen.io/collection/gYkQbE"&gt;shitty CodePens I've made&lt;/a&gt;. Yeah, they're shit but they're a learning experience as well. Expect a write-up on that soon.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open Source
&lt;/h3&gt;

&lt;p&gt;As for open-source, while I haven't contributed any code, I made a few bug reports to a few projects I use, namely &lt;a href="https://github.com/gohugoio/hugo/issues/8961"&gt;Hugo&lt;/a&gt;, &lt;a href="https://github.com/LeaVerou/css.land/issues/14"&gt;LCH Color Picker&lt;/a&gt; and the &lt;a href="https://github.com/arrowtype/recursive/issues/433"&gt;Recursive Font&lt;/a&gt;. It isn't respected as much as code, but I like to think that I'm helping developers triage issues.&lt;/p&gt;

&lt;p&gt;In 2022, I hope to be a better open-source user and make bug reports whenever I find issues. I also want to help improve &lt;a href="https://gohugo.io/"&gt;Hugo's documentation&lt;/a&gt; since it has a lot to improve upon. The first thing to document is &lt;a href="https://github.com/gohugoio/hugoDocs/issues/1622"&gt;Hugo's XML unmarshalling&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  YouTube
&lt;/h2&gt;

&lt;p&gt;I've got two YouTube channels, &lt;a href="https://www.youtube.com/channel/UCuL0GJ0pA1rxuHTV9kSGWjg"&gt;Farai's Codelab&lt;/a&gt; which is supposed to be my main channel and &lt;a href="https://www.youtube.com/channel/UC3AW63kz3oGfTd7XqCPejTw"&gt;Farai's Codelab Notes&lt;/a&gt;, which is meant to hold archives to live streams and throwaway videos.&lt;/p&gt;

&lt;p&gt;On the "main" channel, I've only published content I made years ago and I haven't published anything new on it. Interestingly, the "secondary" channel has more uploads which are mostly me going through &lt;a href="https://www.youtube.com/watch?v=9trT-LL8UL0&amp;amp;list=PLCMLbsG2CZ13ZKEd0r_w1lALPD1pUemvY"&gt;Cracking The Coding Interview&lt;/a&gt;. Despite the fact my friend bought it for me as a Christmas gift, I've never used it until now. I hope to go through this book and finish it.&lt;/p&gt;

&lt;p&gt;As for analytics, just know that I only got 20 minutes of watch time and 14 views on the secondary channel and 4 hours of watch time and 308 views on my main channel. I was surprised that I got 4 hours of watch time on my secondary channel, but I realized that's because of the one post I made which embedded two videos. Glad to see that they were watched.&lt;/p&gt;

&lt;h2&gt;
  
  
  Career
&lt;/h2&gt;

&lt;p&gt;It's still nonexistent, but there are some embers, mostly thanks to the posts I wrote for CSS Tricks which have resulted in me making the most money since graduation in 2018. The job search process is very discouraging which is why I haven't bothered to try for a long time. In 2022, I want to give it one last shot. If it doesn't work, I'll try something else. It's unlikely, but unlikely things happen.&lt;/p&gt;

&lt;p&gt;I also managed to get some contract work through connections, but they mostly failed. For one, I managed to get an MVP running and I fogot about the project only to meet the client in a bank where he paid me for what I did. Next year I hope to be more disciplined when it comes to such projects. Word of mouth is powerful and the best way for people to say nice things about you is to be dependable, which is something I need to work on.&lt;/p&gt;

&lt;p&gt;Another thing I'll need to work on is financial management, but that's another post altogether.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson of The Year: Embrace Experimentation and Iteration
&lt;/h2&gt;

&lt;p&gt;The reason I called this site Farai's Codelab was to give myself a license to experiment with code and share what I've learned. Over the years, that experimental fervor has faded as I got worried that what I produce won't look good to others, which they don't. After many random redesigns, spontanious project ideas and ugly CodePens, I've realized just how rewarding experimentation is. There's a rush I get in figuring things out and though it's ugly, I've learned a lot from it.&lt;/p&gt;

&lt;p&gt;As I go into 2022, I not only want to continue experimenting, I want to embrace iteration more. Rather than perfection upfront, I want to ensure that my projects and articles improve over time. Interestingly enough, this very article is an example of that. I initially published it without this section but decided to add it just to share the biggest lesson I learned in 2021.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In all, I'm still languishing. While I haven't accomplished all I wanted to do, I managed to get some things done and make a little money while a lot in the process. 2022 is the year I hope to turn things around, become financially independent, and start a career.&lt;/p&gt;

&lt;p&gt;As for what I want to achieve next year, there's a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to write more content. Between my unpublished drafts, overactive minds, and possible guest articles, I want to put more content out there.&lt;/li&gt;
&lt;li&gt;Take YouTube seriously. Besides putting my posts in video form, I've got plenty of ideas that could do well on YouTube. I just need to take it seriously.&lt;/li&gt;
&lt;li&gt;Figure out what I'm supposed to do with my newsletter.&lt;/li&gt;
&lt;li&gt;Make the projects I've wanted to make for years.&lt;/li&gt;
&lt;li&gt;Understand the basics of web development, lest I make more ugly sites like the one you're looking at now.&lt;/li&gt;
&lt;li&gt;Contribute more to open source, mostly bug reports and improving Hugo's documentation.&lt;/li&gt;
&lt;li&gt;Finally, and biggest of all, I want to get a job (preferably outside Zim) and start my tech career either programming or writing technical content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a lot, but if you break it down and work on it consistently over many years, it's doable, I hope.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading! If you got this far down, you should know that there'll be another post going through the projects and posts I plan to make in 2022. It'll be a premium exclusive, so &lt;a href="https://patreon.com/faraiscodelab"&gt;sign up to my Patreon&lt;/a&gt; if you want to read it. I might also make a post going through my old projects which will also be a premium exclusive.&lt;/em&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Yes this site looks like ass right now. It's undergoing yet another redesign. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Working With Web Feeds: It’s More Than RSS</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Fri, 17 Dec 2021 17:50:43 +0000</pubDate>
      <link>https://dev.to/faraixyz/working-with-web-feeds-its-more-than-rss-1062</link>
      <guid>https://dev.to/faraixyz/working-with-web-feeds-its-more-than-rss-1062</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/elsewhere/making-great-feeds/"&gt;Working With Web Feeds: It’s More Than RSS&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Between Google Chrome experimenting with “following” sites, along with a growing frustration of how social media platforms limit a creator’s reach to their fans through algorithmic feeds, there’s been renewed interest in RSS feeds and they’re primed for a comeback as we get into 2022.&lt;/p&gt;

&lt;p&gt;You may have heard whispers that “RSS in dead” around the web, but the truth is that they are still widely used as virtually every podcast uses one. Maybe you used to be an RSS fan and need to get re-acquainted with it. Or maybe you’re like Chris here at CSS-Tricks and still love RSS. Whatever the case, RSS is a web technology like any other, and there are best practices for how to create and curate a feed.&lt;/p&gt;

&lt;p&gt;That’s exactly what I’m going to walk you through in this article. Let’s talk about the different kinds of feeds, how to implement them, and what strategies you can use to get the most out of your feed content.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post took far longer than I expected to write, but it’s finally finished. It only took 3 months instead of 6 this time. Thanks again to the CSS Tricks team for helping me with this!&lt;/p&gt;

&lt;p&gt;I plan on adding commentary, but that’ll be an exclusive post.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;See &lt;a href="https://css-tricks.com/working-with-web-feeds-its-more-than-rss/"&gt;Working With Web Feeds: It’s More Than RSS on css-tricks.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;reffering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/?tag=faraixyz00-20"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an Amazon affiliate),&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack="&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bWorking%2bWith%2bWeb%2bFeeds%253A%2bIt%25E2%2580%2599s%2bMore%2bThan%2bRSS"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webfeeds</category>
    </item>
    <item>
      <title>Imagine if Doctors Relied on Google As Much As Programmers Do</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Thu, 16 Dec 2021 17:19:48 +0000</pubDate>
      <link>https://dev.to/faraixyz/imagine-if-doctors-relied-on-google-as-much-as-programmers-do-146k</link>
      <guid>https://dev.to/faraixyz/imagine-if-doctors-relied-on-google-as-much-as-programmers-do-146k</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/posts/pros-use-google/"&gt;"Imagine if Doctors Relied on Google As Much As Programmers Do"&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;This is a common refrain programmers have from time to time, but the truth is that doctors do look things up for their job. Might not be though Google, but they don’t just rely on head knowledge.&lt;/p&gt;

&lt;p&gt;There was a time my face got paralyzed and I had to go to a doctor. I found one and the first thing they checked for was if I was having a stroke. Thankfully I wasn’t having one (if I was, would I even be there). After that, they sat me down and asked a bunch of questions which they furiously typed into a computer.&lt;/p&gt;

&lt;p&gt;A bit later they said I had &lt;a href="https://www.mayoclinic.org/diseases-conditions/bells-palsy/symptoms-causes/syc-20370028"&gt;Bell’s Palsy&lt;/a&gt; and invited me over to look at their laptop which had a program outlining the condition, it’s symptoms, causes and course of treatment. With that, I got the medicine and eyepatch and went about the next few weeks struggling to move half my face which made me realize why banning plastic straw is stupid.&lt;/p&gt;

&lt;p&gt;This episode made me realize that looking things up, particularly with Google, is just a tool. It has little effect on your competency as a professional, whether it is programming, medicine or whatever. Is it worth your time to know every single API call and function signature? What use is me memorizing the &lt;a href="https://www.a11yproject.com/posts/how-to-hide-content/"&gt;&lt;code&gt;visually-only&lt;/code&gt; class&lt;/a&gt; when I can just copy paste it from the &lt;a href="https://www.a11yproject.com/"&gt;a11y project&lt;/a&gt; when I need it?&lt;/p&gt;

&lt;p&gt;It can get annoying when acclaimed programmers sound like they’re just bumbling fools who crib onto Google to get their job done but that can be a strength, can’t it? Knowing how to save time through premade solutions that you can evaluate is a powerful skill.&lt;/p&gt;

&lt;p&gt;Given that, I think it would be better to focus less on people googling shit and more on making sure the stuff they Google is correct to begin with along with people being able to evaluate what they find.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The Internet contains the sum of all human knowledge at our fingertips, but I would like to hire people who don’t take advantage of this amazing resource” is a hell of a weird-ass hill to die on but you do you buddy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;—&lt;a href="https://mobile.twitter.com/jacobian/status/1464290645602758668"&gt;@jacobian&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/?tag=faraixyz00-20"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an Amazon affiliate),&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack="&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2b%2522Imagine%2bif%2bDoctors%2bRelied%2bon%2bGoogle%2bAs%2bMuch%2bAs%2bProgrammers%2bDo%2522"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Breadcrumbs In Hugo</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Tue, 05 Oct 2021 11:10:37 +0000</pubDate>
      <link>https://dev.to/faraixyz/breadcrumbs-in-hugo-303k</link>
      <guid>https://dev.to/faraixyz/breadcrumbs-in-hugo-303k</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/snippets/hugo-breadcrumbs/" rel="noopener noreferrer"&gt;Breadcrumbs In Hugo&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/" rel="noopener noreferrer"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Breadcrumbs are a type of navigation which shows pages in a particular order, like viewing history or, in my case, a page’s hierarchy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodelab.farai.xyz%2Fsnippets%2Fhugo-breadcrumbs%2Fbreadcrumb-ex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodelab.farai.xyz%2Fsnippets%2Fhugo-breadcrumbs%2Fbreadcrumb-ex.png" alt="Links to home, the old ones and v8 redesign with a right arrow between them"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Implementing this was frustrating, but I eventually figured it out. In short, you need to do something similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- In whatever template --&amp;gt;
&amp;lt;p class="breadcrumbs"&amp;gt;
    {{ partial "breadcrumbs.html" . }}
&amp;lt;/p&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Then in &lt;code&gt;breadcrumbs.html&lt;/code&gt;, include this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{ with .Parent }}
    {{ partial "breadcrumbs.html" . }}
    {{ if .Parent }}→{{ end }}
    &amp;lt;a href="{{ .Permalink }}"&amp;gt;{{ .Title }}&amp;lt;/a&amp;gt;
{{ end }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing is that you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;invoke the recursion by calling the breadcrumbs partial to the &lt;code&gt;.Parent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;provide the separator (given you have one) conditional to whether the current &lt;code&gt;.Parent&lt;/code&gt; has a parent and&lt;/li&gt;
&lt;li&gt;link to the current crumb.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;That’s it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can play with semantics based on what you need. Want to use &lt;code&gt;nav &amp;gt; ul&lt;/code&gt; instead of &lt;code&gt;p&lt;/code&gt; and make them list items so you can use &lt;a href="https://getbootstrap.com/docs/4.0/components/breadcrumb/" rel="noopener noreferrer"&gt;Bootstrap’s breadcrumbs&lt;/a&gt;? Go ahead.&lt;/p&gt;

&lt;p&gt;I spent far more time than I should have trying to solve this and this is what I ended up with. If you want the full story on how I got to this point, it’s a &lt;a href="https://www.patreon.com/posts/57024711/" rel="noopener noreferrer"&gt;Patreon Exclusive&lt;/a&gt;. Thanks to &lt;a href="https://discourse.gohugo.io/t/snippet-partial-for-creating-breadcrumbs-uses-bootstrap-4/15426/2" rel="noopener noreferrer"&gt;nfriedli for figuring this out!&lt;/a&gt;!&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/" rel="noopener noreferrer"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz" rel="noopener noreferrer"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz" rel="noopener noreferrer"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz" rel="noopener noreferrer"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya" rel="noopener noreferrer"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amazon.com/?tag=faraixyz00-20" rel="noopener noreferrer"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an Amazon affiliate),&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack=" rel="noopener noreferrer"&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab" rel="noopener noreferrer"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bBreadcrumbs%2bIn%2bHugo"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>hugo</category>
      <category>html</category>
    </item>
    <item>
      <title>Give Your Illustrations Dark Mode With This Simple Trick (SPOILER: It's a CSS Filter)</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Tue, 05 Oct 2021 10:37:49 +0000</pubDate>
      <link>https://dev.to/faraixyz/give-your-illustrations-dark-mode-with-this-simple-trick-spoiler-it-s-a-css-filter-5737</link>
      <guid>https://dev.to/faraixyz/give-your-illustrations-dark-mode-with-this-simple-trick-spoiler-it-s-a-css-filter-5737</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/posts/quick-dark-illustrations/" rel="noopener noreferrer"&gt;Give Your Illustrations Dark Mode With This Simple Trick (SPOILER: It's a CSS Filter)&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/" rel="noopener noreferrer"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;code&gt;filter: invert(100%);&lt;/code&gt;—that’s it!&lt;/p&gt;

&lt;p&gt;Ok fine, it won’t work &lt;del&gt;all&lt;/del&gt; most of the time (it’s terrible on actual photos) but it’s good for illustrations with simple color palettes, like xkcd comics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodelab.farai.xyz%2Fsnippets%2Fquick-dark-illustrations%2Fwisdom-of-the-ancients-comic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodelab.farai.xyz%2Fsnippets%2Fquick-dark-illustrations%2Fwisdom-of-the-ancients-comic.png" alt="Two copies of a simply drawn XKCD comic, one white on black the other black on white"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://xkcd.com/979/" rel="noopener noreferrer"&gt;Wisdom of The Ancients by xkcd&lt;/a&gt; &lt;a href="https://www.explainxkcd.com/wiki/index.php/979:_Wisdom_of_the_Ancients" rel="noopener noreferrer"&gt;Transcript&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;On my site, I put that CSS in a class &lt;code&gt;invert-hack&lt;/code&gt; which I place on any illustrations I want to flip to dark mode.&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/" rel="noopener noreferrer"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz" rel="noopener noreferrer"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz" rel="noopener noreferrer"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz" rel="noopener noreferrer"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya" rel="noopener noreferrer"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;del&gt;&lt;a href="https://amazon.com/?tag=faraixyz03-20" rel="noopener noreferrer"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an amazon affiliate)&lt;/del&gt;,&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack=" rel="noopener noreferrer"&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab" rel="noopener noreferrer"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bGive%2bYour%2bIllustrations%2bDark%2bMode%2bWith%2bThis%2bSimple%2bTrick%2b%2528SPOILER%253A%2bIt%2527s%2ba%2bCSS%2bFilter%2529"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>darkmode</category>
      <category>css</category>
    </item>
    <item>
      <title>Web Features That May Not Work As You’d Expect</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Fri, 23 Jul 2021 15:24:43 +0000</pubDate>
      <link>https://dev.to/faraixyz/web-features-that-may-not-work-as-you-d-expect-2f7f</link>
      <guid>https://dev.to/faraixyz/web-features-that-may-not-work-as-you-d-expect-2f7f</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/elsewhere/unexpected-web-features/"&gt;Web Features That May Not Work As You’d Expect&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;As the web gets more and more capable, developers are able to make richer online experiences. There are times, however, where some new web capabilities may not work as you would expect in the interest of usability, security and privacy.&lt;/p&gt;

&lt;p&gt;I have run into situations like this. Like lazy loading in HTML. It’s easy to drop that attribute onto an image element only to realize… it actually needs more than that to do its thing. We’ll get into that specific one in a moment as we look at a few other features that might not work exactly as you‘d expect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the first post I’ve written for an online web dev publication. I’m embarassed to say that it took 6 months to get it out, but here it is! Thanks to Geoff and Chris for helping me with this! I do hope to write more content for other publications throughout the rest of the year.&lt;/p&gt;

&lt;p&gt;Read &lt;a href="https://css-tricks.com/web-features-that-may-not-work-as-youd-expect/"&gt;Web Features That May Not Work As You’d Expect on CSS Tricks&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;del&gt;&lt;a href="https://amazon.com/?tag=faraixyz03-20"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an amazon affiliate)&lt;/del&gt;,&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack="&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bWeb%2bFeatures%2bThat%2bMay%2bNot%2bWork%2bAs%2bYou%25E2%2580%2599d%2bExpect"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>You Can Give A Website Dark Mode With Just One CSS Property</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Sun, 27 Jun 2021 10:02:51 +0000</pubDate>
      <link>https://dev.to/faraixyz/you-can-give-a-website-dark-mode-with-just-one-css-property-1dm2</link>
      <guid>https://dev.to/faraixyz/you-can-give-a-website-dark-mode-with-just-one-css-property-1dm2</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/posts/til/color-scheme/" rel="noopener noreferrer"&gt;You Can Give A Website Dark Mode With Just One CSS Property&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/" rel="noopener noreferrer"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I’m too lazy to do all the work required to make a proper dark mode for now so I’m trying to find a quick fix. I tried to use &lt;code&gt;filter: invert(100%)&lt;/code&gt; on the body but it would literally invert everything, including images and emojis. I was about to give up on it before I came across &lt;a href="https://blog.jim-nielsen.com/2021/css-system-colors/" rel="noopener noreferrer"&gt;Jim Nielsen’s post on the &lt;code&gt;color-scheme&lt;/code&gt; property&lt;/a&gt; which tells the browser what color schemes a site (or element) supports and changes the default color based on the user’s preferences. To use it, you just need to specify the &lt;code&gt;color-scheme&lt;/code&gt; property on the &lt;code&gt;:root&lt;/code&gt; element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:root {
    color-scheme: light dark;
}

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

&lt;/div&gt;



&lt;p&gt;This supports both light and dark mode. You can also just set &lt;code&gt;light&lt;/code&gt; or &lt;code&gt;dark&lt;/code&gt; as well as apply the &lt;code&gt;color-scheme&lt;/code&gt; property to a specific element. In some environments (like email), you can also apply a &lt;code&gt;&amp;lt;meta name="color-scheme"&amp;gt;&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;Note that it doesn’t work in Firefox yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues
&lt;/h2&gt;

&lt;p&gt;When I tried this the link colors didn’t change in Safari resulting in this ugly and inaccessible style. It worked perfectly fine in Chromium browsers however.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodelab.farai.xyz%2Fposts%2Ftil%2Fcolor-scheme%2Fdark-mode-header.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodelab.farai.xyz%2Fposts%2Ftil%2Fcolor-scheme%2Fdark-mode-header.png" alt="The site’s header with the logo and navigation links in full blue against a black background"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jim had the same issue. Because of that, I ended up implementing some sort of dark mode using Apple’s &lt;a href="https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/#dynamic-system-colors" rel="noopener noreferrer"&gt;dynamic system colors&lt;/a&gt;. The &lt;a href="https://www.w3.org/TR/css-color-4/#css-system-colors" rel="noopener noreferrer"&gt;CSS Colors Module 4&lt;/a&gt; has system colors corresponding to the OS’s UI but they don’t have good support so I just copy-pasted the RGB values. &lt;a href="https://www.tempertemper.net/blog/fixing-safaris-html-only-dark-mode-bug" rel="noopener noreferrer"&gt;Temper Temper explains how to “fix” dark mode on Safari&lt;/a&gt; better than I have.&lt;/p&gt;

&lt;p&gt;Also, looking at &lt;a href="https://www.w3.org/TR/css-color-adjust-1/" rel="noopener noreferrer"&gt;color scheme’s spec&lt;/a&gt;, there was this scary warning noting that they don’t guarantee a color palette.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The light and dark color schemes don’t represent an exact color palette (such as black-and-white), but a range of possible palettes. To guarantee specific colors, authors must specify those colors themselves.&lt;/strong&gt; Note also that, consequently, pairing default or  colors with author-specified colors cannot guarantee any particular contrast level; it might be necessary to set both foreground and background colors together to ensure legibility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Given those issues my attempt to implement dark mode lazily has become the start of an interesting journey. Still, it’s worth putting in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.dev/color-scheme/" rel="noopener noreferrer"&gt;Improved dark mode default styling with the &lt;code&gt;color-scheme&lt;/code&gt; CSS property and the corresponding meta tag on web.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webkit.org/blog/8840/dark-mode-support-in-webkit/" rel="noopener noreferrer"&gt;Dark Mode Support in WebKit on webkit.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/" rel="noopener noreferrer"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz" rel="noopener noreferrer"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz" rel="noopener noreferrer"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz" rel="noopener noreferrer"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya" rel="noopener noreferrer"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;del&gt;&lt;a href="https://amazon.com/?tag=faraixyz03-20" rel="noopener noreferrer"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an amazon affiliate)&lt;/del&gt;,&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack=" rel="noopener noreferrer"&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab" rel="noopener noreferrer"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bYou%2bCan%2bGive%2bA%2bWebsite%2bDark%2bMode%2bWith%2bJust%2bOne%2bCSS%2bProperty"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>darkmode</category>
      <category>css</category>
      <category>html</category>
    </item>
    <item>
      <title>Converting Video into Animated Images Using FFmpeg</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Fri, 11 Jun 2021 03:47:28 +0000</pubDate>
      <link>https://dev.to/faraixyz/converting-video-into-animated-images-using-ffmpeg-3cng</link>
      <guid>https://dev.to/faraixyz/converting-video-into-animated-images-using-ffmpeg-3cng</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/posts/snippets/ffmpeg-animated-images/"&gt;Converting Video into Animated Images Using FFmpeg&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;This post has been republished with new information.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;This post will supplement an upcoming post on why you should stop using GIFs in favor of newer image and video formats. Here’s how to generate animated images in various media formats using &lt;a href="https://ffmpeg.org/download.html"&gt;FFmpeg&lt;/a&gt;.&lt;/p&gt;


&lt;ul&gt;
    &lt;li&gt;Preparing The Source Clip For Further Conversion&lt;/li&gt;
    &lt;li&gt;
Images
      &lt;ul&gt;
        &lt;li&gt;GIF&lt;/li&gt;
        &lt;li&gt;WebP&lt;/li&gt;
        &lt;li&gt;Sequenced AVIF (Chrome For Now)&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
Videos
      &lt;ul&gt;
        &lt;li&gt;AVC/h.264 MP4 (widest support)&lt;/li&gt;
        &lt;li&gt;HEVC/h.265 (WebKit)&lt;/li&gt;
        &lt;li&gt;VP8/VP9 (Not WebKit)&lt;/li&gt;
        &lt;li&gt;
AV1 Video (Chrome and Firefox)
          &lt;ul&gt;
            &lt;li&gt;aomenc (Reference Encoder)&lt;/li&gt;
            &lt;li&gt;rav1e (Fastest)&lt;/li&gt;
            &lt;li&gt;SVT-AV1&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
  &lt;/ul&gt;

&lt;h2&gt;
  
  
  Preparing The Source Clip For Further Conversion
&lt;/h2&gt;

&lt;p&gt;First thing to do is convert it to an uncompressed &lt;code&gt;y4m&lt;/code&gt; video, slicing it up and setting the framerate as necessary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -ss &amp;lt;start_point&amp;gt; -t &amp;lt;duration_from_start&amp;gt; -i &amp;lt;source_media&amp;gt; -an -vf 'scale=&amp;lt;width&amp;gt;:&amp;lt;height&amp;gt;,setpts=&amp;lt;stretch_factor&amp;gt;*PTS,fps=&amp;lt;framerate&amp;gt;' -pix_fmt yuv420p &amp;lt;raw_input&amp;gt;.y4m

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

&lt;/div&gt;



&lt;p&gt;What the option flags mean:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-ss&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Marks the start position of the video stream as a &lt;a href="http://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax"&gt;time duration&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the duration of the datastream from &lt;code&gt;-ss&lt;/code&gt; (or 0) as a &lt;a href="http://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax"&gt;time duration&lt;/a&gt;. Use both &lt;code&gt;-ss&lt;/code&gt; and &lt;code&gt;-t&lt;/code&gt; before &lt;code&gt;-i&lt;/code&gt; to limit the video input.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-an&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes audio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-vf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The &lt;a href="https://ffmpeg.org/ffmpeg-filters.html#Video-Filters"&gt;video filters&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scale&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the &lt;strong&gt;w&lt;/strong&gt; idth and &lt;strong&gt;h&lt;/strong&gt; eight of the video&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setpts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the presentation timestamps (PTS) for the video. Used to &lt;a href="https://trac.ffmpeg.org/wiki/How%20to%20speed%20up%20/%20slow%20down%20a%20video"&gt;speed up and slow down video&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the framerate for the video.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pix_fmt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the color format. Necessary if you’re converting from GIFs.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note, if you are going to set a framerate for a GIF, it &lt;a href="https://superuser.com/a/1449370"&gt;has a delay between frames&lt;/a&gt; in hundreths of a second (fps=100/delay). So:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Delay&lt;/th&gt;
&lt;th&gt;Framerate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10pfs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;50fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;33fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;25fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;20fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;15fps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Images
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GIF
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;source_input&amp;gt;.y4m -filter_complex "[0:v] split [a][b];[a] palettegen [p];[b][p] paletteuse" -loop 0 &amp;lt;output&amp;gt;.gif

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

&lt;/div&gt;



&lt;p&gt;Simply put the &lt;code&gt;-filter_complex&lt;/code&gt; flag in this case generates a color palette to use in the GIF. See &lt;a href="https://engineering.giphy.com/how-to-make-gifs-with-ffmpeg/"&gt;GIPHY’s Engineering blog on how to make GIFs&lt;/a&gt; to explain the flag.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-loop 0&lt;/code&gt; makes it loop forever.&lt;/p&gt;

&lt;p&gt;You can leave it out, resulting in a much smaller GIF (at the expense of quality).&lt;/p&gt;

&lt;h3&gt;
  
  
  WebP
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -loop 0 -q:v 100 -compression_level 6 &amp;lt;output&amp;gt;.webp

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;q:v&lt;/code&gt; is the image quality, from 0 to 100. It’ll be much smaller, but WebP can get blocky if you push the quality too hard.&lt;/p&gt;

&lt;p&gt;Like GIF, &lt;code&gt;-loop 0&lt;/code&gt; makes it loop forever.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sequenced AVIF (Chrome For Now)
&lt;/h3&gt;

&lt;p&gt;ffmpeg doesn’t support writing to AVIF containers when I wrote this, so you nee to use &lt;a href="https://github.com/AOMediaCodec/libavif/releases"&gt;avifenc&lt;/a&gt; to do this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;avifenc &amp;lt;raw_input&amp;gt;.y4m &amp;lt;output&amp;gt;.avif

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Videos
&lt;/h2&gt;

&lt;p&gt;From here on out, I won’t go over the options too much since there’s a lot to consider, most of which I don’t understand so I’ll link to the respective encoding guide if you want more options.&lt;/p&gt;

&lt;h3&gt;
  
  
  AVC/h.264 MP4 (widest support)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -c:v libx264 -preset veryslow &amp;lt;output&amp;gt;.mp4

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

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://trac.ffmpeg.org/wiki/Encode/H.264#Preset"&gt;&lt;code&gt;preset&lt;/code&gt;&lt;/a&gt; flag tries to find the best tradeoff between quality and compression at a given bitrate and file size.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/H.264"&gt;H.264 Encoding Guide&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HEVC/h.265 (WebKit)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -c:v libx265 -preset veryslow -tag:v hvc1 &amp;lt;output&amp;gt;.mp4

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

&lt;/div&gt;



&lt;p&gt;You need the &lt;code&gt;-tag:v hvc1&lt;/code&gt; for the video to play in Safari. &lt;a href="https://aaron.cc/ffmpeg-hevc-apple-devices/"&gt;Thanks Aaron!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;preset&lt;/code&gt; is the same as in AVC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/H.265"&gt;H.265 Encoding Guide&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  VP8/VP9 (Not WebKit)
&lt;/h3&gt;

&lt;p&gt;Switch the &lt;code&gt;vp8&lt;/code&gt; for &lt;code&gt;vp9&lt;/code&gt; depending on which one you choose. &lt;code&gt;vp9&lt;/code&gt; is newer so better, although it doesn’t have the support of &lt;code&gt;vp8&lt;/code&gt; (although it’s reasonable).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -c:v vp9 &amp;lt;output&amp;gt;.webm

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/VP8"&gt;VP8 Encoding Guide&lt;/a&gt;/&lt;a href="https://trac.ffmpeg.org/wiki/Encode/VP9"&gt;VP9 Encoding Guide&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AV1 Video (Chrome and Firefox)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Update 21 May 2021:&lt;/strong&gt; When I initially wrote this post, my build of ffmpeg didn’t include different av1 encoders so I tried to encode AV1 videos using the encoders directly. As I was updating this post to add instructions on how them, I noticed that the alternatate encoders are now built in the standard build of ffmpeg.&lt;/p&gt;

&lt;p&gt;Encoding AV1 will use a lot of CPU and it takes longer than the others.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -c:v libaom-av1 &amp;lt;output&amp;gt;.webm

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

&lt;/div&gt;



&lt;p&gt;If you’re on an older version of ffmpeg, you need to add &lt;code&gt;-strict -2&lt;/code&gt;. Note that you can also use &lt;code&gt;rav1e&lt;/code&gt; and &lt;code&gt;SVT-AV1&lt;/code&gt; in FFmpeg to encode AV1 videos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/AV1"&gt;AV1 Encoding Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  aomenc (Reference Encoder)
&lt;/h4&gt;

&lt;p&gt;You’ll either have to &lt;a href="https://aomedia.googlesource.com/aom/+/master"&gt;compile aomenc yourself&lt;/a&gt; or you can use &lt;a href="https://ci.appveyor.com/project/marcomsousa/build-aom/build/artifacts"&gt;aomenc’s Windows builds&lt;/a&gt; by &lt;a href="https://github.com/marcomsousa"&gt;Marco Sousa&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aomenc.exe -o &amp;lt;output_file&amp;gt;.webm &amp;lt;raw_input&amp;gt;.y4m

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  rav1e (Fastest)
&lt;/h4&gt;

&lt;p&gt;You can find &lt;a href="https://github.com/xiph/rav1e/releases"&gt;rav1e’s builds on GitHub&lt;/a&gt;. Note that rav1e only generates the raw video stream (saved as an ivf file) which needs to be muxed into a webm container file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rav1e.exe &amp;lt;raw_input&amp;gt;.y4m -o &amp;lt;intermediate&amp;gt;.ivf
ffmpeg -i &amp;lt;intermediate&amp;gt;.ivf-c:v copy &amp;lt;output&amp;gt;.webm -hide_banner -loglevel error

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  SVT-AV1
&lt;/h4&gt;

&lt;p&gt;While there are some &lt;a href="https://github.com/AOMediaCodec/SVT-AV1/releases"&gt;SVT-AV1 builds on GitHub&lt;/a&gt;, the project is marked as archived and &lt;a href="https://gitlab.com/AOMediaCodec/SVT-AV1"&gt;SVT-AV1’s Gitlab Repo&lt;/a&gt; doesn’t have any prebuilt binaries so you’ll have to compile it yourself. However you get the binary, like rav1e, you need to mux the raw video stream into a webm container file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SvtAv1EncApp.exe -b &amp;lt;intermediate&amp;gt;.ivf -i &amp;lt;raw_input&amp;gt;.y4m
ffmpeg -i $destIvf -c:v copy &amp;lt;output&amp;gt;.webm

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

&lt;/div&gt;






&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;del&gt;&lt;a href="https://amazon.com/?tag=faraixyz03-20"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an amazon affiliate)&lt;/del&gt;,&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack="&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bConverting%2bVideo%2binto%2bAnimated%2bImages%2bUsing%2bFFmpeg"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>images</category>
      <category>avif</category>
      <category>av1</category>
      <category>webp</category>
    </item>
    <item>
      <title>Converting Video into Animated Images (and Other Videos) With FFmpeg (For The Most Part)</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Thu, 15 Apr 2021 17:07:31 +0000</pubDate>
      <link>https://dev.to/faraixyz/converting-video-into-animated-images-and-other-videos-with-ffmpeg-for-the-most-part-3da7</link>
      <guid>https://dev.to/faraixyz/converting-video-into-animated-images-and-other-videos-with-ffmpeg-for-the-most-part-3da7</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/snippets/ffmpeg-animated-images/"&gt;Converting Video into Animated Images (and Other Videos) With FFmpeg (For The Most Part)&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;This post will supplement an upcoming post on why you should stop using GIFs in favor of newer image and video formats. Here’s how to generate animated images in various media formats using &lt;a href="https://ffmpeg.org/download.html"&gt;FFMpeg&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;


&lt;ul&gt;
    &lt;li&gt;Preparing The Source Clip For Further Conversion&lt;/li&gt;
    &lt;li&gt;
Images
      &lt;ul&gt;
        &lt;li&gt;GIF&lt;/li&gt;
        &lt;li&gt;WebP&lt;/li&gt;
        &lt;li&gt;Sequenced AVIF (Chrome For Now)&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;
Videos
      &lt;ul&gt;
        &lt;li&gt;AVC/h.264 MP4 (widest support)&lt;/li&gt;
        &lt;li&gt;HEVC/h.265 (WebKit)&lt;/li&gt;
        &lt;li&gt;VP8/VP9 (Android)&lt;/li&gt;
        &lt;li&gt;AV1 Video (Chrome and Firefox)&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
  &lt;/ul&gt;

&lt;h2&gt;
  
  
  Preparing The Source Clip For Further Conversion
&lt;/h2&gt;

&lt;p&gt;First thing to do is convert it to an uncompressed &lt;code&gt;y4m&lt;/code&gt; video, slicing it up and setting the framerate as necessary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -ss &amp;lt;start_point&amp;gt; -t &amp;lt;duration_from_start&amp;gt; -i &amp;lt;source_media&amp;gt; -an -vf 'scale=&amp;lt;width&amp;gt;:&amp;lt;height&amp;gt;,setpts=&amp;lt;stretch_factor&amp;gt;*PTS,fps=&amp;lt;framerate&amp;gt;' -pix_fmt yuv420p &amp;lt;raw_input&amp;gt;.y4m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What the option flags mean:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-ss&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Marks the start position of the video stream as a &lt;a href="http://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax"&gt;time duration&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the duration of the datastream from &lt;code&gt;-ss&lt;/code&gt; (or 0) as a &lt;a href="http://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax"&gt;time duration&lt;/a&gt;. Use both &lt;code&gt;-ss&lt;/code&gt; and &lt;code&gt;-t&lt;/code&gt; before &lt;code&gt;-i&lt;/code&gt; to limit the video input.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-an&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes audio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-vf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The &lt;a href="https://ffmpeg.org/ffmpeg-filters.html#Video-Filters"&gt;video filters&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scale&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the &lt;strong&gt;w&lt;/strong&gt; idth and &lt;strong&gt;h&lt;/strong&gt; eight of the video&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setpts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the presentation timestamps (PTS) for the video. Used to &lt;a href="https://trac.ffmpeg.org/wiki/How%20to%20speed%20up%20/%20slow%20down%20a%20video"&gt;speed up and slow down video&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifies the framerate for the video.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pix_fmt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the color format. Not necessary and the only reason I specified it is because I had issues in an earlier draft&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note, if you are going to set a framerate for a GIF, it &lt;a href="https://superuser.com/a/1449370"&gt;has a delay between frames&lt;/a&gt; in hundreths of a second (fps=100/delay). So:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Delay&lt;/th&gt;
&lt;th&gt;Framerate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10pfs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;50fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;33fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;25fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;20fps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;15fps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Images
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GIF
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;source_input&amp;gt;.y4m -filter_complex "[0:v] split [a][b];[a] palettegen [p];[b][p] paletteuse" -loop 0 &amp;lt;output&amp;gt;.gif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply put the &lt;code&gt;-filter_complex&lt;/code&gt; flag in this case generates a color palette to use in the GIF. See &lt;a href="https://engineering.giphy.com/how-to-make-gifs-with-ffmpeg/"&gt;GIPHY’s Engineering blog on how to make GIFs&lt;/a&gt; to explain the flag.&lt;/p&gt;

&lt;p&gt;You can leave it out, resulting in a much smaller GIF (at the expense of quality).&lt;/p&gt;

&lt;h3&gt;
  
  
  WebP
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -loop 0 -q:v 100 -compression_level 6 &amp;lt;output&amp;gt;.webp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;q:v&lt;/code&gt; is the image quality, from 0 to 100. It’ll be much smaller, but WebP can get blocky if you push the quality too hard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sequenced AVIF (Chrome For Now)
&lt;/h3&gt;

&lt;p&gt;ffmpeg doesn’t support writing to AVIF containers when I wrote this, so you nee to use &lt;a href="https://github.com/AOMediaCodec/libavif/releases"&gt;avifenc&lt;/a&gt; to do this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;avifenc &amp;lt;raw_input&amp;gt;.y4m &amp;lt;output&amp;gt;.avif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Videos
&lt;/h2&gt;

&lt;p&gt;From here on out, I won’t go over the options too much since there’s a lot to consider, most of which I don’t understand so I’ll link to the respective encoding guide if you want more options.&lt;/p&gt;

&lt;h3&gt;
  
  
  AVC/h.264 MP4 (widest support)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input.y4m -c:v libx264 -preset veryslow .&amp;lt;output&amp;gt;.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://trac.ffmpeg.org/wiki/Encode/H.264#Preset"&gt;&lt;code&gt;preset&lt;/code&gt;&lt;/a&gt; flag tries to find the best tradeoff between quality and compression at a given bitrate and file size.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/H.264"&gt;H.264 Encoding Guide&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HEVC/h.265 (WebKit)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -c:v libx265 -preset veryslow -tag:v hvc1 &amp;lt;output&amp;gt;.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need the &lt;code&gt;-tag:v hvc1&lt;/code&gt; for the video to play in Safari. &lt;a href="https://aaron.cc/ffmpeg-hevc-apple-devices/"&gt;Thanks Aaron!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;preset&lt;/code&gt; is the same as in AVC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/H.265"&gt;H.265 Encoding Guide&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  VP8/VP9 (Android)
&lt;/h3&gt;

&lt;p&gt;Switch the &lt;code&gt;vp8&lt;/code&gt; for &lt;code&gt;vp9&lt;/code&gt; depending on which one you choose. &lt;code&gt;vp9&lt;/code&gt; is newer so better, although it doesn’t have the support of &lt;code&gt;vp8&lt;/code&gt; (although it’s reasonable).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -c:v vp8 &amp;lt;output&amp;gt;.webm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/VP8"&gt;VP8 Encoding Guide&lt;/a&gt;/&lt;a href="https://trac.ffmpeg.org/wiki/Encode/VP9"&gt;VP9 Encoding Guide&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AV1 Video (Chrome and Firefox)
&lt;/h3&gt;

&lt;p&gt;Encoding AV1 will use a lot of CPU and it takes a very long time; more so on my shitty laptop encoding at 0.1fps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i &amp;lt;raw_input&amp;gt;.y4m -strict -2 -c:v libaom-av1 .&amp;lt;raw_input&amp;gt;.webm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://trac.ffmpeg.org/wiki/Encode/AV1"&gt;AV1 Encoding Guide&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;del&gt;&lt;a href="https://amazon.com/?tag=faraixyz03-20"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an amazon affiliate)&lt;/del&gt;,&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack="&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also &lt;a href="https://buttondown.email/faraiscodelab"&gt;subscribe to my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have feedback? Send an email to &lt;a href="//mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bConverting%2bVideo%2binto%2bAnimated%2bImages%2b%2528and%2bOther%2bVideos%2529%2bWith%2bFFmpeg%2b%2528For%2bThe%2bMost%2bPart%2529"&gt;gandiyafarai+feedback at gmail dot com&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Now Have A Newsletter; See The First Email</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Sun, 11 Apr 2021 19:01:21 +0000</pubDate>
      <link>https://dev.to/faraixyz/i-now-have-a-newsletter-see-the-first-email-3l1e</link>
      <guid>https://dev.to/faraixyz/i-now-have-a-newsletter-see-the-first-email-3l1e</guid>
      <description>&lt;p&gt;After hesitating a lot on making a newsletter, I’m pleased to introduce the &lt;a href="https://buttondown.email/faraiscodelab"&gt;Farai’s Codelab Newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Read the first edition in which &lt;a href="https://buttondown.email/faraiscodelab/archive/my-very-first-newsletter-featuring-intros-and-wips/"&gt;I introduce the myself, newsletter, my current work and future plans&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://buttondown.email/faraiscodelab/archive/"&gt;newsletter is availible online&lt;/a&gt; as well as an &lt;a href="https://buttondown.email/faraiscodelab/rss"&gt;RSS feed of the emails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Only thing left is to add a fancy subscribe box for the site and to keep it running. My measure of success is when I have to pay for it. Hope to get to that point!&lt;/p&gt;

&lt;p&gt;plz subscribe, kthanxbai!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I Optimize PNGs</title>
      <dc:creator>Farai Gandiya</dc:creator>
      <pubDate>Tue, 30 Mar 2021 20:43:16 +0000</pubDate>
      <link>https://dev.to/faraixyz/how-i-optimize-pngs-1e5f</link>
      <guid>https://dev.to/faraixyz/how-i-optimize-pngs-1e5f</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://codelab.farai.xyz/scribbles/optimizing-pngs/"&gt;How I Optimize PNGs&lt;/a&gt; was first published on &lt;a href="https://codelab.farai.xyz/"&gt;Farai's Codelab&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Here’s how I optimize images in three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Resize the image using &lt;a href="https://imagemagick.org/index.php"&gt;ImageMagick&lt;/a&gt;&lt;/strong&gt; to the desired sizes. The size I usually convert to is a 240px width image for small screen devices like &lt;a href="https://en.wikipedia.org/wiki/Feature_phone"&gt;feature phones&lt;/a&gt; that fit the media query of &lt;code&gt;(max-width: 400px) and (-webkit-device-pixel-ratio: 1)&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;If it’s a non-photogenic image inside a JPEG, I convert the image sizes to PNG using it.&lt;/li&gt;
&lt;li&gt;If I’m converting an SVG, I use &lt;a href="https://inkscape.org/"&gt;Inkscape&lt;/a&gt; (specifically &lt;a href="https://wiki.inkscape.org/wiki/index.php/Using_the_Command_Line"&gt;inkscape-cli&lt;/a&gt;) since it’s very good at rendering SVGs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;a href="https://compresspng.com"&gt;CompressPNG.com&lt;/a&gt; to restrict the color palette&lt;/strong&gt; as much as I can using a slider. This makes a massive difference in file sizes.&lt;/li&gt;
&lt;li&gt;Finally, I then &lt;strong&gt;use &lt;a href="https://github.com/google/zopfli/blob/master/README.zopflipng"&gt;ZopfliPNG&lt;/a&gt; to recompress the PNG&lt;/strong&gt; for a slight size reduction. PNGs use some sort of DEFLATE compression algorithm to compress all the image data—Zopfli is a &lt;q&gt;very good, but slow&lt;/q&gt; implementation of DEFLATE. It’s a ~7% reduction which is just a handful of kilobytes.&lt;/li&gt;
&lt;li&gt;Depending on the file size reduction and quality, I might also &lt;strong&gt;convert it to WebP or AVIF&lt;/strong&gt;. This isn’t as common since PNGs ae really good at non photographic images.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process is based on my naive understanding of how PNGs work. I want to make a comprehensive post on how PNGs work and on how to use that understanding to better compress PNGs. There’s a lot about the compression techniques, color indexing, sampling and the like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Glossary
&lt;/h2&gt;

&lt;p&gt;non-photographic image—not a photo like illustrations, graphics and diagrams.&lt;/p&gt;




&lt;p&gt;Thanks for reading! If you liked this post, consider &lt;a href="https://codelab.farai.xyz/support/"&gt;supporting my work&lt;/a&gt; by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sharing my work,&lt;/li&gt;
&lt;li&gt;refering me for a job (or hire me for freelance work),&lt;/li&gt;
&lt;li&gt;sponsoring me on &lt;a href="https://patreon.com/faraixyz"&gt;Patreon&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.buymeacoffee.com/faraixyz"&gt;buying Me A Coffee&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ko-fi.com/faraixyz"&gt;buying Me A Ko-Fi&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://paypal.me/fgandiya"&gt;sending me a tip on Paypal&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;del&gt;&lt;a href="https://amazon.com/?tag=faraixyz03-20"&gt;buy something on Amazon with my affiliate link&lt;/a&gt; (I’ll earn a commision on this as an amazon affiliate)&lt;/del&gt;,&lt;/li&gt;
&lt;li&gt;or &lt;a href="https://shareasale.com/r.cfm?b=467188&amp;amp;u=2110247&amp;amp;m=46483&amp;amp;urllink=www%2Enamecheap%2Ecom%2F&amp;amp;afftrack="&gt;buy a domain on Namecheap with my affiliate link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
