<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>cjwainwright.co.uk</title><link>https://cjwainwright.co.uk</link><description>Comics, Web Development, Maths and Physics, Games and more...</description><item><title>Hair</title><pubDate>Sat, 19 Dec 2020 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/comics/series/rnd/31/index.html</link><description>&lt;span data-feed-id=&quot;comics/rnd31&quot; data-feed-title=&quot;Hair&quot; data-feed-date=&quot;2020-12-19&quot;&gt;&lt;img src=&quot;https://cjwainwright.co.uk/comics/series/rnd/31/hair.jpg&quot; width=&quot;1000&quot; height=&quot;1000&quot; alt=&quot;&quot; title=&quot;&quot; data-panels=&quot;0,0,497,480;483,0,516,480;0,470,497,529;483,470,516,529&quot;&gt;&lt;/span&gt;</description></item><item><title>When God closes a door</title><pubDate>Sun, 09 Aug 2020 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/comics/series/rnd/30/index.html</link><description>&lt;span data-feed-id=&quot;comics/rnd30&quot; data-feed-title=&quot;When God closes a door&quot; data-feed-date=&quot;2020-08-09&quot;&gt;&lt;img src=&quot;https://cjwainwright.co.uk/comics/series/rnd/30/godclosesadoor.jpg&quot; width=&quot;1000&quot; height=&quot;2700&quot; alt=&quot;&quot; title=&quot;&quot; data-panels=&quot;0,0,999,947;0,202,487,745;477,341,522,248;477,576,522,371;0,932,406,440;392,932,607,440;0,1356,999,94;0,1436,428,504;417,1436,582,504;0,1926,999,96;0,2011,999,689&quot;&gt;&lt;/span&gt;</description></item><item><title>Friendship</title><pubDate>Sat, 11 Jul 2020 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/comics/series/rnd/29/index.html</link><description>&lt;span data-feed-id=&quot;comics/rnd29&quot; data-feed-title=&quot;Friendship&quot; data-feed-date=&quot;2020-07-11&quot;&gt;&lt;img src=&quot;https://cjwainwright.co.uk/comics/series/rnd/29/pigeon_comic.jpg&quot; width=&quot;1200&quot; height=&quot;1200&quot; alt=&quot;&quot; title=&quot;&quot; data-panels=&quot;0,0,606,598;594,0,606,598;0,587,606,602;594,587,606,613&quot;&gt;&lt;/span&gt;</description></item><item><title>Pooh and Friends</title><pubDate>Fri, 05 Oct 2018 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/sketchbook/poohandfriends/index.html</link><description>&lt;div data-feed-id=&quot;poohandfriends&quot; data-feed-title=&quot;Pooh and Friends&quot; data-feed-date=&quot;05 Oct 2018&quot;&gt;
    &lt;p&gt;
        What would Winnie the Pooh and Friends look like if they were real animals. Well, this is not fully realistic
        but you get the idea, Pooh is pretty intense!
    &lt;/p&gt;
    &lt;div class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/poohandfriends/poohandfriends.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Pine Cone</title><pubDate>Sat, 29 Sep 2018 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/sketchbook/pinecone/index.html</link><description>&lt;div data-feed-id=&quot;pineconedrawing&quot; data-feed-title=&quot;Pine Cone&quot; data-feed-date=&quot;29 Sep 2018&quot;&gt;
    &lt;p&gt;
        A sketch of a pine cone, done as an exercise in patience.
    &lt;/p&gt;
    &lt;div class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/pinecone/pinecone.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Bee</title><pubDate>Sun, 20 May 2018 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/sketchbook/bee/index.html</link><description>&lt;div data-feed-id=&quot;beedrawing&quot; data-feed-title=&quot;Bee&quot; data-feed-date=&quot;20 May 2018&quot;&gt;
    &lt;p&gt;
        Trying out a mechanical pencil for drawing, it&apos;s good for details. Here&apos;s a drawing I did of a bee, from a photo
        I took of a bee!
    &lt;/p&gt;
    &lt;div class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/bee/bee.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Star Wars</title><pubDate>Sat, 30 Dec 2017 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/sketchbook/starwars/index.html</link><description>&lt;div data-feed-id=&quot;Star Wars&quot; data-feed-title=&quot;Star Wars&quot; data-feed-date=&quot;30 Dec 2017&quot;&gt;
    &lt;p&gt;
        Trying to get back into some drawing after a little while, here&apos;s some sketches of Star Wars characters!
    &lt;/p&gt;
    &lt;br&gt;
    &lt;p class=&quot;center&quot;&gt;
        Luke and Leia
    &lt;/p&gt;
    &lt;p class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/starwars/lukeandleia.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/p&gt;
    &lt;br&gt;
    &lt;p class=&quot;center&quot;&gt;
        Rey
    &lt;/p&gt;
    &lt;p class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/starwars/rey.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/p&gt;
    &lt;br&gt;
    &lt;p class=&quot;center&quot;&gt;
        Kylo Ren
    &lt;/p&gt;
    &lt;p class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/starwars/kyloren.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/p&gt;
    &lt;br&gt;
    &lt;p class=&quot;center&quot;&gt;
        Rose and Finn
    &lt;/p&gt;
    &lt;p class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/starwars/roseandfinn.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/p&gt;
    &lt;br&gt;
