<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/css" href="https://www.aaron-gustafson.com/c/feed.min.css" ?><feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:amg="https://www.aaron-gustafson.com.com/amg-dtd/"><title>Aaron Gustafson: Content tagged the web</title><subtitle>The latest 20 posts and links tagged the web.</subtitle><id>https://www.aaron-gustafson.com</id><link href="https://www.aaron-gustafson.com/feeds/the-web.xml" rel="self"/><link href="https://www.aaron-gustafson.com"/><author><name>Aaron Gustafson</name><uri>https://www.aaron-gustafson.com</uri></author><updated>2026-04-29T12:00:00Z</updated><entry><id>https://www.aaron-gustafson.com/notebook/links/the-webaim-million-the-2026-report-on-the-accessibility-of-the-top-1000000-home-pages/</id><title type="html"><![CDATA[🔗 The WebAIM Million: The 2026 report on the accessibility of the top 1,000,000 home pages]]></title><link href="https://www.aaron-gustafson.com/notebook/links/the-webaim-million-the-2026-report-on-the-accessibility-of-the-top-1000000-home-pages/" rel="alternate" type="text/html" /><link href="https://webaim.org/projects/million/" rel="related" type="text/html" /><published>2026-04-29T12:00:00Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>The latest WebAIM Million is a sobering reminder that, at scale, the web is getting more complex faster than it is getting more accessible.</p><p>There are a lot of grim numbers in here, but the one that really sticks with me is how many of the same, eminently-fixable issues continue to dominate year after year. We’re still talking about contrast, missing labels, empty buttons, and missing alt text. In other words, this is not a story about edge cases. It’s a story about fundamentals.</p>]]></content><amg:twitter><![CDATA[The latest WebAIM Million is not encouraging: more complexity, more ARIA, and more detectable barriers across the top million home pages.]]></amg:twitter><amg:summary><![CDATA[The latest WebAIM Million is a sobering reminder that, at scale, the web is getting more complex faster than it is getting more accessible.]]></amg:summary><summary type="html"><![CDATA[<p>The latest WebAIM Million is a sobering reminder that, at scale, the web is getting more complex faster than it is getting more accessible.</p>]]></summary><category term="accessibility" /><category term="the web" /><category term="industry" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/links/endgame-for-the-open-web/</id><title type="html"><![CDATA[🔗 Endgame for the Open Web]]></title><link href="https://www.aaron-gustafson.com/notebook/links/endgame-for-the-open-web/" rel="alternate" type="text/html" /><link href="https://www.anildash.com/2026/03/27/endgame-open-web/" rel="related" type="text/html" /><published>2026-04-24T12:00:00Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>This is a sobering but necessary reminder that the open web’s current crisis is not theoretical; it’s already playing out across publishing, open source, standards, and shared infrastructure.</p><p>I appreciate how clearly Anil connects dots that too many people are still treating as separate problems. This isn’t just about AI summaries siphoning traffic from publishers or slop code drowning maintainers or bad actors ignoring long-standing norms like <code>robots.txt</code>. It’s all of those things at once. The through-line is extraction: taking value from open systems without giving anything back, then undermining the very ecosystems that made that extraction possible in the first place.</p><blockquote><p>The good of the web only exists because of the openness of the web. They can’t just keep on taking and taking without expecting people to finally draw a line and saying “enough”.</p></blockquote><p>If you care about the web as a public good, this post is worth your time.</p>]]></content><amg:twitter><![CDATA[This is a tough read, but an important one: the attacks on the open web are not abstract anymore.]]></amg:twitter><amg:summary><![CDATA[A sobering but necessary reminder that the open web’s current crisis is not theoretical; it’s already playing out across publishing, open source, standards, and shared infrastructure.]]></amg:summary><summary type="html"><![CDATA[<p>A sobering but necessary reminder that the open web’s current crisis is not theoretical; it’s already playing out across publishing, open source, standards, and shared infrastructure.</p>]]></summary><category term="the web" /><category term="AI/ML" /><category term="society" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.anildash.com/images/tunnel.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/links/the-power-of-no-in-internet-standards/</id><title type="html"><![CDATA[🔗 The Power of ‘No’ in Internet Standards]]></title><link href="https://www.aaron-gustafson.com/notebook/links/the-power-of-no-in-internet-standards/" rel="alternate" type="text/html" /><link href="https://www.mnot.net/blog/2026/02/13/no" rel="related" type="text/html" /><published>2026-04-23T12:05:00Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>This is an important piece about where power actually lives on the web: not in the specification itself, but in whether powerful players choose to participate, implement, and ship.</p><p>I also appreciate Mark’s call for more ambition here. Too often, we talk about the web as if it’s destined to be an OS for web apps rather than a public-interest platform in its own right. That’s not inevitable. But getting somewhere better requires recognizing that refusal, delay, and strategic disinterest can be every bit as consequential as formal opposition.</p>]]></content><amg:twitter><![CDATA[A useful reminder that the real power in standards work is often the power to say no.]]></amg:twitter><amg:summary><![CDATA[This is an important piece about where power actually lives on the web: not in the specification itself, but in whether powerful players choose to participate, implement, and ship.]]></amg:summary><summary type="html"><![CDATA[<p>This is an important piece about where power actually lives on the web: not in the specification itself, but in whether powerful players choose to participate, implement, and ship.</p>]]></summary><category term="web standards" /><category term="the web" /><category term="society" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.mnot.net/blog/image/wait_here.jpeg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/links/link-rot-and-digital-decay-on-government-news-and-other-webpages/</id><title type="html"><![CDATA[🔗 Link Rot and Digital Decay on Government, News and Other Webpages]]></title><link href="https://www.aaron-gustafson.com/notebook/links/link-rot-and-digital-decay-on-government-news-and-other-webpages/" rel="alternate" type="text/html" /><link href="https://www.pewresearch.org/data-labs/2024/05/17/when-online-content-disappears/" rel="related" type="text/html" /><published>2024-05-24T16:23:56Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<blockquote><p>A quarter of all webpages that existed at one point between 2013 and 2023 are no longer accessible, as of October 2023. In most cases, this is because an individual page was deleted or removed on an otherwise functional website.</p></blockquote><p>Linkrot, especially in government and legal scenarios, is a tremendous problem, which is why we need services like the Internet Archive and <a href="http://Perma.cc">Perma.cc</a>. If you have the means, please consider supporting these, and similar, projects!</p>]]></content><amg:twitter><![CDATA[Linkrot, especially in government and legal scenarios, is a tremendous problem, which is why we need services like the @InternetArchive and @PermaCC.]]></amg:twitter><category term="the web" /><category term="industry" /><category term="URLs" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/one-world-one-web-one-love/</id><title type="html"><![CDATA[✍🏻 One World, One Web, One Love]]></title><link href="https://www.aaron-gustafson.com/notebook/one-world-one-web-one-love/" rel="alternate" type="text/html" /><published>2024-01-25T17:19:18Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>Today would have been Molly Holzschlag’s 61st birthday. I want to take a moment to remember her by sharing a bit from <a href="https://web.archive.org/web/20120706174033/http://the-pastry-box-project.net/molly-holzschlag/2012-may-20">a post she made way back in 2012 on the new defunct <cite>Pastry Box Project</cite></a>.</p><p>The post was largely about how the web enables us to be there for one another in times of crisis. Molly shared how she found solace—while reeling from the emergency hospitalization of her mother—in the support of her community through email, Twitter, and Facebook.</p><p>Molly recognized the power of the web—and the Open Web in particular—to connect people and communities for the betterment of all humans. Sure, she saw the downsides too and would grumble about them quite often, but she was a firm believer that the web was a net positive for the world.</p><p>As I reflected on her life last year when we lost her, this passage really struck me:</p><blockquote><p>Mortality reminds us in very cold, frightening terms how fragile our life and times truly are. The Web, which is a naturally social and interactive communications platform, can help bring us all closer. The fighting, the drama, the debates - they all become irrelevant in these very mortal moments. Let us all reach for the greatness within ourselves and put it into our Web work every day, because even on those days we feel it’s overwhelming or doesn’t matter, it really truly does. One world, one Web, one love, my brothers and sisters.</p></blockquote><p>I cannot think of a better way to remember Molly on this day.</p><p>Much love to you and your communities!</p>]]></content><amg:twitter><![CDATA[Today would have been Molly Holzschlag’s 61st birthday. I want to take a moment to remember her by sharing a bit from a post she made way back in 2012.]]></amg:twitter><amg:summary><![CDATA[Today would have been Molly Holzschlag’s 61st birthday. I want to take a moment to remember her by sharing a bit from a post she made way back in 2012.]]></amg:summary><summary type="html"><![CDATA[<p>Today would have been Molly Holzschlag’s 61st birthday. I want to take a moment to remember her by sharing a bit from a post she made way back in 2012.</p>]]></summary><category term="inclusion" /><category term="influences" /><category term="personal" /><category term="the web" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.aaron-gustafson.com/i/posts/2024-01-25/hero.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/sharing-in-the-age-of-3p-cookie-mageddon/</id><title type="html"><![CDATA[✍🏻 Sharing in the Age of 3p Cookie-mageddon]]></title><link href="https://www.aaron-gustafson.com/notebook/sharing-in-the-age-of-3p-cookie-mageddon/" rel="alternate" type="text/html" /><published>2023-12-15T18:28:35Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>Over a decade ago, I wrote up <a href="https://blog.easy-designs.net/archives/dont-sell-out-your-users/">detailed instructions on how to enable users to share your content on social media without allowing them to be tracked by every social media site via cookies</a>. In a few short weeks <a href="https://developers.google.com/privacy-sandbox/blog/cookie-countdown-2023oct">“third party” cookies will get the boot in Chromium-based browsers</a>. If you’re still relying on third party share widgets on your site, your users may start seeing problems. Now is a good time to replace them with code that Just Works™. Here’s how…</p><h2 id="sharing%2C-the-old-fashioned-way" tabindex="-1"><a class="header-anchor" href="#sharing%2C-the-old-fashioned-way" aria-hidden="true">#</a> Sharing, the Old-fashioned Way</h2><p>When it comes to sharing, there are myriad ways to do it. If you’re at all familiar with my work, it should come as no surprise that I always start with a universally-useable and accessible baseline and then <a href="/tags/progressive-enhancement">progressively enhance</a> things from there. Thankfully, every social media site I commonly use (with the exception of the Fediverse) makes this pretty easy by providing a form that accepts inbound content via the query string.<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup> You can <a href="https://www.linkedin.com/cws/share?url=https://www.aaron-gustafson.com/notebook/rebuilding-a-php-app-using-isomorphic-javascript-with-eleventy-and-netlify/">try LinkedIn’s to see it in action</a>.</p><p>Each service is a little different, but all function similarly. I support the following ones in this site:</p><table><caption>Social Media Sites and Their Sharing URLs</caption><thead><tr><th scope="col">Site</th><th scope="col">Destination</th><th scope="col">URL</th><th scope="col">Optional Params</th></tr></thead><tbody><tr><th scope="row">Twitter / X</th><td><a href="https://twitter.com/%EF%BF%BD4%EF%BF%BDintent/tweet%EF%BF%BD5%EF%BF%BD%EF%BF%BD6%EF%BF%BD%EF%BF%BD7%EF%BF%BDurl%EF%BF%BD8%EF%BF%BD%EF%BF%BD9%EF%BF%BD%EF%BF%BD10%EF%BF%BD%EF%BF%BD11%EF%BF%BD%EF%BF%BD12%EF%BF%BD">https://twitter.com/�4�intent/tweet�5��6��7�url�8��9��10��11��12�</a><tr><th scope="row">Hacker News</th><td><a href="https://news.ycombinator.com/%EF%BF%BD4%EF%BF%BDsubmitlink%EF%BF%BD5%EF%BF%BD%EF%BF%BD6%EF%BF%BD%EF%BF%BD7%EF%BF%BDu%EF%BF%BD8%EF%BF%BD%EF%BF%BD9%EF%BF%BD%EF%BF%BD10%EF%BF%BD%EF%BF%BD11%EF%BF%BDt%EF%BF%BD12%EF%BF%BD">https://news.ycombinator.com/�4�submitlink�5��6��7�u�8��9��10��11�t�12�</a> = the title you want to share </td></tr><tr><th scope="row">Facebook</th><td><a href="https://www.facebook.com/%EF%BF%BD4%EF%BF%BDsharer.php%EF%BF%BD5%EF%BF%BD%EF%BF%BD6%EF%BF%BD%EF%BF%BD7%EF%BF%BDu%EF%BF%BD8%EF%BF%BD%EF%BF%BD9%EF%BF%BD%EF%BF%BD10%EF%BF%BD%EF%BF%BD11%EF%BF%BD%EF%BF%BD12%EF%BF%BD">https://www.facebook.com/�4�sharer.php�5��6��7�u�8��9��10��11��12�</a><tr><th scope="row">LinkedIn</th><td><a href="https://www.linkedin.com/cws/share%EF%BF%BD4%EF%BF%BD%EF%BF%BD5%EF%BF%BD%EF%BF%BD6%EF%BF%BDurl%EF%BF%BD7%EF%BF%BD%EF%BF%BD8%EF%BF%BD%EF%BF%BD9%EF%BF%BD%EF%BF%BD10%EF%BF%BD%EF%BF%BD11%EF%BF%BD">https://www.linkedin.com/cws/share�4��5��6�url�7��8��9��10��11�</a><tr><th scope="row">Pinterest</th><td><a href="https://pinterest.com/%EF%BF%BD4%EF%BF%BDpin/create/button/%EF%BF%BD5%EF%BF%BD%EF%BF%BD6%EF%BF%BD%EF%BF%BD7%EF%BF%BDurl%EF%BF%BD8%EF%BF%BD%EF%BF%BD9%EF%BF%BD%EF%BF%BD10%EF%BF%BD%EF%BF%BD11%EF%BF%BDmedia%EF%BF%BD12%EF%BF%BD">https://pinterest.com/�4�pin/create/button/�5��6��7�url�8��9��10��11�media�12�</a> = an image to share<br><code>description</code> = the text you want to share</td></tr></tbody></table><p>Using this information, I created <a href="https://github.com/aarongustafson/aaron-gustafson.com/blob/main/src/_includes/partials/post/sharing.njk">a partial template for use on any page in this site</a> (though I mainly use it on blog posts right now). Each link includes useful text content (e.g., “Share on <strong>__</strong>”) and a local SVG of the service’s icon. Here’s a simplified overview of the markup I use:</p><pre class="language-html" tabindex="0"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>social-links social-links–share<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>social-links__item<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span><span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>{{ SHARE URL }}<span class="token punctuation">”</span></span><span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>social-link<span class="token punctuation">”</span></span><span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>nofollow<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span><span class="token punctuation">&gt;</span></span>{{ SERVICE ICON }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>b</span><span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>social-link__text<span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>Share on {{ SERVICE NAME }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>b</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">&gt;</span></span></code></pre><p>You can check out the baseline experience on this very page by disabling JavaScript.</p><figure id="2023-12-14-01"><p><img src="https://www.aaron-gustafson.com/i/posts/2023-12-15/1.png" alt=""></p><figcaption>My baseline sharing component is a list of icon links.</figcaption></figure><p>It’s worth noting that I have chosen not to enforce opening these links in a new tab. You can do that if you like, but on mobile devices I’d prefer the user just navigate to the share page directly. You may have a different preference, but if you decide to spawn a new tab, be sure your link text lets folks know that’s what will happen. I do include a <a href="https://developer.mozilla.org/docs/Web/HTML/Attributes/rel#nofollow"><code>rel=&quot;nofollow&quot;</code></a> on the link, however, to prevent search spiders from indexing the share forms.</p><p>If you test out these links, you’ll notice many of the target forms will pick up a ton of information from your page automatically. By and large, this info is grabbed from your page’s <a href="https://developers.facebook.com/docs/opengraph/">Open Graph data</a> (<a href="https://developers.facebook.com/docs/sharing/webmasters#markup">stored in <code>meta</code> tags</a>) or <a href="https://www.w3.org/TR/json-ld11/">Linked Data</a> (as <a href="https://json-ld.org/">JSON-LD</a>). You can write that info to your page by hand or use a plugin to generate it for you automatically. There are a ton of options out there if you choose to go the later route (which I’d recommend).</p><h2 id="enhancement-level-1%3A-popup-share" tabindex="-1"><a class="header-anchor" href="#enhancement-level-1%3A-popup-share" aria-hidden="true">#</a> Enhancement Level 1: Popup Share</h2><p>If you played around with any of the various share forms, you probably noticed that they are, by and large, designed as discrete interactions best-suited to a narrow window (e.g., mobile) or popup. To provide that experience, I’ve long-relied on a little bit of JavaScript to launch them in a new, appropriately-sized window:</p><pre class="language-js" tabindex="0"><code class="language-js"><span class="token keyword">function</span><span class="token function">popup</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">var</span> $link <span class="token operator">=</span> e<span class="token punctuation">.</span>target<span class="token punctuation">;</span><span class="token keyword">while</span><span class="token punctuation">(</span>$link<span class="token punctuation">.</span>nodeName<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">!=</span><span class="token string">“a”</span><span class="token punctuation">)</span><span class="token punctuation">{</span>$link <span class="token operator">=</span> $link<span class="token punctuation">.</span>parentNode<span class="token punctuation">;</span><span class="token punctuation">}</span>e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> popup <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span>$link<span class="token punctuation">.</span>href<span class="token punctuation">,</span><span class="token string">“share”</span><span class="token punctuation">,</span><span class="token string">“height=500,width=600,status=no,toolbar=no,popup”</span><span class="token punctuation">,</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">try</span><span class="token punctuation">{</span>popup<span class="token punctuation">.</span><span class="token function">focus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">catch</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token keyword">var</span> screen_width <span class="token operator">=</span><span class="token string">“visualViewport”</span><span class="token keyword">in</span> window<span class="token operator">?</span> window<span class="token punctuation">.</span>visualViewport<span class="token punctuation">.</span>width<span class="token operator">:</span> window<span class="token punctuation">.</span>innerWidth<span class="token punctuation">,</span>$links <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">“.social-links–share a”</span><span class="token punctuation">)</span><span class="token punctuation">,</span>count <span class="token operator">=</span> $links<span class="token punctuation">.</span>length<span class="token punctuation">;</span><span class="token keyword">if</span><span class="token punctuation">(</span>screen_width <span class="token operator">&gt;</span><span class="token number">600</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">while</span><span class="token punctuation">(</span>count<span class="token operator">–</span><span class="token punctuation">)</span><span class="token punctuation">{</span>$links<span class="token punctuation">[</span>count<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">“click”</span><span class="token punctuation">,</span> popup<span class="token punctuation">,</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>$links<span class="token punctuation">[</span>count<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">“.social-link__text”</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">+=</span><span class="token string">&quot; (in a popup)“</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><p>The first chunk defines a new function called <code>popup()</code> that will act as the event listener. It takes the event (<var>e</var>) as an argument and then finds the associated link (bubbling up through the DOM as necessary in that <code>while</code> loop). Once it finds the link, the function opens a new popup window (using <code>window.open()</code>). Then, to check if the popup was blocked, it attempts (within the <code>try…catch</code>) to focus it. If the focus succeeds, which means the popup wasn’t blocked, the script prevents the link from navigating the user to the <code>href</code> (which is the default behavior, hence <code>e.preventDefault()</code>).</p><p>The second block defines a couple of variables we’ll need. First, it captures the current <var>screen_width</var> using either the window’s <code>visualViewport</code> (if available) or its <code>innerWidth</code> (which is more old school). Next it grabs the social links (<var>$links</var>) and counts them for looping purposes (<var>count</var>).</p><p>The final block is a conditional that checks to see if the <var>screen_width</var> is wider than 600px (an arbitrary width that just feels right… your mileage may vary). If the screen is wider than that threshold, it loops through the links,<sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup> adds the click handler, and adds some text to the link label to let folks know it will open a popup.</p><p>And with that, the first layer of enhancement is complete: Users with JavaScript support who also happen to be using a wider browser window will get the popup share form if the popup is allowed. If the popup isn’t allowed, they’ll default to the baseline experience.</p><h2 id="enhancement-level-2%3A-os-share" tabindex="-1"><a class="header-anchor" href="#enhancement-level-2%3A-os-share" aria-hidden="true">#</a> Enhancement Level 2: OS Share</h2><p>A few years back, browsers began participating in OS-level share activities. On one side, this allowed websites to share some data—URLs, text, files—to other apps on the device via <code>navigator.share()</code>. On the other side of the equation, Progressive Web Apps could advertise themselves—via the Manifest’s <code>share_target</code> member—as being able to receive content shared in this way.</p><p>Sharing a URL and text is <a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share#browser_compatibility">really well supported</a>. That said, it’s only been around a few years at this point and some browsers require an additional permission to use the API.<sup class="footnote-ref"><a href="#fn3" id="fnref3">3</a></sup> For these reasons, it’s best to use the API as a progressive enhancement. Thankfully, it’s easy to test for support:</p><pre class="language-js" tabindex="0"><code class="language-js"><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token string">“share”</span><span class="token keyword">in</span> navigator<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token comment">// all good!</span><span class="token punctuation">}</span></code></pre><p>For my particular implementation, I’ve decided to swap out the individual links for a single button that, when clicked, will proffer the page’s details over to the OS’s share widget. Here’s the code I use to do that:</p><pre class="language-js" tabindex="0"><code class="language-js"><span class="token keyword">var</span> $links <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">”.social-links–share&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>$parent <span class="token operator">=</span> $links<span class="token punctuation">.</span>parentNode<span class="token punctuation">,</span>$button <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">“button”</span><span class="token punctuation">)</span><span class="token punctuation">,</span>title <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">“h1.p-name,title”</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerText<span class="token punctuation">,</span>$description <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">‘meta[name=“og:description”],meta[name=“description”]’</span><span class="token punctuation">,</span><span class="token punctuation">)</span><span class="token punctuation">,</span>text <span class="token operator">=</span> $description <span class="token operator">?</span> $description<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">“content”</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token string">“”</span><span class="token punctuation">,</span>url <span class="token operator">=</span> window<span class="token punctuation">.</span>location<span class="token punctuation">.</span>href<span class="token punctuation">;</span>$button<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span><span class="token string">“Share &lt;svg&gt;…&lt;/svg&gt;”</span><span class="token punctuation">;</span>$button<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">“click”</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token punctuation">{</span>navigator<span class="token punctuation">.</span><span class="token function">share</span><span class="token punctuation">(</span><span class="token punctuation">{</span> title<span class="token punctuation">,</span> text<span class="token punctuation">,</span> url <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>$parent<span class="token punctuation">.</span><span class="token function">insertBefore</span><span class="token punctuation">(</span>$button<span class="token punctuation">,</span> $links<span class="token punctuation">)</span><span class="token punctuation">;</span>$links<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>The first block sets up my variables:</p><ul><li><var>$links</var> - A reference to the list (<code>ul</code>) of sharing links;</li><li><var>$parent</var> - the parent container of that list;</li><li><var>$button</var> - the button I’m going to swap in for the links;</li><li><var>title</var> - The page title (either from the page’s <code>h1</code> or <code>title</code> element);</li><li><var>$description</var> - A reference to a <code>meta</code> description element;</li><li><var>text</var> - The text content of that description, if one is found; and</li><li><var>url</var> - The URL to be shared.</li></ul><p>The second block sets up the button by inserting the text “Share” and an SVG share icon and setting an event listener on it that will pass the collected info to <code>navigator.share()</code>.</p><p>The third and final block swaps out the link list for the button.</p><h2 id="putting-it-all-together" tabindex="-1"><a class="header-anchor" href="#putting-it-all-together" aria-hidden="true">#</a> Putting It All Together</h2><p>The final step to putting this all together involves setting up the conditional that determines which enhancement is offered. To keep everything a bit cleaner, I’m also moving each of the enhancements into its own function:</p><pre class="language-js" tabindex="0"><code class="language-js"><span class="token operator">!</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">window<span class="token punctuation">,</span> document<span class="token punctuation">,</span> navigator</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">function</span><span class="token function">prepForPopup</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token comment">// popup code</span><span class="token punctuation">}</span><span class="token keyword">function</span><span class="token function">popup</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token comment">// popup event handler</span><span class="token punctuation">}</span><span class="token keyword">function</span><span class="token function">swapForShareAPI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token comment">// share button code</span><span class="token punctuation">}</span><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token string">“share”</span><span class="token keyword">in</span> navigator<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token function">swapForShareAPI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span><span class="token function">prepForPopup</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span><span class="token keyword">this</span><span class="token punctuation">.</span>document<span class="token punctuation">,</span><span class="token keyword">this</span><span class="token punctuation">.</span>navigator<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>With this setup in place, I can provide the optimal experience in browsers that support the web share API and a pretty decent fallback experience to browsers that don’t. And if none of these enhancements can be applied, users can still share my content to the places I’ve identified… no cookies or third-party widgets required.</p><p>You can <a href="https://codepen.io/aarongustafson/pen/eYxajwy">see (and play with) an isolated demo of this interface over on Codepen</a>.</p><hr class="footnotes-sep"><section class="footnotes"><h4 class="hidden">Footnotes</h4><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>Interesting side-note: If you own a form like this on your site, <a href="/notebook/my-own-personal-pwa/">it makes a great share target</a>. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>Why a reverse <code>while</code> loop? Well, the order of execution doesn’t matter and decrementing <code>while</code> loops are faster in some instances. It’s a micro-optimization that boosts perf on older browsers and lower-end chipsets. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li><li id="fn3" class="footnote-item"><p>Like many modern APIs, it also requires a secure connection (HTTPS). <a href="#fnref3" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content><amg:twitter><![CDATA[Are you still relying on third party share widgets? You should really stop that. Here’s how…]]></amg:twitter><amg:summary><![CDATA[Over a decade ago, I wrote up detailed instructions on how to enable users to share your content on social media without allowing them to be tracked by every social media site via cookies. In a few short weeks “third party” cookies will get the boot in Chromium-based browsers. If you’re still relying on third party share widgets on your site, now is a good time to replace them. Here’s how…]]></amg:summary><summary type="html"><![CDATA[<p>Over a decade ago, I wrote up detailed instructions on how to enable users to share your content on social media without allowing them to be tracked by every social media site via cookies. In a few short weeks “third party” cookies will get the boot in Chromium-based browsers. If you’re still relying on third party share widgets on your site, now is a good time to replace them. Here’s how…</p>]]></summary><category term="HTML" /><category term="privacy" /><category term="progressive enhancement" /><category term="the web" /><category term="user experience" /><category term="web development" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.aaron-gustafson.com/i/posts/2023-12-15/hero.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/remembering-molly/</id><title type="html"><![CDATA[✍🏻 Remembering Molly]]></title><link href="https://www.aaron-gustafson.com/notebook/remembering-molly/" rel="alternate" type="text/html" /><published>2023-09-08T18:14:31Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>We lost a seminal figure in the world of web design this week. And I lost a good friend and mentor. Molly Holzschlag cared deeply for the web and those of us who till its soils.</p><p>This is a tough post to write, to be honest. It’s difficult to articulate just how influential Molly has been on my own work, my philosophical approach to web design, and my career.</p><h2 id="molly-was-warm-and-welcoming" tabindex="-1"><a class="header-anchor" href="#molly-was-warm-and-welcoming" aria-hidden="true">#</a> Molly was warm and welcoming</h2><figure id="2023-09-08-01"><p><img src="https://www.aaron-gustafson.com/i/posts/2023-09-08/molly-and-patrick-at-tpac.jpg" alt=""></p><figcaption>Molly and Patrick Haney saying cheers with their mini smoothies at the W3C’s 2007 TPAC conference in Cambridge, MA. She’d invited me, Patrick, Steph Troeth, and Matt Oliphant to give the W3C an outsider’s perspective of their organization.</figcaption></figure><p>Molly was there when I gave my first talk. 2003. COMDEX. I’d been invited out by the World Organization of Webmasters to give a talk on XHTML. The talk was solid. My delivery was atrocious. Molly was quick to come up after and congratulate me. I was floored.</p><p>I told her how excited I was to see her and Eric Meyer give a talk on CSS later in the day. She told me Eric had had to cancel his trip last minute and asked me if I would be interested in giving the talk with her. Just like that. I don’t know that she had any idea who I was (I’d only just published my first piece in <cite>A List Apart</cite> a few months earlier). But that was how Molly rolled. She saw my passion for web standards and somehow knew I’d be able to step up.</p><p>That one welcoming gesture was huge for me. And it was the start of a long collaboration and friendship. After that talk, we met up in Vegas again in 2004 and then went on a speaking tour the U.S. together in 2005, running web standards workshops where we taught people the fundamentals of HTML, CSS, JavaScript, and accessibility. I learned so much from her during that time and bore witness, over and over, to her immense capacity for welcoming people, bringing them together, breaking bread, building her tribe… she was the very embodiment of the word <em>hospitable</em>.</p><p>And <em>gregarious</em>. Her boisterous laugh was infectious and memorable. I can still hear it echoing in my ears.</p><h2 id="molly-was-generous-with-her-time" tabindex="-1"><a class="header-anchor" href="#molly-was-generous-with-her-time" aria-hidden="true">#</a> Molly was generous with her time</h2><figure id="2023-09-08-02"><p><img src="https://www.aaron-gustafson.com/i/posts/2023-09-08/aaron-and-molly.jpg" alt="Me and Molly presenting at TechEd in 2005. We’re at the front of a darkened conference room and someone in front of us is looking at the World Organization of Webmasters’ website on a CRT monitor."></p><figcaption>This was Molly and I presenting at TechEd Pasadena, CA in 2005. One of many stops we made on our tour that year.</figcaption></figure><p>I don’t know that I’ve ever met someone who gave as much of herself as Molly did. She always, <em>always</em> put others first, sometimes to her own detriment.</p><p>When I first met Molly, she was leading the Web Standards Project (WaSP). She poured her heart and soul into that organization and the cause of web standards. I lost count of how many events she spoke at, often on her own dime. She invited educators into her home to teach them how to properly teach the next generation of web designers and developers… for free.</p><p>She always put her advocacy for the cause first… a double edged sword we’ve since named advocacy fatigue. It took a toll on her—mentally, physically, and spiritually—and she took the occasional break from it, but she never gave up on the fight for a more egalitarian web.</p><h2 id="molly-created-opportunities-for-others" tabindex="-1"><a class="header-anchor" href="#molly-created-opportunities-for-others" aria-hidden="true">#</a> Molly created opportunities for others</h2><figure id="2023-09-08-03"><p><img src="https://www.aaron-gustafson.com/i/posts/2023-09-08/working-on-slides.jpg" alt="In this photo Molly is lying on her stomach on a hotel bed with two laptops open. She’s working on our slide deck."></p><figcaption>While on tour, Molly and I spent nearly every waking moment together, working on our slides, hatching plans, and generally having a ball. She was the big sister I’d never had.</figcaption></figure><p>Another aspect of Molly’s giving nature was her insistence on opening doors for people, career-wise. I witnessed her pass along amazing opportunities that found their way into her inbox with an incredible amount of joy. Like doling out incredible gifts for a holiday.</p><p>One such gift she handed me was the opportunity to do some work with Adaptive Path. Through her introduction, I got the chance to work with an amazing team on several projects… all from my living room thousands of miles from their San Francisco offices. That was the kind of sway she pulled.</p><p>That work led to a part-time role (and health insurance) at Bolt|Peters, where I worked on Ethnio. That role gave me the freedom to quit my day job at an ad agency and begin building my own consulting business, which I launched a few months later and ran for over a decade.</p><p>All because of the doors Molly opened.</p><p>In a separate path, she invited me to join WaSP, where I worked on a lot of JavaScript-focused efforts. That led to me working with Microsoft on improvements to IE7 and IE8 and—years later—to me eventually joining Microsoft as a web standards advocate.</p><p>All because of the doors Molly opened.</p><p>And I was not alone. Wherever and whenever Molly saw an opportunity to help someone on their career journey, she would help them. Book contracts. Speaking engagements. Networking. Freelance work. If Molly saw any way she could help you, she did. No ego. No expectations. Selfless.</p><p>Her example is what inspired me to build my mentoring program. I don’t know that I can ever do as much good as she did for people, but she made me want to try.</p><h2 id="molly-wanted-the-web-to-win" tabindex="-1"><a class="header-anchor" href="#molly-wanted-the-web-to-win" aria-hidden="true">#</a> Molly wanted the web to win</h2><figure id="2023-09-08-04"><p><img src="https://www.aaron-gustafson.com/i/posts/2023-09-08/molly-training.jpg" alt="In this photo Molly is teaching people about the CSS box model. The screen behind her shows a dissection of the different parts that affect an element’s dimensions and layout."></p><figcaption>So much of my presentation style and skills were learned from watching Molly work her magic.</figcaption></figure><p>If you know Molly’s name, this is probably why. She was a staunch—and loud—advocate for web standards and accessibility. A veteran of the browser wars (and subsequent skirmishes), she knew the landscape and she knew how imperative it was for standards to emerge and for browsers to implement them consistently.</p><p>I wasn’t there for the meeting, but she told me Bill Gates tried to tell her the web was “done” ’round about the IE6 days and she yelled at him. While she wasn’t one to shy away from the occasional embellishment, she was just as unlikely to shy away from a confrontation over the viability and future of the web… so it would not surprise me at all to hear that she’d yelled at him.</p><p>Molly was a lioness—nurturing and maternal to the web and its denizens and a fierce protector when they were threatened. She saw the potential of the web as a great equalizer and bristled when folks would try to wall it off or exclude people—especially disempowered people—from accessing it.</p><p>That passionate support for the open web never wavered, even when Molly became ill. In fact we’d been talking about whether it might make sense to re-launch WaSP this year, a decade after we’d shuttered it because we thought the work was done—it wasn’t.</p><h2 id="molly-will-live-on-in-our-memories-and-our-craft" tabindex="-1"><a class="header-anchor" href="#molly-will-live-on-in-our-memories-and-our-craft" aria-hidden="true">#</a> Molly will live on in our memories and our craft</h2><figure id="2023-09-08-05"><p><img src="https://www.aaron-gustafson.com/i/posts/2023-09-08/molly-presenting.jpg" alt="In this photo Molly is presenting on some topic or another. She is isolated against a white wall with a strong shadow behind her from the spotlights."></p></figure><p>Knowing Molly affected me. Deeply. Her kindness, thoughtfulness, generosity, and passion live on in everyone her life and work touched. Including me.</p><p>I don’t know what to make of a world without Molly, but I hate that we’re living in one. She truly was a force of nature and, as such, has left an indelible mark on this industry.</p><p>I’m so thankful to have known her. To have received her mentorship. To have called her a friend.</p><p>Goodnight Mols. I love you.</p><figure id="2023-09-08-06"><audio src="/m/loves-immortal-fountain.mp3" controls><p>Looks like you can’t play this audio file. <a href="/m/loves-immortal-fountain.mp3" download>Try downloading it</a>.</p></audio><figcaption>Molly was also a talented songwriter, singer, and musician. This is a recording of “Love’s Immortal Fountain,” which she also wrote.</figcaption></figure><hr><h2 id="other-folks%E2%80%99-memories-of-molly" tabindex="-1"><a class="header-anchor" href="#other-folks%E2%80%99-memories-of-molly" aria-hidden="true">#</a> Other folks’ memories of Molly</h2><ul><li><a href="https://webdirections.org/blog/vale-molly-holzschlag/">John Allsopp</a></li><li><a href="https://www.linkedin.com/posts/farukates_im-deeply-saddened-by-the-news-that-my-dear-activity-7105772524147277824-ndgC">Faruk Ateş</a></li><li><a href="https://www.lireo.com/remembering-molly-holzschlag/">Deborah Edwards-Oñoro</a></li><li><a href="https://meryl.net/in-memory-of-molly-e-holzschlag-the-fairy-godmother-of-the-web/">Meryl Evans</a></li><li><a href="https://gri.gs/844/remembering-molly/">Jason Grigsby</a></li><li><a href="https://www.linkedin.com/posts/stephenhay_remembering-molly-aaron-gustafson-activity-7110154519165956096--rGY/">Stephen Hay</a></li><li><a href="https://thehistoryoftheweb.com/remembering-molly-one-of-the-greats/">Jay Hoffman</a></li><li><a href="https://brucelawson.co.uk/2023/goodbye-molly-holzschlag/">Bruce Lawson</a></li><li><a href="https://www.linkedin.com/posts/maymatt_cn-death-my-first-paid-speaking-gig-in-activity-7105036507572310016-Z55E">Matt May</a></li><li><a href="https://meyerweb.com/eric/thoughts/2023/09/06/memories-of-molly/">Eric Meyer</a></li></ul><p>More <a href="https://front-end.social/tags/mollyholzschlag">on front-end.social by following #MollyHolzschlag</a>.</p><p>Know of others? Please <a href="/contact/?reason=Another+rememberence+post+about+Molly">share them</a>.</p>]]></content><amg:twitter><![CDATA[We lost a seminal figure in the world of web design this week. And I lost a good friend and mentor. RIP Molly Holzschlag.]]></amg:twitter><amg:summary><![CDATA[We lost a seminal figure in the world of web design this week. And I lost a good friend and mentor. RIP Molly Holzschlag.]]></amg:summary><summary type="html"><![CDATA[<p>We lost a seminal figure in the world of web design this week. And I lost a good friend and mentor. RIP Molly Holzschlag.</p>]]></summary><category term="influences" /><category term="career" /><category term="personal" /><category term="industry" /><category term="the web" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.aaron-gustafson.com/i/posts/2023-09-08/molly-taking-pictures.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/links/mastodon-twitter-crossposter/</id><title type="html"><![CDATA[🔗 Mastodon Twitter Crossposter]]></title><link href="https://www.aaron-gustafson.com/notebook/links/mastodon-twitter-crossposter/" rel="alternate" type="text/html" /><link href="https://crossposter.masto.donte.com.br" rel="related" type="text/html" /><published>2022-10-31T20:37:26Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>If you’re considering moving to Mastodon, but not ready to give up on Twitter yet, you should check out this awesome, highly-configurable cross-posting tool.</p>]]></content><amg:twitter><![CDATA[If you’re considering moving to Mastodon, but not ready to give up on Twitter yet, you should check out this awesome, highly-configurable cross-posting tool.]]></amg:twitter><category term="social" /><category term="the web" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/locking-down-your-github-hosted-domains/</id><title type="html"><![CDATA[✍🏻 Locking down your GitHub-hosted Domains]]></title><link href="https://www.aaron-gustafson.com/notebook/locking-down-your-github-hosted-domains/" rel="alternate" type="text/html" /><published>2022-08-11T20:15:48Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>The other day someone claimed a hostname on a domain I own and it took me a while to track down how. After a lot of digging around, trying to figure out how the hijack was accomplished, it turns out it was via GitHub Pages.</p><p>When you set up a custom domain with GitHub pages, you have to point your domain at GitHub’s servers. <a href="https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site">There are a bunch of ways to do this</a>, but if you use an A record, you need to be careful with your DNS settings. The site in question had a wildcard hostname (*) A record pointed at GitHub’s servers. At the time I’d set it up, that was the recommendation if you wanted all traffic to go to the same place.</p><p>Fast forward a few years and <a href="https://medium.com/@jehy/hijacking-domain-using-github-pages-41c80ac57523">it’s become a known exploit of GitHub Pages</a>: when wildcard hostnames are in play, any repo can add a CNAME file to their repository and claim ownership of a hostname belonging to that domain. GitHub even warns you not to do this anymore, but I hadn’t checked the docs in years. In my particular case, it was an archived domain that I don’t really use anymore, but I wouldn’t have been aware of the DNS hijack if the attacker hadn’t taken the step of claiming the domain on Google’s Webmaster Central.</p><p>Thankfully the fix was simple: Remove the wildcard A record and point the Apex domain at GitHub’s IP addresses.</p><p>If you use GitHub pages to host any of your own domains, I highly recommend auditing their DNS records to ensure this doesn’t happen to you. You can also use <a href="https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/verifying-your-custom-domain-for-github-pages">domain verification for GitHub Pages</a> and <a href="https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-organization-settings/verifying-or-approving-a-domain-for-your-organization">organizations</a> to further protect yourself.</p>]]></content><amg:twitter><![CDATA[If you use GitHub Pages and don’t have your DNS properly configured, anyone can add a hostname to your domain]]></amg:twitter><amg:summary><![CDATA[The other day someone claimed a hostname on a domain I own and it took me a while to track down how. Turns out it was via GitHub pages.]]></amg:summary><summary type="html"><![CDATA[<p>The other day someone claimed a hostname on a domain I own and it took me a while to track down how. Turns out it was via GitHub pages.</p>]]></summary><category term="hazards" /><category term="URLs" /><category term="the web" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.aaron-gustafson.com/i/posts/2022-08-11/hero.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/links/the-internet-isn-t-forever-/</id><title type="html"><![CDATA[🔗 The Internet Isn’t Forever ]]></title><link href="https://www.aaron-gustafson.com/notebook/links/the-internet-isn-t-forever-/" rel="alternate" type="text/html" /><link href="https://longreads.com/2018/02/20/the-internet-isnt-forever/" rel="related" type="text/html" /><published>2018-02-28T20:33:35Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>This excellent piece breaks down many of the issues around what it means (in the larger, societal sense) to store information digitally.</p><blockquote><p>In the 21st century, more and more information is “born digital” and will stay that way, prone to decay or disappearance as servers, software, Web technologies, and computer languages break down. The task of internet archivists has developed a significance far beyond what anyone could have imagined in 2001, when the Internet Archive first cranked up the Wayback Machine and began collecting Web pages…</p></blockquote>]]></content><category term="the web" /><category term="the future" /><category term="society" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://longreadsblog.files.wordpress.com/2018/02/bustillos-full-774x10241-e1519013270135.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/links/i-bought-a-book-about-the-internet-from-1994-and-none-of-the-links-worked/</id><title type="html"><![CDATA[🔗 I Bought a Book About the Internet From 1994 and None of the Links Worked]]></title><link href="https://www.aaron-gustafson.com/notebook/links/i-bought-a-book-about-the-internet-from-1994-and-none-of-the-links-worked/" rel="alternate" type="text/html" /><link href="https://motherboard.vice.com/en_us/article/paabgg/i-bought-a-book-about-the-internet-from-1994-and-none-of-the-links-worked" rel="related" type="text/html" /><published>2017-08-25T18:43:03Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>A tale of woe as old as… well, the Web. The Web is mutable. Content disappears, for good and for bad. This is part of the reason projects like <a href="https://archive.org/web/">Archive.org</a> and <a href="https://perma.cc/">Perma.cc</a> excite me so much. It’s also why <a href="https://aarongustafson.github.io/notebook/avoiding-linkrot-in-print-with-the-help-of-perma-dot-cc/">I chose to use Perma.cc to archive every site referenced in my book</a>.</p>]]></content><amg:twitter><![CDATA[This is why I chose to use Perma.cc to archive every site referenced in Adaptive Web Design]]></amg:twitter><category term="the web" /><category term="hazards" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://video-images.vice.com/articles/5990e613348aac59d3f1a05f/lede/1502668921693-Untitled-design-1.jpeg?image-resize-opts=Y3JvcD0xeHc6MC43NzUyeGg7MHh3LDAuMTZ4aCZyZXNpemU9MTIwMDoqJnJlc2l6ZT0xMjAwOio" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/why-do-you-love-the-web/</id><title type="html"><![CDATA[✍🏻 Why Do You Love the Web?]]></title><link href="https://www.aaron-gustafson.com/notebook/why-do-you-love-the-web/" rel="alternate" type="text/html" /><published>2017-03-08T15:20:23Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>A few weeks back, <a href="https://www.aaron-gustafson.com/notebook/looking-for-a-mentor/">I put out the call for a mentee for 2017</a>. As part of the application process, I asked folks to publicly discuss why they love the Web. The applicants shared some amazing stories, anecdotes, and experiences in those posts and I wanted to take a moment to share them with you.<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>  I present them here, in order of submission.</p><h2 id="max-cantor%3A-growing-up-online%3A-penpals-and-php" tabindex="-1"><a class="header-anchor" href="#max-cantor%3A-growing-up-online%3A-penpals-and-php" aria-hidden="true">#</a><a href="https://sufferingasaservice.com/growing-up-online-penpals-and-php-d55844944ee4#.oh9m9gp4x">Max Cantor: Growing Up Online: Penpals and PHP</a></h2><blockquote><p>I still remember the first time a friend with a different provider gave me their email address. I was used to the cozy confines of AOL, where emailing another user required only their “screen name”–what we think of today as the part that goes before the @ sign. (Mine was Maxinator1.)</p></blockquote><blockquote><p>“What’s this funny stuff at the end, after your screen name?” I asked.</p></blockquote><blockquote><p>“That’s the domain. Mine’s compuserve dot com. Yours must be AOL dot com.”</p></blockquote><blockquote><p>“What? You can’t not be on AOL.”</p></blockquote><blockquote><p>“Why not?”</p></blockquote><blockquote><p>“How do you look at keywords?”</p></blockquote><blockquote><p>“I don’t!”</p></blockquote><h2 id="rina-henderson%3A-the-web.-why-do-i-like-it%3F" tabindex="-1"><a class="header-anchor" href="#rina-henderson%3A-the-web.-why-do-i-like-it%3F" aria-hidden="true">#</a><a href="https://www.linkedin.com/pulse/web-why-do-i-like-rina-henderson">Rina Henderson: The web. Why do I like it?</a></h2><blockquote><p>Believe it or not, the invention of the web was not to give me something to do when I grew up.</p></blockquote><h2 id="amberley-romo%3A-the-road-so-far%2C-pt-ii" tabindex="-1"><a class="header-anchor" href="#amberley-romo%3A-the-road-so-far%2C-pt-ii" aria-hidden="true">#</a><a href="http://amberley.me/2017/01/17/the-road-so-far-pt-ii/">Amberley Romo: The Road So Far, Pt II</a></h2><blockquote><p>I see power in the web for the very real capacity it has for good — communication and connection, access to communication, and on and on. And just like magic, it can be wielded in the interest of the light or the darkness (and those lines aren’t always the clearest). I want to do what I can to use it for good.</p></blockquote><h2 id="river-kanies%3A-why-i-chose-to-become-a-web-startup-consultant" tabindex="-1"><a class="header-anchor" href="#river-kanies%3A-why-i-chose-to-become-a-web-startup-consultant" aria-hidden="true">#</a><a href="https://medium.com/@river.kanies/why-i-chose-to-become-a-web-startup-consultant-28b059397fe2">river kanies: Why I chose to become a web startup consultant</a></h2><blockquote><p>I will never stop learning, and I will never stop putting myself out of my financial and intellectual comfort zone. I think that, ultimately, this attitude will lead me to be very successful, even if it means being dirt poor for the next few years :}</p></blockquote><h2 id="manuel-matuzovic%3A-this-is-not-a-new-year%E2%80%99s-resolution" tabindex="-1"><a class="header-anchor" href="#manuel-matuzovic%3A-this-is-not-a-new-year%E2%80%99s-resolution" aria-hidden="true">#</a><a href="https://medium.com/@matuzo/this-is-not-a-new-years-resolution-2c69d3a0ffeb">Manuel Matuzovic: This is not a New Year’s resolution</a></h2><blockquote><p>Web design and web development are not (just) about writing the most flexible, <em>reactive</em> and dynamic app, impressing colleagues and clients, and earning awards. First and foremost it’s about people using our products. I believe that from time to time we all need to be reminded of that fact.</p></blockquote><h2 id="max-b%C3%B6ck%3A-three-goals-for-2017" tabindex="-1"><a class="header-anchor" href="#max-b%C3%B6ck%3A-three-goals-for-2017" aria-hidden="true">#</a><a href="https://mxb.at/blog/three-goals-for-2017/">Max Böck: Three Goals for 2017</a></h2><blockquote><p>I can still remember what it was like to build my first website. I had absolutely no clue how to do stuff, it was all trial and error. But going back and forth between blogs, tutorials and stack overflow, watching other people work, shamelessly copying bits and pieces—I improved.</p></blockquote><blockquote><p>The fact that I can just hit <code>view source</code> on any website and see how it’s made still amazes me.</p></blockquote><blockquote><p>Altough I have a degree in web development now, I can honestly say that I learnt most of what I do by soaking up information available on the open web.</p></blockquote><blockquote><p>This is only made possible by lots of talented people who not only produce great work, but dedicate their time and energy to show others how to do it, too. I don’t know any other profession with such an open exchange of knowledge.</p></blockquote><blockquote><p>People from around the world actually work together on open-source projects, just to build something that others can use. Top developers in the field will share their latest findings publicly in carefully crafted tutorials and code examples on Github.</p></blockquote><blockquote><p>Think about how amazing that is—an entire industry where you can learn every last secret of the trade for free—all you need is dedication and an internet connection.</p></blockquote><h2 id="kyle-jones%3A-looking-ahead%E2%80%94and-to-the-side" tabindex="-1"><a class="header-anchor" href="#kyle-jones%3A-looking-ahead%E2%80%94and-to-the-side" aria-hidden="true">#</a><a href="https://kylejonestn.wordpress.com/2017/01/20/looking-ahead-and-to-the-side/">Kyle Jones: Looking Ahead—and to the Side</a></h2><blockquote><p>“Inter-Connectivity.” It’s a word I learned from an administrator at work. He challenged his team to reach out and reach through to other organizations. Organizations that are probably striving for the same goal that we are, but are too focused to look left or right to see others that are trying to do the same thing.</p></blockquote><blockquote><p>…</p></blockquote><blockquote><p>It’s why I love the web. The Internet seems to have a knack for inter-connectivity (hyperlinking, search results, purchase recommendations, @mentions, etc). It doesn’t come as naturally for humans at times. It takes risking assumptions and being intentional. Sometimes we need more of that spiderweb mentality and reach out, not just up or down. My administrator was telling us that, yes, we do a great work, but don’t be blinded to think we’re the only ones. Just imagine what good we could do together with more partners that don’t exactly look or function just like us.</p></blockquote><h2 id="ste-grainer%3A-seeking-mentorship" tabindex="-1"><a class="header-anchor" href="#ste-grainer%3A-seeking-mentorship" aria-hidden="true">#</a><a href="https://stegrainer.com/journal/2017/looking-for-a-mentor">Ste Grainer: Seeking Mentorship</a></h2><blockquote><p>I started making websites in the mid-90s when I was still in high school. I was fascinated that I could put something up on the web and people anywhere in the world could see it if they knew where to look. That feeling still inspires me, even after 20 years.</p></blockquote><h2 id="ivan-zusko%3A-mentor%3A-be-or-not-to-be" tabindex="-1"><a class="header-anchor" href="#ivan-zusko%3A-mentor%3A-be-or-not-to-be" aria-hidden="true">#</a><a href="https://medium.com/@IvanZusko/mentor-be-or-not-to-be-120b29d49be7">Ivan Zusko: Mentor: Be or not to be</a></h2><blockquote><p>Every time you are revising your knowledge and things you used to accept as ‘it is so simply because it is so’. And very often can happen that during a process of your professional evolution (in fact does not matter what kind of profession you belong to), you were missing some obvious details which could make your present life as the established professional much easier. The most trivial question can open your eyes on some hidden secrets which were escaping from your attention just because there were dozens and dozens of the different and the more interesting things that seemed more important at that time.</p></blockquote><h2 id="joanne-daudier%3A-how-i-got-started-in-tech" tabindex="-1"><a class="header-anchor" href="#joanne-daudier%3A-how-i-got-started-in-tech" aria-hidden="true">#</a><a href="https://medium.com/@jdaudier/how-i-got-started-in-tech-my-developer-origin-story-7d95ee249b06">Joanne Daudier: How I Got Started in Tech</a></h2><blockquote><p>What I love about being a developer is that I’m always learning something new and meeting other more senior devs that are so willing to lend a helping hand to newbies.</p></blockquote><h2 id="tyler-malone%3A-state-of-a-career" tabindex="-1"><a class="header-anchor" href="#tyler-malone%3A-state-of-a-career" aria-hidden="true">#</a><a href="https://medium.com/@tylermalone/state-of-a-career-b53ef3a9e53a">Tyler Malone: State of a Career</a></h2><blockquote><p>I love what I do now because my experience in development has been diametrically opposed to that previous job. Solutions to problems are almost never a 1:1 ratio, collaboration is embraced, the pursuit of continual learning is highly encouraged, and the communities I’ve been a part of have been thoroughly supportive.</p></blockquote><h2 id="tabassum-mohamed-fakier%3A-career-goals" tabindex="-1"><a class="header-anchor" href="#tabassum-mohamed-fakier%3A-career-goals" aria-hidden="true">#</a><a href="http://tabassum.com/blog/day-16-career-goals">Tabassum Mohamed Fakier: Career goals</a></h2><blockquote><p>I thought this was going to be difficult to answer, but it’s actually quite simple - albeit long-winded. I love the immense potential it represents; allowing people to help themselves, allowing people to help others directly, fostering connections in lieu of constant personal contact, delivering new experiences, helping people do good things for free - I could go on. There are just so, so, so many reasons why the web is important. The web extends beyond just websites for me: I used it as a crutch to overcome social anxieties and excessive shyness. I taught myself how to code using resources my parents would not afford on paper. I expressed myself. I entertained myself. I made friends when it was difficult for me to maintain friendships at school - and some of these individuals are close friends of mine seven years later. Heck, the web even introduced to me to my soulmate who is with me in Australia. I loved being on the web and I always wanted to be a creator on it.</p></blockquote><blockquote><p>There are so many lines being crossed for the sake of monetisation, for the sake of control, and I want this to change. Ultimately, I really want to give back in honour of the faceless strangers that made a lot of my life happen the way it did. The web should be better for everyone.</p></blockquote><h2 id="brian-bell%3A-the-puddle-jumper" tabindex="-1"><a class="header-anchor" href="#brian-bell%3A-the-puddle-jumper" aria-hidden="true">#</a><a href="http://brianbell.me/2017/the-puddle-jumper/">Brian Bell: The Puddle Jumper</a></h2><blockquote><p>As a kid, I rarely played with a toy the same way twice. When I got older I spent my waking hours flipping, spinning, and grinding at the skatepark. In school, I pursued graphic design. A few months into my first nine-to-five, I discovered the web.</p></blockquote><blockquote><p>Every decision along the way was made with that question top-of-mind, <em>“What else can I do with this?”</em></p></blockquote><h2 id="todd-libby%3A-mentoring" tabindex="-1"><a class="header-anchor" href="#todd-libby%3A-mentoring" aria-hidden="true">#</a><a href="http://six03.com/2017/mentoring/">Todd Libby: Mentoring</a></h2><blockquote><p>I want to keep learning until my children send me into a home, or even when I finally take that dirt nap I hear about.</p></blockquote><hr><p>I truly wish I could mentor all of these folks this year, but I’m only one guy with a day job and a family I’d like to see on occasion. This is going to be one heck of a tough choice. I’d like to take a moment to thank each and every one of these folks (and all of the other applicants) for sharing their stories and their goals with me, with <strong>us</strong>.</p><p>I urge you to read their posts and maybe write one of your own.</p><hr class="footnotes-sep"><section class="footnotes"><h4 class="hidden">Footnotes</h4><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>In other words, there were so many great applications that this will buy me some more time to make my decision :-) <a href="#fnref1" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content><amg:summary><![CDATA[The applicants for my mentorship program shared some amazing stories, anecdotes, and experiences in their posts on why they love the Web and I wanted to take a moment to share them with you]]></amg:summary><summary type="html"><![CDATA[<p>The applicants for my mentorship program shared some amazing stories, anecdotes, and experiences in their posts on why they love the Web and I wanted to take a moment to share them with you</p>]]></summary><category term="mentoring" /><category term="the web" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/the-web-is-messy-and-beautiful/</id><title type="html"><![CDATA[✍🏻 The Web is Messy and Beautiful]]></title><link href="https://www.aaron-gustafson.com/notebook/the-web-is-messy-and-beautiful/" rel="alternate" type="text/html" /><published>2016-07-14T15:17:32Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>In two back-to-back, potentially <abbr aria-label="Not Safe for Work">NSFW</abbr> posts discussing web development vs. platform-specific development, Eran Hammer covered a lot of the pain points encountered in each. For instance, on the Web, you’ve got rendering and user interface inconsistencies between browsers. On the other hand, retention for apps is notoriously crappy.</p><p>Toward the end of his second piece, Eran nailed my long-time contention in this quasi-fictional war between the Web and native:</p><blockquote><p>It’s never really app vs native. It’s a complicated tradeoff between multiple factors and no matter how much you read about it, how many statistics you collect, how many experts you talk to, you will still have to figure it out on your own, based on the specific properties of the experience you are building. And keep evaluating your decisions.</p></blockquote><p>As with everything, the right choice often depends on a variety of factors, many of which are likely to change.</p><p>In the end, I typically fall down on the side of the Web because I find its “messy” nature to be one of its great strengths. The Web is malleable and capable of being different things for different people. This flexibility allows it to travel further and empower more people than platform-specific apps ever will. I guess that’s why I am so stoked about progressive web apps too. When done well, they enable useful tools to go further and reach more people while providing many of the benefits of an installed application. If they’re successful, they really could be the best of both worlds.</p><p>Anyway, both posts are well worth a read:</p><ul><li><a href="https://web.archive.org/web/20160610075155/https://hueniverse.com/2016/06/08/the-fucking-open-web/">The Fucking Open Web</a></li><li><a href="https://web.archive.org/web/20160703011716/https://hueniverse.com/2016/06/20/the-open-web-fuck-yeah/">The Open Web, Fuck Yeah!</a> (the rebuttal)</li></ul><p><em>Note: I no longer use “native” in this context, but it remains in quoted material.</em></p>]]></content><amg:summary><![CDATA[As with everything, the decision to go Web or platform-specific often depends on a variety of factors, many of which are likely to change.]]></amg:summary><summary type="html"><![CDATA[<p>As with everything, the decision to go Web or platform-specific often depends on a variety of factors, many of which are likely to change.</p>]]></summary><category term="progressive enhancement" /><category term="the web" /><category term="progressive web apps" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/avoiding-linkrot-in-print-with-the-help-of-perma-dot-cc/</id><title type="html"><![CDATA[✍🏻 Avoiding Link Rot in Print with the Help of Perma.cc]]></title><link href="https://www.aaron-gustafson.com/notebook/avoiding-linkrot-in-print-with-the-help-of-perma-dot-cc/" rel="alternate" type="text/html" /><published>2015-12-02T21:03:35Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>I think we can all agree, <a href="https://en.wikipedia.org/wiki/Link_rot">link rot</a> is a problem. A 2014 study by Harvard Law School determined that <a href="http://journals.cambridge.org/action/displayAbstract?fromPage=online&amp;aid=9282809&amp;fileId=S1472669614000255/">roughly 50% of the URLs referenced in U.S. Supreme Court opinions no longer work</a>. That’s <em>terrifying</em>.</p><p>When I was mid-way through writing <a href="http://adaptivewebdesign.info/2nd-edition/">the Second Edition of <cite>Adaptive Web Design</cite></a>, I realized that it was pretty likely some of the links I was referencing might disappear over the years. Little did I know, some of them would disappear <em>while I was writing the book!</em></p><p><a href="https://archive.org/web/">The Internet Archive’s Wayback Machine</a> is pretty good, but it doesn’t archive everything, and I often find captured pages end up broken—especially if they rely heavily JavaScript, but often images go missing as well. I wanted to make sure that when you pick up the book a year from now or even 10 years from now, the links will still work.</p><p>I evaluated a few options for creating a permanent archive of each and every link in the book (there are over 200), but then it dawned on me that <a href="https://perma.cc/">Perma.cc</a> might be the perfect answer.</p><p><a href="http://Perma.cc">Perma.cc</a> was created by the <a href="http://librarylab.law.harvard.edu/">Harvard Library Innovation Lab</a> in reaction to the paper I mentioned earlier. It is a distributed archive of URLs for scholarly and legal documents, supported not only by Harvard, but over 90 (<em>and counting!</em>) libraries, distributed all over the world. <a href="https://github.com/harvard-lil/perma">It’s also open source</a>. Each <a href="https://perma.cc/docs#archive-formats">URL is preserved as a live view, an archived view, and a screen capture</a> taken when the link is added. Archived URLs are kept for a minumum of 2 years, but <a href="https://perma.cc/docs#vesting-links">may be “vested” into the permanent archive by a member organization</a>.</p><p>I had contributed some CSS to the project a while back, so I reached out to my contacts to see if they might be interested in vesting all of the links for the book. Turns out they were big fans of <a href="http://adaptivewebdesign.info/1st-edition/">the First Edition</a> and enthusiastically offered their support.</p><p>Converting all of the links took time (and a lot of double- and triple-checking), but the result is that every article, blog post, and web page that I referenced in the book will remain accessible to you in perpetuity. I think that’s pretty awesome. And, as an added bonus, since <a href="http://Perma.cc">Perma.cc</a> creates unique URLs that are relatively short, those of you who read it in print won’t have to re-type the often incredibly-lengthy original URLs.</p><p>I can’t thank <a href="http://mattphillips.info/">Matt Phillips</a>, <a href="https://twitter.com/abziegler">Adam Ziegler</a>, <a href="http://jackcushman.org/">Jack Cushman</a>, and everyone else at the Harvard Library Innovation Lab enough for creating <a href="http://Perma.cc">Perma.cc</a><em>and</em> for offering their service to my readers. You all are amazing!</p>]]></content><amg:summary><![CDATA[When I was mid-way through writing the Second Edition of Adaptive Web Design, I realized that it was pretty likely some of the links I was referencing might disappear over the years.]]></amg:summary><summary type="html"><![CDATA[<p>When I was mid-way through writing the Second Edition of Adaptive Web Design, I realized that it was pretty likely some of the links I was referencing might disappear over the years.</p>]]></summary><category term="the future" /><category term="the web" /><category term="URLs" /><category term="user experience" /><category term="writing" /><category term="hazards" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/ramblings-on-new-browser-features-interoperability-craft-and-the-future-of-the-web/</id><title type="html"><![CDATA[✍🏻 Ramblings on New Browser Features, Interop&shy;erability, Craft, and the Future of the Web]]></title><link href="https://www.aaron-gustafson.com/notebook/ramblings-on-new-browser-features-interoperability-craft-and-the-future-of-the-web/" rel="alternate" type="text/html" /><published>2015-08-07T14:14:23Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>Last week <a href="http://www.quirksmode.org/about/">Peter-Paul Koch (PPK)</a> posted <a href="http://www.quirksmode.org/blog/archives/2015/07/stop_pushing_th.html">a lengthy treatise on why browsers should stop “pushing the web forward”</a>. I thoroughly enjoyed the read and agree with him on a number of points. I also agreed with the well-articulated responses from <a href="https://jakearchibald.com/2015/if-we-stand-still-we-go-backwards/">Jake Archibald (of Google)</a> and <a href="https://dev.opera.com/blog/on-a-moratorium-on-new-browser-features/">Bruce Lawson (of Opera)</a>. I guess I’m saying I see both sides. Like <a href="http://chriscoyier.net/">Chris Coyier</a>, I live in <a href="https://css-tricks.com/the-gray-gray-ghost-that-i-call-home/">a world filled with varying shades of grey</a> rather than stark black &amp; white.</p><h2 id="new-features-vs.-interoperability" tabindex="-1"><a class="header-anchor" href="#new-features-vs.-interoperability" aria-hidden="true">#</a> New Features vs. Interoperability</h2><p>One of the arguments PPK makes is against browsers competing on features. It really rang true to me:</p><blockquote><p>I call for a moratorium on new browser features of about a year. Let’s postpone all completely new features that as of right now don’t yet work in any browser.</p><p>Browsers are encouraged to add features that are already supported by other browsers, and to write bug fixes. In fact, finding time for these unglorious but necessary jobs would be an important advantage of the moratorium. As an added bonus it would decrease the amount of tools web developers need.</p></blockquote><p><a href="/notebook/competing-on-chrome/">Back in January</a>, I wrote about how I was excited by Microsoft’s announcement of “Project Spartan” (now “Microsoft Edge”) and it’s focus on interoperability. Interoperability’s a long word, so I’m gonna go with “interop” from here on out.</p><p>I was not on the Microsoft payroll at the time, but I was still stoked to see their focus on interop in the new rendering engine. They’d even gone, in my humble opinion, above and beyond in this regard—aliasing Webkit’s experimental, legacy CSS syntaxes to their modern, standards-based implementations. This ensured poorly coded sites worked well in their browser and didn’t penalize users for a designer’s mistake. Talk about being a good web citizen!</p><p>Of course, Microsoft Edge wasn’t the first browser to do this. <a href="http://snook.ca/archives/html_and_css/vendor-prefixes-competing">IE 7 Mobile implemented <code>-webkit-text-size-adjust</code> back in 2010</a>. <a href="https://dev.opera.com/articles/opera-mobile-emulator-webkit-prefix-support/">Opera</a> and <a href="https://wiki.mozilla.org/Platform/Layout/CSS_Compatibility#questions_and_methodology">Mozilla</a> also <a href="https://lists.w3.org/Archives/Public/www-style/2012Feb/0313.html">felt the pressure</a> and eventually implemented <code>-webkit-</code> vendors prefixes in versions of their browsers. It’s a weird world when one browser vendor is forced to implement another’s proprietary syntax just to make the web work, but it’s the sad state of things in our <a href="http://christianheilmann.com/2015/07/17/the-full-stackoverflow-developer/">full StackOverflow development</a> world.</p><p>With the move away from vendor prefixes in CSS to <a href="http://www.howtogeek.com/139736/how-to-change-hidden-advanced-settings-in-any-browser/">“feature flags”</a>, you’d think this sort of thing would be behind us, but it’s not. <a href="http://www.otsukare.info/">Karl Dubost</a>, of Mozilla, recently <a href="http://www.otsukare.info/2015/07/29/vendor-prefixes-market">bemoaned the implications of Apple’s latest vendor prefix silliness</a> on his blog. In that post, he made a keen observation:</p><blockquote><p>We have reached the point where browser vendors have to start implementing or aliasing these WebKit prefixes just to allow their users to browse the Web, see <a href="https://wiki.mozilla.org/Compatibility/Mobile/Non_Standard_Compatibility">Mozilla</a> in Gecko and <a href="https://twitter.com/jacobrossi/status/614544147941355520">Microsoft</a> in Edge. The same thing is happening over again. In the past, browser vendors had to implement the quirks of IE to be compatible with the Web. As much as I hate it, we will have to specify the current <code>-webkit-</code> prefixes to implement them uniformly.</p></blockquote><p>I completely understand PPK’s desire for browsers to apply the brakes a bit and focus on interop. With new features being added to “the web”—but in reality only browser X, Y, or Z—on the regular, without guaranteed interop, it feels like we’re stirring up the browser wars again. All the new shiny is exciting, but I lived through the browser wars the first time and they sucked for everyone involved. <span data-quotable>Web standards helped us get everyone on the same page and brokered what we’d hoped was going to be a lasting peace.</span></p><p>Now I’m not sure I agree with applying the brakes for a specific amount of time, but I do see great value in prioritizing interop over new features. And when browsers do implement new features, they should definitely put them behind feature flags (or some similar opt-in) to ensure we—the web development community—don’t start relying on some fancy new feature before it’s been vetted. Feature flags are awesome because they allow me, a designer, to experiment with a new technology <em>in my own browser</em> without affecting things for everyone else on the open web.</p><p><a href="http://alistapart.com/article/prefix-or-posthack">We used to think vendor prefixes were enough of a deterrent</a> to using a particular experimental CSS property or JavaScript method. Sadly that’s turned out to not be the case. I would bet good money on the sad reality that 80% of the working web designers out there don’t understand that <code>-*-</code> means “experimental” or even “proprietary”. We—the web design authors, speakers, educators, and other influencers—did a shitty job landing that message with the industry as a whole. But even if we’d hounded people about it, it probably wouldn’t have mattered: Vendor-prefixed properties work. And now they work even in browsers they were never meant to.</p><p>So, here’s what I’d love to see browser vendors do:</p><ol><li>Prioritize interop over new features. Don’t halt development on new features, just put them on the back burner so the rising tide can, as they say, lift <em>all</em> the ships. Web developers and end users all benefit when there’s feature parity and stability among browsers.</li><li>Put a ban on vendor-prefixes. They are not generally understood to be experimental. If you feel you must use a vendor prefix, ensure it’s only enabled by a corresponding feature flag.</li><li>Use feature flags (or some similar opt-in) to enable developers to test experimental features in their own browsers, but also to ensure they aren’t available on the “open web” before they’re ready.</li></ol><h2 id="the-web-vs.-platform-specific-development" tabindex="-1"><a class="header-anchor" href="#the-web-vs.-platform-specific-development" aria-hidden="true">#</a> The Web vs. Platform-Specific Development</h2><p>PPK has harped on this a few times. There is currently a palpable tension between platform-specific development and the web. It’s driving most of the new features in the web “platform”<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup> and it’s giving many of us old-timers a touch of angina.</p><p>The reason is simple: The web was created as a massively interconnected document repository. A wealth of knowledge dependent on the hyperlink and the URL. The web was (and indeed still is) stateless by default, meaning it has no idea who you are or what you’ve done from request to request. This is very egalitarian: everyone has access and anyone can contribute.</p><p>As more businesses moved online, the web became necessarily transactional. Suddenly websites needed to know information about your “state” so they could sell you things and track your movements around their site and the rest of the web. With the advent of cookies and the Common Gateway Interface (CGI), a web server could adjust the content it sent in response to a request, based on what it knew about you and what you were doing.</p><p>Taking this simple capacity a step further, it became possible to write actual software on the web. Content management systems were probably the first big chunk of software to move online, but more soon followed. JavaScript came along and allowed us to add a bit of logic to the client side, reducing our reliance on round-trips to the server. Then we got Ajax and the whole JavaScript world exploded. We now have web-based photo editors, integrated development environments (IDEs), games, and more, all reliant on JavaScript’s ability to interact with the browser and manipulate what the user sees in real-time.</p><p>There were earlier machinations certainly, but the last ten years have seen the biggest push to bring more traditional software-like interactions to the web. Dozens of organizations, big and small, are trying to make their mark creating <em>the</em> framework for building these “next-generation” web-based app experiences. Honestly, I don’t have a problem with that. I don’t really have an interest in client-side frameworks, but I don’t have a problem with them either… provided developers who wish to bring their programming talents to the web take a little time to learn about the medium.</p><p><span data-quotable>If you don’t take the time to understand how the web works, you’ll spend half your time cursing it and the other half trying to work around the things that frustrate you (which you will probably write off as “poorly designed” or “ill-conceived”).</span> If you don’t understand how the web works, you’ll build fragile experiences that collapse like a house of cards when any one of your many dependencies—the network, JavaScript, some particular element or browser API—isn’t available. If you don’t understand how the web works, what you build will simply be <a href="https://adactio.com/journal/8245">on the web, not of it</a>.</p><p>I don’t particularly care much about bringing “native like” experiences to the web. It’s not that I don’t write software (I do), I just don’t really care if something I make for the web feels like a piece of installed software. I’ll do everything in my power to ensure my users have a great experience, but I know that each person’s experience will be a little bit different and I no longer feel the need to enforce my will on their experience. I’d rather create many ways for someone to interact with the things I build and hope one or more of those work well for whoever happens by and whatever device they happen to be using.</p><p>Platform-specific software and the web have always co-existed. We had installed software on computers long before the web even existed and we will continue to have installed software for as long as there are computers. Some software will move to the web if it makes sense for it to do so. Other software will remain platform-specific. Either option could be right or wrong depending on what you are trying to do. For instance, I would never personally write a photo editor in the browser because image processing requires a lot of memory and CPU cycles. Putting it in a browser moves it one more level away from the hardware. Abstraction eases development, but it invariably increases overhead and reduces performance.</p><p>Traditional software and the web can and should co-exist. They also can and should continue to inform one another. Ultimately, that will help us better serve the needs of our users, however they use our creations.</p><h2 id="change-vs.-stagnation" tabindex="-1"><a class="header-anchor" href="#change-vs.-stagnation" aria-hidden="true">#</a> Change vs. Stagnation</h2><p>Underpinning this whole “platform-specific vs. web” thing is, I think, a feeling many of us old-timers have that our web—the web we grew up building—is slipping away from us. We cling to the idea of the web as an open platform<sup class="footnote-ref"><a href="#fn2" id="fnref2">2</a></sup> for people to share their thoughts, passions, and cat photos. We like the web as it was originally. We like the web as we made it.</p><p>The web is changing. In some ways it’s changing for the better, in some ways for the worse. It’s a far different beast today than <a href="http://info.cern.ch/hypertext/WWW/TheProject.html">when Tim Berners-Lee typed that first <code>&lt;HEADER&gt;</code></a> and you can certainly do a lot more in the browser now than you could when I first picked up HTML. But I don’t think halting progress on the web is desirable.</p><p>As Jake points out in his response, stagnation is not a good policy. Stagnation pretty much killed BlackBerry. It also led to a lot of developer frustration in the guise of IE 6.</p><p>Change is not inherently bad. It’s pace can be quite frustrating at times, though. PPK certainly seems to be feeling that way about its speed now just as <a href="https://infrequently.org/2007/09/slides-from-my-standards-heresy-talk/">Alex Russell lamented its plodding progress back in 2007</a>. But when you take a step back, especially with a historical perspective, you see the changes are cyclical in many ways. The bandwidth issues we dealt with during the dial-up era are with us again in the form of mobile networks. The lessons we learned building a web for 640x480 screens are equally applicable in a world of wearables. And the text-based interactions we created in the very early days will serve as a template as we move boldly forward into the realm of voice-driven user experiences.</p><h2 id="cutting-edge-vs.-craft" tabindex="-1"><a class="header-anchor" href="#cutting-edge-vs.-craft" aria-hidden="true">#</a> Cutting Edge vs. Craft</h2><p>In his post, PPK also complained that we’re simply getting too many new features on the web, which makes it hard to keep up. More than that, however, it makes it hard to truly come to a deeper understanding of how these different pieces work. To really hone our craft. In other words, it’s becoming harder to be an expert generalist.</p><p>Jake and Bruce completely get this, as do I. <a href="https://web.archive.org/web/http://lanyrd.com/2015/web-design-day/sdpbgz/">Lyza Danger Gardener has even given an amazing talk on the topic</a>. The sheer volume of new drafts, specs, and concepts (not to mention tooling options) is overwhelming. I’m sure I don’t know half of the features that are in the HTML5 spec, let alone the umpteen CSS3 modules. I probably never will. And I’m ok with that. I’ll pick and choose the bits I’m interested in playing around with and find ways to integrate them into my practice a little at a time. That’s how we learn. That’s how we’ve always learned.</p><p>To assuage PPK’s fears, however, I would argue that there are a lot more of us working on the web now than there were in the more leisurely paced days he remembers so fondly. And we’re sharing what we learn. Whether driven by altruistic desire to spread knowledge or an interest in rockstar-like fame in the industry (or even a smidge of both), it doesn’t really matter how it happens—the fact is that it does. We learn and we share. And the tools we have today make it even easier to do so. Not only do we have the usual magazine and blogging outlets, but we also have CodePen and JS Bin and Github and more.</p><p>We each have the capacity to research the hell out of one specific area of web design and be the conduit for that knowledge into the web design hive mind. Look at <a href="https://www.google.com/search?q=sara+soueidan+svg">Sara Soueidan with SVG</a> or <a href="https://www.google.com/search?q=rachel+nabors+css+animation">Rachel Nabors with CSS Animation</a> or <a href="https://www.google.com/search?q=Zoe+Mickley+Gillenwater+flexbox">Zoe Mickley Gillenwater with flexbox</a>. <span data-quotable>Individually, we will never be able to learn it all, but collectively we can.</span> Together, we can tackle any problem by accessing what we need to know when we need to know it.</p><h2 id="developer-convenience-vs.-user-needs" tabindex="-1"><a class="header-anchor" href="#developer-convenience-vs.-user-needs" aria-hidden="true">#</a> Developer Convenience vs. User Needs</h2><p>Another angle in this very dense piece from PPK was around tooling and polyfills:</p><blockquote><p>We get ever more features that become ever more complex and need ever more polyfills and other tools to function—<a href="http://www.quirksmode.org/blog/archives/2015/05/tools_dont_solv.html">tools that are part of the problem</a>, and not of the solution.</p></blockquote><p>The whole “polyfill it and move on” movement has him a little annoyed. I share his sentiment. I don’t think a JavaScript-based solution should be considered “good enough” for interop. <a href="http://kryogenix.org/code/browser/everyonehasjs.html">JavaScript is not guaranteed.</a> Moreover, JavaScript implementations are also never going to be as fast as a browser implementation. If browsers want to pick up a polyfill and implement it behind the scenes, that’s fine because it will run faster, but loading up our websites with potentially megabytes worth of polyfills in order to use new “standards” seems ludicrous.</p><p>As an industry, we are doing an awful lot of navel gazing. <span data-quotable>We are spending more time solving our own development problems (legitimate in some cases, fabricated in others) by throwing more and more code at the problem.</span> As a consequence, our users are paying the price in <a href="http://www.theverge.com/2015/7/20/9002721/the-mobile-web-sucks">slower sites</a>, <a href="http://www.soasta.com/blog/page-bloat-average-web-page-2-mb/">heavier web pages</a>, <a href="http://www.yottaa.com/Why-Your-Website-Is-Slow-Poor-JavaScript-Performance">poor performance</a>, and <a href="https://web.archive.org/web/20150213090118/http://farukat.es/journal/2015/02/708-how-flipboard-chose-form-over-function-their-web-version">bad experiences</a> (or <a href="http://sighjavascript.tumblr.com/">no experience</a>). And, on top of that, we’re solving <em>our</em> problems not <em>their</em> problems.</p><h2 id="all-is-not-lost" tabindex="-1"><a class="header-anchor" href="#all-is-not-lost" aria-hidden="true">#</a> All is not lost</h2><p>We are designers. Design is about solving problems for our users, not creating new ones for them. Whether we are writing code, sketching interfaces, authoring copy, curating content, or building servers, we should make each and every decision based on what will benefit our users. If it means we can’t use some shiny new technology, so be it. We can still play with the new stuff in our own browser, on our personal sites, and on CodePen. We can learn about them in our own experimentation and share that knowledge with the rest of our industry. We can improve our craft. The web can get better.</p><p><em>Note: I no longer use “native” in this context, but it remains in quoted material.</em></p><hr class="footnotes-sep"><section class="footnotes"><h4 class="hidden">Footnotes</h4><ol class="footnotes-list"><li id="fn1" class="footnote-item"><p>I think I just threw up in my mouth a little. I hate using that word when speaking about the web, but there it is. <a href="#fnref1" class="footnote-backref">↩︎</a></p></li><li id="fn2" class="footnote-item"><p>In the other sense of the word. <a href="#fnref2" class="footnote-backref">↩︎</a></p></li></ol></section>]]></content><amg:summary><![CDATA[A few thoughts and ramblings spurred by a post from PPK and reactions from Jake Archibald and Bruce Lawson.]]></amg:summary><summary type="html"><![CDATA[<p>A few thoughts and ramblings spurred by a post from PPK and reactions from Jake Archibald and Bruce Lawson.</p>]]></summary><category term="web design" /><category term="browsers" /><category term="the web" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/apple-vs-the-open-web/</id><title type="html"><![CDATA[✍🏻 Apple vs. the Open Web]]></title><link href="https://www.aaron-gustafson.com/notebook/apple-vs-the-open-web/" rel="alternate" type="text/html" /><published>2013-07-07T22:39:00Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>I’ll admit it: I never really got Siri.</p><p>To me, she’s always been a bit gimmicky. When she debuted on the iPhone 4S, I thought the voice recognition stuff was neat, but I didn’t see her as being anything close to the “digital assistant” Apple promised us. The idea was good, but the implementation was about as inspiring as my then 5-year-old Garmin. Oh, but she couldn’t give you turn by turn directions.</p><p>Sure, Siri’s gotten better, but not much.</p><p>Now, after reading <a href="https://twitter.com/dankaplan">Dan Kaplan</a>’s excellent TechCrunch post <a href="http://techcrunch.com/2013/06/30/will-apple-sideline-siri-before-she-kills-google/">lamenting the Siri that could have been</a>, I realize how much better she could—nay <em>should</em>—be. You see, prior to being bought by Apple, Siri Assistant was pretty damn useful. She was a true digital assistant, capable of setting up a whole evening of fun for you by purchasing movie tickets, getting you dinner reservations, and even hailing you a cab. Pre buy-out, her creators even had plans to supercharge Siri by giving her predictive awareness (think <a href="http://en.wikipedia.org/wiki/Google_Now">Google Now</a>). Dan offered a few examples of how this might work:</p><blockquote><ul><li><span class="initial quote">“</span>Hey Dan, your flight to NYC has just been canceled! Would you like me to book the next one?<span class="final quote">”</span></li><li><span class="initial quote">“</span>Hey Dan, you weren’t at home when your package got delivered. Would you like me to redirect it to your office?<span class="final quote">”</span></li><li><span class="initial quote">“</span>Hey Dan, you’ve got a coffee meeting downtown in 25 minutes. How about I summon a Lyft?<span class="final quote">”</span></li></ul></blockquote><p>Given Siri’s previous capabilities and the plans her creators had, how did she become so lame?</p><p>Personally, I think the reason is simple: Apple doesn’t get the web. Sure there are a lot of incredibly smart and talented people who work at Apple who clearly do understand what the web is and how it works, but I think as a company Apple doesn’t. Or worse it does, but they can’t control it or monetize it, so they’re not interested.</p><p>It’s a feeling I’ve had for quite some time, but reading this piece (especially in light of Jeremy Keith’s fantastic post about <a href="http://adactio.com/journal/6291/">the movement of many web companies toward creating more walled gardens</a>) really convinced me. I mean take a look at Maps.</p><p>Prior to iOS 6, Google Maps was the de-facto mapping and directions app. It offered your standard driving and walking directions, but it also offered public transit directions based on public data (much of which Google has coalesced into <a href="http://www.google.com/intl/en/landing/transit/">Google Maps Transit</a>). Now, with Apple’s homegrown Maps, if you want to get transit directions, you need to download a separate app from the App Store. Travel a lot? Try 8 differnet apps. Or 10.</p><p>Instead of using existing APIs to make transit directions native to Maps, they opted to fragment the experience.*</p><figure><img alt="" src="/i/posts/2013-07-07/ios-maps-transit.png"/><figcaption>A quick direction search using Maps and the resulting screen when I route via public transit.</figcaption></figure><p>Sure, you might argue that the Maps team may have had to cut the transit feature due to time or budget constraints, but they found the time to make the maps three-dimensional. Just sayin’.</p><p>Clearly Apple could have used any of the <a href="http://www.commuterapi.com/">publicly available transit APIs</a> to accomplish this task, but they didn’t. The same goes for Siri. There are a ton of freely-available resources out there to collect information and then do something useful with it—to truly allow Siri to become the digital assistant of our dreams—but Apple doesn’t seem to have any interest. And I think their software is suffering for it.</p><p>* I’m all for de-coupling functionality in order to scale application logic, but de-coupling (a.k.a. fragmenting) the user experience is downright baffling. Especially for a company that prides themselves on both design and user experience.</p>]]></content><amg:summary><![CDATA[I’ll admit it: I never really got Siri.]]></amg:summary><summary type="html"><![CDATA[<p>I’ll admit it: I never really got Siri.</p>]]></summary><category term="the web" /><category term="user experience" /><category term="philosophy" /></entry></feed>