&lt;/div&gt;</description></item><item><title>Caching single page applications</title><pubDate>Thu, 08 Sep 2016 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/webdev/cachingspa/index.html</link><description>&lt;div data-feed-id=&quot;CachingSpa&quot; data-feed-title=&quot;Caching single page applications&quot; data-feed-date=&quot;8 Sep 2016&quot;&gt;
&lt;p&gt;
    One of the key features of single page applications (SPAs) is that they serve the exact same html page to the browser irrespective of the URL you visit.
    This html defines the framework of the app, I&apos;ll refer to it as the app html.
    In the following example we analyse how caching of the app html would behave in a typical SPA, and then we look at what we can do to improve it.
&lt;/p&gt;
&lt;p&gt;
    Imagine that this week&apos;s fad is a website which allows you to watch videos of certain pets.
    Let us also assume that this website has been written as a SPA.
&lt;/p&gt;
&lt;p&gt;    
    An email shows up in my inbox:
&lt;/p&gt;
&lt;div class=&quot;center&quot;&gt;
&lt;img src=&quot;https://cjwainwright.co.uk/webdev/cachingspa/images/email.png&quot; width=&quot;640px&quot; height=&quot;640px&quot; alt=&quot;Hi, Check out tiddles: http://example.com/cats/tiddles  x&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
    Of course I follow the link, and my cache being empty for this site I download the app html and all the resources linked from it.
&lt;/p&gt;
&lt;p&gt;
    Let&apos;s ignore the extra resources the app html requires as these can be versioned and cached outright at a fixed URL, they&apos;re not really an issue for subsequent visits.
    Our simplified situation looks like this.
&lt;/p&gt;
&lt;div class=&quot;center&quot;&gt;
&lt;img src=&quot;https://cjwainwright.co.uk/webdev/cachingspa/images/cache1.png&quot; width=&quot;640px&quot; height=&quot;640px&quot; alt=&quot;1. Check cache for http://example.com/cats/tiddles - Cache empty 2. Download from server 3. Add to cache 4. Return to client&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
    Now if I revisit that same URL, my browser can serve the app html directly from the cache, with possibly just a revalidaton request and 304 not modified response from the server, assuming the appropriate caching headers were set. However...
&lt;/p&gt;
&lt;p&gt;
    Later in the day I see a tweet:
&lt;/p&gt;
&lt;div class=&quot;center&quot;&gt;
&lt;img src=&quot;https://cjwainwright.co.uk/webdev/cachingspa/images/tweet.png&quot; width=&quot;640px&quot; height=&quot;640px&quot; alt=&quot;Rover beats other dogs with this one weird trick. http://example.com/dogs/rover&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
    I follow the clickbait.
    Now I&apos;ve never been to this URL before, so there will be nothing in the cache and my browser will call off to the server and once again download the app html.
&lt;/p&gt;
&lt;div class=&quot;center&quot;&gt;
&lt;img src=&quot;https://cjwainwright.co.uk/webdev/cachingspa/images/cache2.png&quot; width=&quot;640px&quot; height=&quot;640px&quot; alt=&quot;1. Check cache for http://example.com/dogs/rover - No match 2. Download from server 3. Add to cache 4. Return to client&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
    In fact every time I visit some url in the SPA that I&apos;ve not been to before, assuming I&apos;ve not navigated from within the control of the SPA itself, the browser re-downloads the app html and caches it separately.
    Can&apos;t we save those extra bytes and milliseconds by not downloading it again? 
&lt;/p&gt;
&lt;h2&gt;Not the solution you&apos;re looking for&lt;/h2&gt;
&lt;p&gt;
    We could go back to doing our SPA URLs the oldschool way, so rather than having clean URLs to identify the state/position in the application, like
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;http://example.com/cats/tiddles&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    we could use URL fragments like
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;http://example.com/#!/cats/tiddles&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    This way there&apos;s only one URL as far as the server is concerned as the fragment is not sent to the server. 
    As such we only download the app html on the first visit to our app, subsequent visits to any state in our app, for example to check out Rover, will be 304 not modified responses.
&lt;/p&gt;
&lt;p&gt;
    &quot;But I can&apos;t give up my clean URLs&quot; I hear you cry.
    So how can we get the same caching behaviour, but still keep our clean URLs?
&lt;/p&gt;
&lt;h2&gt;Use a service worker&lt;/h2&gt;
&lt;p&gt;
    A &lt;a href=&quot;https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API&quot; class=&quot;external&quot;&gt;service worker&lt;/a&gt; allows us to have full programmatic control over the network requests and responses as well as caching.
    So, using a service worker we can ensure that each of our requests to different urls serves the same app html from the cache, even if we&apos;ve never been to that specific URL before.
&lt;/p&gt;
&lt;p&gt;
    So, in our app html we register the service worker.
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;navigator.serviceWorker.register(&apos;/sw.js&apos;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    Before you go any further make sure you use the correct caching headers for the service worker itself - it will always be requested, so we want a 304 not modified response whenever it hasn&apos;t changed.
&lt;/p&gt;
&lt;p&gt;
    Now, inside the service worker we need to take control of our cache. On install let&apos;s cache our app html.
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;self.addEventListener(&apos;install&apos;, event =&amp;gt; {
    var installed = caches.open(&apos;cache-v1&apos;).then(cache =&amp;gt; cache.addAll([&apos;/&apos;]));
    event.waitUntil(installed);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    Whenever a network request is made it is handled by the service worker, and so we can check to see if it is for a URL that requires the app html as a response.
    I&apos;ve hidden the logic of this URL check away inside a function &lt;code class=&quot;language-js&quot;&gt;isPageRequest&lt;/code&gt;, as this logic is specific to your application&apos;s URL routing structure.
    If it is a request for the app html, let&apos;s mock up a request that will match the app html that is stored in the cache.
    Using this request we retrieve the response from the cache and send it back to the browser, no need to even go to the network.
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;self.addEventListener(&apos;fetch&apos;, event =&amp;gt; {
    var request = event.request;
    if(isPageRequest(request)) {
        request = new Request(&apos;/&apos;);
    }

    var response = caches.match(request).then(resp =&amp;gt; resp || fetch(request));
    event.respondWith(response);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    Now, every page request, whether it&apos;s for &lt;code class=&quot;language-http&quot;&gt;/cats/tiddles&lt;/code&gt;, &lt;code class=&quot;language-http&quot;&gt;/dogs/rover&lt;/code&gt;, or whatever, they all get redirected to a request for &lt;code class=&quot;language-http&quot;&gt;/&lt;/code&gt;.
    As such they can all share the same cache response, even if you&apos;ve never been to that specific URL before.
&lt;/p&gt;
&lt;/div&gt;</description></item><item><title>Adult, Single</title><pubDate>Sat, 13 Feb 2016 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/comics/series/rnd/28/index.html</link><description>&lt;span data-feed-id=&quot;comics/rnd28&quot; data-feed-title=&quot;Adult, Single&quot; data-feed-date=&quot;2016-02-13&quot;&gt;&lt;img src=&quot;https://cjwainwright.co.uk/comics/series/rnd/28/single.jpg&quot; width=&quot;720&quot; height=&quot;2096&quot; alt=&quot;&quot; title=&quot;&quot; data-panels=&quot;10,7,703,717;10,713,396,353;396,713,317,353;10,1056,703,595;10,1641,273,428;272,1641,441,446&quot;&gt;&lt;/span&gt;</description></item><item><title>Dinnertime</title><pubDate>Sun, 25 Oct 2015 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/comics/series/rnd/27/index.html</link><description>&lt;span data-feed-id=&quot;comics/rnd27&quot; data-feed-title=&quot;Dinnertime&quot; data-feed-date=&quot;2015-10-25&quot;&gt;&lt;img src=&quot;https://cjwainwright.co.uk/comics/series/rnd/27/worms.jpg&quot; width=&quot;800&quot; height=&quot;2133&quot; alt=&quot;&quot; title=&quot;&quot; data-panels=&quot;15,13,427,369;430,13,356,369;15,368,771,593;15,947,393,343;395,947,391,343;15,1275,771,373;15,1634,771,491&quot;&gt;&lt;/span&gt;</description></item><item><title>Famous Faces - Part III</title><pubDate>Thu, 27 Aug 2015 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/sketchbook/famousfaces3/index.html</link><description>&lt;div data-feed-id=&quot;Famous Faces 3&quot; data-feed-title=&quot;Famous Faces - Part III&quot; data-feed-date=&quot;27 Aug 2015&quot;&gt;
    &lt;p&gt;
        This is the third part in my on-going attempts at capturing a likeness.
        Parts &lt;a href=&quot;https://cjwainwright.co.uk/sketchbook/famousfaces/&quot;&gt;one&lt;/a&gt; and &lt;a href=&quot;https://cjwainwright.co.uk/sketchbook/famousfaces2/&quot;&gt;two&lt;/a&gt; were in pencil,
        this time I decided to digitally paint them.
        I thought I&apos;d try make them a little harder, too.
        I think these people are either a little less distinctive or a little less well known.
        Also, no clues at all this time!
    &lt;/p&gt;
    &lt;p&gt;
        So, can you tell who the following three famous faces are?
    &lt;/p&gt;
    &lt;p class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/famousfaces3/famous_face_1.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/p&gt;
    &lt;br&gt;
    &lt;p class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/famousfaces3/famous_face_2.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/p&gt;
    &lt;br&gt;
    &lt;p class=&quot;center&quot;&gt;
        &lt;img src=&quot;https://cjwainwright.co.uk/sketchbook/famousfaces3/famous_face_3.jpg&quot; alt=&quot;&quot;&gt;
    &lt;/p&gt;
    &lt;br&gt;
&lt;/div&gt;</description></item><item><title>Mosquito</title><pubDate>Sun, 09 Aug 2015 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/comics/series/rnd/26/index.html</link><description>&lt;span data-feed-id=&quot;comics/rnd26&quot; data-feed-title=&quot;Mosquito&quot; data-feed-date=&quot;2015-08-09&quot;&gt;&lt;img src=&quot;https://cjwainwright.co.uk/comics/series/rnd/26/mosquito.png&quot; width=&quot;900&quot; height=&quot;910&quot; alt=&quot;&quot; title=&quot;&quot; data-panels=&quot;0,0,231,231;219,0,237,231;445,0,234,231;669,0,231,231;0,221,231,233;219,221,237,233;445,221,234,233;669,221,231,233;0,444,231,235;219,444,236,235;445,444,234,235;669,444,231,235;0,669,231,230;219,669,236,230;445,669,234,230;669,669,231,241&quot;&gt;&lt;/span&gt;</description></item><item><title>Tweet Tweet</title><pubDate>Wed, 29 Jul 2015 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/comics/series/rnd/25/index.html</link><description>&lt;span data-feed-id=&quot;comics/rnd25&quot; data-feed-title=&quot;Tweet Tweet&quot; data-feed-date=&quot;2015-07-29&quot;&gt;&lt;img src=&quot;https://cjwainwright.co.uk/comics/series/rnd/25/tweet.jpg&quot; width=&quot;870&quot; height=&quot;1600&quot; alt=&quot;&quot; title=&quot;&quot; data-panels=&quot;12,10,369,334;369,10,488,334;12,331,280,311;279,331,289,311;556,331,301,311;12,628,280,324;279,628,578,324;12,939,455,331;455,939,402,331;12,1257,318,332;318,1257,539,343&quot;&gt;&lt;/span&gt;</description></item><item><title>How to remember the flexbox alignment properties</title><pubDate>Tue, 16 Jun 2015 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/webdev/flexboxalignment/index.html</link><description>&lt;div data-feed-id=&quot;FlexBoxAlignment&quot; data-feed-title=&quot;How to remember the flexbox alignment properties&quot; data-feed-date=&quot;16 Jun 2015&quot;&gt;
&lt;p&gt;
    If you&apos;ve used &lt;a href=&quot;http://www.w3.org/TR/css-flexbox-1/&quot; class=&quot;external&quot;&gt;flexbox&lt;/a&gt;,
    the powerful layout mechanism in CSS, you may have found yourself occasionally mixed up trying to remember the correct property names, I know I have.
    In particular, the properties pertaining to alignment and distribution –
    &lt;code class=&quot;language-css&quot;&gt;justify-content&lt;/code&gt;, &lt;code class=&quot;language-css&quot;&gt;align-items&lt;/code&gt; and &lt;code class=&quot;language-css&quot;&gt;align-content&lt;/code&gt; – 
    always caused me some trouble. 
    I&apos;ll explain why I found them confusing, and hopefully this will help you to remember them correctly too.
&lt;/p&gt;
&lt;h2&gt;The garden path&lt;/h2&gt;
&lt;p&gt;
    Let&apos;s first look at a couple of dictionary definitions you are probably familiar with:
&lt;/p&gt;
&lt;dl&gt;
    &lt;dt&gt;&lt;dfn&gt;justify&lt;/dfn&gt;:&lt;/dt&gt;
    &lt;dd&gt;Adjust (a line of type or piece of text) so that the print fills a space evenly or forms a straight edge at the margin&lt;/dd&gt;
    &lt;dt&gt;&lt;dfn&gt;align&lt;/dfn&gt;:&lt;/dt&gt;
    &lt;dd&gt;Place or arrange (things) in a straight line&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
    It&apos;s natural to try and apply these definitions to understand the meaning of the flexbox properties.
    But this will lead you up the garden path – it looks good to start with but then suddenly stops making sense.
    Let&apos;s have a look at the three properties I mentioned above to see how this happens.
&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;justify-content&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;
    Here&apos;s what the specification has to say about this property:
&lt;/p&gt;
&lt;blockquote class=&quot;fancyquote&quot;&gt;
    The justify-content property aligns flex items along the main axis of the current line of the flex container. … 
    Typically it helps distribute extra free space leftover when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size.
&lt;/blockquote&gt;
&lt;div class=&quot;center&quot;&gt;
    &lt;img src=&quot;https://cjwainwright.co.uk/webdev/flexboxalignment/images/justify-content.png&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
    This seems to fit with the dictionary definition of justify, i.e. adjusting the distribution of items along the main axis.
    So, feeling comfortable in our interpretation we move on to the next property.
&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;align-items&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;
    Again, from the specification for this property we have:
&lt;/p&gt;
&lt;blockquote class=&quot;fancyquote&quot;&gt;
    Flex items can be aligned in the cross axis of the current line of the flex container. … 
    align-items sets the default alignment for all of the flex container’s items
&lt;/blockquote&gt;
&lt;div class=&quot;center&quot;&gt;
    &lt;img src=&quot;https://cjwainwright.co.uk/webdev/flexboxalignment/images/align-items.png&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
    This also fits with the dictionary definition of align, i.e. moving the items in the cross axis to achieve a desired line up along the main axis.
    It&apos;s all beginning to make sense, no?
    But you shouldn&apos;t get too comfortable with this.
    The first sign that something is amiss with our interpretation is that this property uses “items”, but the previous one used “content”, we&apos;ll get back to that in a minute.
&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;align-content&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;
    We now meet our third property, about which the specification tells us:
&lt;/p&gt;
&lt;blockquote class=&quot;fancyquote&quot;&gt;
    The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis.
&lt;/blockquote&gt;
&lt;div class=&quot;center&quot;&gt;
    &lt;img src=&quot;https://cjwainwright.co.uk/webdev/flexboxalignment/images/align-content.png&quot;&gt;
&lt;/div&gt;
&lt;p&gt;
    Oh! What?
    This fits a lot better with the dictionary definition of justify does it not?
    And indeed, this property can take all the same values (plus &lt;code class=&quot;language-css&quot;&gt;stretch&lt;/code&gt;) that &lt;code class=&quot;language-css&quot;&gt;justify-content&lt;/code&gt; could take.
    So, what&apos;s going on? Why is this property not called justify?
&lt;/p&gt;
&lt;h2&gt;Justification&lt;/h2&gt;
&lt;p&gt;
    The flexbox alignment properties are part of a bigger picture, which has its own specification, the &lt;a href=&quot;http://www.w3.org/TR/css3-align/&quot; class=&quot;external&quot;&gt;CSS box alignment specification&lt;/a&gt;.
    This specification takes the CSS alignment behaviour of flexbox and generalizes it to be utilised across various other layout models.
&lt;/p&gt;
&lt;p&gt;
    If you read through this specification you&apos;ll find the following comment.
&lt;/p&gt;
&lt;blockquote class=&quot;fancyquote&quot;&gt;
    Note: This specification uses the terms “justify” and “align” to distinguish between alignment in the inline and stacking dimensions, respectively.
    The choice is somewhat arbitrary, but having the two terms allows for a consistent naming scheme that works across all of CSS’s layout models.
&lt;/blockquote&gt;
&lt;p&gt;
    So justify and align actually have nothing to do with their dictionary definitions, they are not distinguishing the type of alignment, they are merely for distinguishing directions of alignment.
    Bringing this back to flexbox layouts, “justify” means you&apos;re moving things in the main axis direction whereas “align” means you&apos;re moving things in the cross axis direction.
&lt;/p&gt;
&lt;p&gt;
    So what is it that distinguishes the different layout behaviours? Well, it&apos;s actually the “content” vs “items” difference we noticed earlier.
&lt;/p&gt;
&lt;p&gt;
    &lt;code class=&quot;language-css&quot;&gt;*-content&lt;/code&gt; properties are for arranging the content &lt;i&gt;with respect to their container&lt;/i&gt;.
    You can think of content as all the items treated as a whole.
    Thus, aligning content consists of things such as choosing the space around and between items in order to achieve a specific alignment with respect to their container.
    That&apos;s pretty much what we originally thought justify meant.
&lt;/p&gt;
&lt;p&gt;
    &lt;code class=&quot;language-css&quot;&gt;*-items&lt;/code&gt; properties can be thought of as defining how items should line up with each other. 
    That&apos;s what we originally thought align meant.
    The specification doesn&apos;t word it quite like this, but I think this interpretation works quite well.
    I should note that this property sets the default alignment for each item, you can actually specify a specific alignment on the item itself using the corresponding &lt;code&gt;*-self&lt;/code&gt; property.
&lt;/p&gt;
&lt;p&gt;
    So it all makes sense in the end, I hope! To help you out here&apos;s an alignment properties cheat sheet:
&lt;/p&gt;
&lt;div class=&quot;center&quot;&gt;
    &lt;table class=&quot;data&quot; style=&quot;display: inline-table;&quot;&gt;
        &lt;tbody&gt;&lt;tr&gt;
            &lt;th&gt;Term&lt;/th&gt;
            &lt;th&gt;Meaning&lt;/th&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;white-space: nowrap&quot;&gt;justify-*&lt;/td&gt;
            &lt;td&gt;move along the main axis&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;white-space: nowrap&quot;&gt;align-*&lt;/td&gt;
            &lt;td&gt;move along the cross axis&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;white-space: nowrap&quot;&gt;*-content&lt;/td&gt;
            &lt;td&gt;adjust all items together to arrange with respect to their container&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;white-space: nowrap&quot;&gt;*-items&lt;/td&gt;
            &lt;td&gt;default alignment for items relative to each other&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;white-space: nowrap&quot;&gt;*-self&lt;/td&gt;
            &lt;td&gt;specific alignment for an item relative to others&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>Source maps for private code</title><pubDate>Sun, 24 May 2015 00:00:00 GMT</pubDate><link>https://cjwainwright.co.uk/webdev/sourcemaps/index.html</link><description>&lt;div data-feed-id=&quot;SourceMapsForPrivateCode&quot; data-feed-title=&quot;Source maps for private code&quot; data-feed-date=&quot;24 May 2015&quot;&gt;
&lt;p&gt;
    If you&apos;re doing front end web development these days, chances are the source code you write is being transformed in your build process before it reaches the browser.
    It might be minification, transpilation or possibly compilation from a completely different language.
&lt;/p&gt;
&lt;p&gt;
    At some point, inevitably, you&apos;re going to want to debug the generated code that the browser is running, and it might be so terribly obfuscated from the code you wrote that it&apos;s impossible to work out exactly what is going on.
&lt;/p&gt;
&lt;p&gt;
    The solution is to use &lt;b&gt;&lt;a href=&quot;https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit&quot; class=&quot;external&quot;&gt;source maps&lt;/a&gt;&lt;/b&gt;.
    They essentially provide an inverse lookup from positions in your generated code back to your original source code.
    Source maps can be created during your build, and most build processes have some form of source map support these days. 
&lt;/p&gt;
&lt;p class=&quot;center&quot;&gt;
    &lt;img src=&quot;https://cjwainwright.co.uk/webdev/sourcemaps/images/sourcemaps.png&quot; width=&quot;600&quot; height=&quot;350&quot; alt=&quot;diagram of build process and source map&quot;&gt;
&lt;/p&gt;
&lt;p&gt;
    In order to use a source map, your browser dev tools need first to be able to find it.
    If your generated code is JavaScript, one way to let the dev tools know where to look is to add a comment to the end of the generated code which defines the &lt;b&gt;sourceMappingURL&lt;/b&gt; - the location of the source map.
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;//# sourceMappingURL=mylib.js.map&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    If this URL is not absolute, then it is assumed relative to the location of the generated code.
&lt;/p&gt;
&lt;p&gt;
    Now when you open your browser dev tools to debug the generated code, the tools can download the source map and use it to map back to your original source code.
&lt;/p&gt;
&lt;p&gt;
    There are a couple of ways the source map can link back to the original sources.
    One possibility is to have your source code available at some URL and have the source map point at that via it&apos;s &lt;b&gt;sourcesRoot&lt;/b&gt; property.
    However the option I&apos;d recommend is creating your source maps with the original source code embedded inside them using the &lt;b&gt;sourcesContent&lt;/b&gt; property.
    For one it means you don&apos;t have to host your source code.
    But further, if you change your source code without rebuilding, your source map is still going to work as it contains a snapshot of the source code from the time of the build.
&lt;/p&gt;
&lt;p class=&quot;center&quot;&gt;
    &lt;img src=&quot;https://cjwainwright.co.uk/webdev/sourcemaps/images/sourcemaps_embedded.png&quot; width=&quot;600&quot; height=&quot;350&quot; alt=&quot;diagram of build process and source map with embedded sources content&quot;&gt;
&lt;/p&gt;
&lt;p&gt;
    So you now have working source maps allowing you to debug your generated code.
    But, if you&apos;ve distributed your source maps along with your generated code, so can everyone else!
    You may not want this, after all &lt;i&gt;not all code is open source&lt;/i&gt;.
    So how do you debug your generated code without distributing the source maps?
&lt;/p&gt;
&lt;p&gt;
    One way to solve this is to host your source maps on a private website.
    This may be on localhost, or possibly shared on your private network.
    Let&apos;s say you set up a private site http://sourcemaps/, then the source mapping URL in your generated code can be set up to point at this site.
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;//# sourceMappingURL=http://sourcemaps/mylib.js.map&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    This way anyone who opens up the browser dev tools without having access to your (or their own equivalent) sourcemaps site will not be able to load the source maps (it&apos;ll 404 in the dev tools) and so your original source code is safe from prying eyes.
    You, however, will be able to debug your generated code with the aid of the correct source maps.
&lt;/p&gt;
&lt;p&gt;
    If writing a private URL into your generated code feels like a hack to you, then I agree.
    I would much rather the browser dev tools implemented a feature allowing you to choose root locations to use when resolving non-absolute source mapping URLs.
    A lot like how when debugging dlls in Visual Studio you can choose a symbols server to point at to look for the relevant pdb files.
    Imagine something like this:
&lt;/p&gt;
&lt;p class=&quot;center&quot;&gt;
    &lt;img src=&quot;https://cjwainwright.co.uk/webdev/sourcemaps/images/sourcemaps_devtools.png&quot; width=&quot;300&quot; height=&quot;290&quot; alt=&quot;possible dev tools options for setting source map servers&quot;&gt;
&lt;/p&gt;&lt;/div&gt;</description></item></channel></rss>