<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Amy St. John</title>
    <description>The latest articles on Forem by Amy St. John (@thatamy).</description>
    <link>https://forem.com/thatamy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F6860%2F_RWq4qJz.jpg</url>
      <title>Forem: Amy St. John</title>
      <link>https://forem.com/thatamy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thatamy"/>
    <language>en</language>
    <item>
      <title>Dynamic Imports of JSON</title>
      <dc:creator>Amy St. John</dc:creator>
      <pubDate>Sun, 18 Aug 2019 23:38:00 +0000</pubDate>
      <link>https://forem.com/thatamy/dynamic-imports-of-json-ipl</link>
      <guid>https://forem.com/thatamy/dynamic-imports-of-json-ipl</guid>
      <description>&lt;h2&gt;
  
  
  TL:DR
&lt;/h2&gt;

&lt;p&gt;If you want to do a dynamic import of JSON with Webpack be sure to account for a JSON file not having a default export when you’re trying to extract the value and call &lt;code&gt;default&lt;/code&gt; on the returned module to return the whole JSON object.&lt;/p&gt;




&lt;p&gt;As someone who has been around the web development scene a long time and has often worked on large enterprise software that is behind the times, it can be hard to keep up to date with all the latest technology and trends when you don’t have opportunities to use it every day at work (and you have two small children at home to take care of). So I’ve been trying to find some extra time the last couple months to study up on all the tools that I’d be using at my new job and signed up for a &lt;a href="https://frontendmasters.com/" rel="noopener noreferrer"&gt;Front End Masters&lt;/a&gt; account to help me brush up.&lt;/p&gt;

&lt;p&gt;One of the tools I had used before but had never taken the time to fully understand was &lt;strong&gt;Webpack&lt;/strong&gt;. I had only used Webpack at one previous job and only for 4 months so I knew I wasn’t using it to its fullest potential, and recently I learned how to do &lt;strong&gt;dynamic imports&lt;/strong&gt; with Webpack and that was particularly exciting as someone who has specialized in front-end performance in the past. If you haven’t been introduced to dynamic imports yet it is helpful for solving performance issues by making sure you’re only serving up larger bundles of code when you actually need it, and it’s all &lt;a href="https://v8.dev/features/dynamic-import" rel="noopener noreferrer"&gt;regular JS under the hood&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Working with modern JS you often see static imports for modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;myLib&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./myLib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But dynamic imports aren’t grabbed from the server until runtime. Using Webpack and the dynamic import structure it creates a promise that will retrieve the chunk at runtime and allow you to act on it at that point. Simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This creates its own bundle chunk&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myLib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./myLib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;myButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Chunk only downloads at this point and then you react to it&lt;/span&gt;
  &lt;span class="nx"&gt;myLib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;libFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;libFunc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After learning about this through the video, reading documentation and examples, and practicing it on my own I really thought I got it and was excited to put it to use. I ended up with the perfect opportunity a few weeks later at work. We had some sample JSON data that was being used as an occasional fallback to show an example graph when customer data wasn’t available. However it was being loaded with a &lt;code&gt;() =&amp;gt; require('myData.json')&lt;/code&gt; statement. This was problematic because those large JSON files were being included in multiple other chunks instead of just one, and all these large files were being served up whether or not the sample data was even going to be used.&lt;/p&gt;

&lt;p&gt;Now of course there’s multiple ways you can solve that issue, and I certainly thought about just throwing the JSON onto the server and making a request for it when it was needed, but I wanted to make the minimal amount of changes possible and thought, “Why don’t we just turn this into a dynamic import?” So I quickly changed the &lt;code&gt;require&lt;/code&gt; into an &lt;code&gt;import&lt;/code&gt; and immediately saw the chunks change drastically— it was beautiful. The sample data files became their own chunks and those other giant chunks became much smaller. But I was having trouble accessing the information from those files, and there were a couple different reasons for that, but the one I want to focus on is the one that was so difficult to find the answer for, maybe because it seems so obvious in hindsight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON files don’t have a default export.&lt;/strong&gt; And because of the other problems I was experiencing with resolving the promise in a legacy React component, I was at first dealing with a pending promise in the debugger instead of being able to just easily see what Webpack was returning. So I spent a good amount of time searching the internet to try to figure out if there’s a special way you need to deal with JSON files when you are dynamically importing them and couldn’t initially even find examples of anyone doing dynamic imports of JSON files.&lt;/p&gt;

&lt;p&gt;So this was frustrating but I did eventually discover an example in an answer on StackOverflow that specifically showed what I needed and realized that this info needs to exist in more places on the internet. When you are dealing with a promise of a JSON file, you need to specifically be calling default on it, which is a key in the module object returned.&lt;/p&gt;

&lt;p&gt;Examples of just capturing the data object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt;&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;myData&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;myData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// or&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myData.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also worth noting that this isn’t the case if you’re using Parcel or dynamic imports outside of Webpack. In those cases the JSON will just be returned; which is part of why this was so confusing.&lt;/p&gt;

&lt;p&gt;So I’m hoping this will help anyone else who gets confused if they’re new to dynamic imports with Webpack and trying to work with JSON.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webpack</category>
      <category>react</category>
      <category>json</category>
    </item>
    <item>
      <title>Project: Is Alameda Exploding?</title>
      <dc:creator>Amy St. John</dc:creator>
      <pubDate>Fri, 17 Aug 2018 20:55:00 +0000</pubDate>
      <link>https://forem.com/thatamy/project-is-alameda-exploding-nag</link>
      <guid>https://forem.com/thatamy/project-is-alameda-exploding-nag</guid>
      <description>&lt;p&gt;I live on the island of Alameda in the San Francisco Bay area. We are bordered on our east side by the Oakland Coliseum and our west side by AT&amp;amp;T Park just directly across the water 3 miles away. When there are fireworks in either of these places we can hear them, and sometimes see them. On holidays we hear all the surrounding fireworks. We also get Blue Angels flying over and so on.&lt;/p&gt;

&lt;p&gt;In short, we’re used to hearing noises, and I usually turn to my husband and say, “Must be sportsball” and shrug. But a week and a half ago and we were hearing all kinds of fireworks, my husband said, “I wish there was just a site I could go to in order to verify why I’m hearing fireworks.” (It was the A’s winning a game.) Which in turn made me think of the site “Is Oakland on Fire?” and thought it’d be fun to make something simple like that.&lt;/p&gt;

&lt;p&gt;So this week I decided to quickly bang something out and got really excited to actually be working on a personal coding project for once, since I tend to not have a lot of time for my own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Holidays
&lt;/h2&gt;

&lt;p&gt;I figured Sinatra would be perfect to quickly get something up and running since it’s only a one page site, and then started out by looking into any plugins or API’s that would easily give me a list of holidays. Since I really only care about the ones that have fireworks, I could have hard coded the information but really wanted the site to be as automated and easily maintainable as possible. I ended up finding &lt;a href="https://github.com/holidays/holidays" rel="noopener noreferrer"&gt;this Holidays Ruby gem&lt;/a&gt; which was perfect for what I needed. It makes it easy to also check if there are any fireworks holidays that week, since for Independence Day we tend to hear things in the days before and after, even though they’re technically illegal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;FIREWORK_HOLIDAYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="s2"&gt;"Independence Day"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"New Year's Eve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"Lunar New Year's Day"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"The second day of Lunar New Year"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"The third day of Lunar New Year"&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_holidays&lt;/span&gt;
  &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt; &lt;span class="s2"&gt;"Checking Holidays"&lt;/span&gt;
  &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;
  &lt;span class="n"&gt;holidays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Holidays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:us&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:hk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# Might be the week of Independence Day, etc&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;holidays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;Holidays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any_holidays_during_work_week?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;holidays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Holidays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next_holidays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:us&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:hk&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# We only care about the holidays that might have explosions&lt;/span&gt;
  &lt;span class="n"&gt;holidays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;holiday&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;holiday&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;detect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;hol&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;FIREWORK_HOLIDAYS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There might be some additional holidays to add, but I’m going to wait to expand it. Also since holidays don’t regularly change, I will be adding caching soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sports
&lt;/h2&gt;

&lt;p&gt;Then I figured the most heavy duty part was going to be finding the information about the sports games. I assumed I was going to need to use web scraping to get the information and started setting up &lt;a href="http://www.nokogiri.org/" rel="noopener noreferrer"&gt;Nokogiri&lt;/a&gt; and &lt;a href="https://github.com/jnunemaker/httparty" rel="noopener noreferrer"&gt;HTTParty&lt;/a&gt;. I quickly realized, however, that all the websites I wanted information from use JavaScript to load the information in after the initial page load. I haven’t done much web scraping before and did some research about how to address this and quickly came across &lt;a href="https://gohighbrow.com/scraping-javascript-heavy-websites/" rel="noopener noreferrer"&gt;this page&lt;/a&gt; that mentions just accessing the urls that are bringing in the information, since JavaScript is usually accessing JSON anyway before manipulating it on the front-end. Of course I read this and went, “Oh duh, that’s way more straightforward.”&lt;/p&gt;

&lt;p&gt;So I found the behind the scenes URL’s on all the sports sites and ditched Nokogiri, since it was completely unnecessary, and just started looking through all the JSON being returned to find the information that I needed for my purposes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Scraper&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:check_for_games&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;grab_page_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"Athletics"&lt;/span&gt;
      &lt;span class="no"&gt;HTTParty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseball_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"531221"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"Giants"&lt;/span&gt;
      &lt;span class="no"&gt;HTTParty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;baseball_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"531220"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"Warriors"&lt;/span&gt;
      &lt;span class="no"&gt;HTTParty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basketball_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;winning_baseball_game?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dates"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;

    &lt;span class="n"&gt;home_game&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;simple_date&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="no"&gt;VENUE_NAMES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"games"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;"venue"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;home_game&lt;/span&gt;

    &lt;span class="n"&gt;night_game&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"games"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dayNight"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"night"&lt;/span&gt;
    &lt;span class="n"&gt;is_winner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"games"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"teams"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;"home"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;"isWinner"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;home_game&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;night_game&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;is_winner&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_for_games&lt;/span&gt;
    &lt;span class="n"&gt;games&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="no"&gt;SPORTS_TEAMS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Checking site for &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

      &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;grab_page_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"Warriors"&lt;/span&gt;
        &lt;span class="n"&gt;home_game&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"games"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;detect&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"home"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;simple_date&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;games&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;home_game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;games&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;winning_baseball_game?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;games&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that was basically it. I put it up on Heroku and then started fiddling with it to make it faster. I ended up adding IronCache to store the results after the JSON had been retrieved and parsed, which was the biggest bottleneck.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;It’s a bit of a frivilous project, but it was fun. Here are some of the variations of what you might see.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Famy-mac.com%2Fimages%2Falameda_exploding1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Famy-mac.com%2Fimages%2Falameda_exploding1.jpg" alt="No idea, it's either in your head or it could be Armageddon" width="" height=""&gt;&lt;/a&gt; &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Famy-mac.com%2Fimages%2Falameda_exploding2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Famy-mac.com%2Fimages%2Falameda_exploding2.jpg" alt="Probably because it's Independence Day" width="" height=""&gt;&lt;/a&gt; &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Famy-mac.com%2Fimages%2Falameda_exploding3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Famy-mac.com%2Fimages%2Falameda_exploding3.jpg" alt="The Giants are playing tonight and just won" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the future I will probably add some checks for whether it’s Fleet Week, and other such loud disturbances to expand it. Hope the Alamedans enjoy it! You can check out the &lt;a href="http://isalamedaexploding.com" rel="noopener noreferrer"&gt;live site&lt;/a&gt; or view the &lt;a href="https://github.com/amy-mac/alameda_exploding" rel="noopener noreferrer"&gt;project on Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>sinatra</category>
      <category>ruby</category>
    </item>
    <item>
      <title>A Sort of Love Letter to HTML</title>
      <dc:creator>Amy St. John</dc:creator>
      <pubDate>Mon, 01 Jan 2018 17:00:00 +0000</pubDate>
      <link>https://forem.com/thatamy/a-sort-of-love-letter-to-html-45g8</link>
      <guid>https://forem.com/thatamy/a-sort-of-love-letter-to-html-45g8</guid>
      <description>&lt;p&gt;&lt;a href="https://xkcd.com/1144/" rel="noopener noreferrer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CSDGSWTF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://imgs.xkcd.com/comics/tags.png" title="&amp;lt;A&amp;gt;: Like &amp;lt;/a&amp;gt;this. " alt="XKCD Comic" width="451" height="57"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve been studying HTML since 1999, and like everything else it has grown and advanced over time, and I’m still learning new things you can do with it all the time. Unfortunately it tends to be one of the under-appreciated parts of web development, especially for those coming from a background of backend development. I want to explain some of the major points about why it is worth all developers time to fully understand it in order to have a more effective front-end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;We can all agree that we want our websites to be fast, right? One of the ways you can do that is by simply reducing the amount of DOM nodes on a page, or in other words, using less HTML elements. But wait, didn’t I just say, “Yay! HTML is the best! HTML for life!” Truth, but less is more. You want to use HTML &lt;em&gt;effectively&lt;/em&gt;, and just like we don’t want a bunch of messy spaghetti JavaScript around, we need to respect the structure of the page and be strident about using the best tool for the job as you build the foundation of each page.&lt;/p&gt;

&lt;p&gt;Here’s why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The more DOM nodes you have, the longer it takes to download that page from the server. HTML usually isn’t responsible for the major chunk of page load time, that award tends to go to images and scripts, but every little bit counts!&lt;/li&gt;
&lt;li&gt;CSS has to parse the entire DOM to figure out where it needs to apply the styles, and of course CSS performance in itself is a huge topic we won’t get into. The point is that the less unnecessary HTML elements on the page, the less work the stylesheets have to do, which results in better performance.&lt;/li&gt;
&lt;li&gt;Likewise, when you are querying the DOM in JavaScript or jQuery, the more DOM nodes you have, the harder it has to work to find the element you want. This is why developers tend to save the queried element into a variable when they’re working with it, because it takes precious milliseconds to query it again and again. But why not make that initial search as fast as possible as well?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time I am working heavily on the HTML of a particular page for the first time, the first thing I’ll do is go through and rip out all the superfluous elements. I clean house, so to speak. So now you’re probably asking, “What are all these superfluous elements you keep talking about?” Basically, I’m talking about any element that does not need to be there for the look of the webpage to remain the same. The biggest offenders are pretty easy to spot.&lt;/p&gt;

&lt;p&gt;Here’s what to keep an eye out for:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;’s and &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;’s that have no classes, IDs, or attributes
&lt;/h3&gt;

&lt;p&gt;There might be a good reason that you have a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; as a container for a collection of elements because of its inherent block properties, or maybe you have the styling on the parent element that targets all of its children, but more often than not if I see a bunch of plain &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;’s being nested, they are serving absolutely no purpose whatsoever. Along the same lines, those plain &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;s are usually a red flag. The entire purpose of a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; is to be able to target something small that you want to style differently than everything else around it.&lt;/p&gt;

&lt;p&gt;Like this &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span" rel="noopener noreferrer"&gt;span page from MDN&lt;/a&gt; says, “&lt;em&gt;It should be used only when no other semantic element is appropriate&lt;/em&gt;,” and if you look at that page, you’ll see that both examples show it being added unnecessarily. The first, because it is unstyled and does absolutely nothing. The second example is unnecessary because the background-color can be put on the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; element. A much better example of a proper use case is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;&amp;lt;span class="blueText"&amp;gt;Blue&amp;lt;/span&amp;gt; is my favorite color&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where there would be a class that makes that one word Blue, and the rest of the text in the paragraph is a different color.&lt;/p&gt;

&lt;p&gt;Another thing to look out for is multiple &lt;code&gt;&amp;lt;br/&amp;gt;&lt;/code&gt; tags in a row. This is usually a sign that the element correct element.There are other elements that might be hanging out for no reason, too, but I’m focusing on these because they’re the two biggest offenders that I have come across.&lt;/p&gt;

&lt;h3&gt;
  
  
  Empty Elements
&lt;/h3&gt;

&lt;p&gt;I tend to spend a lot of time in the browser’s inspector, and sometimes I’ll see multiple elements that contain nothing. Not elements like the ones in the previous section, but elements that look like they should actually be doing something, because they have IDs, classes, and/or attributes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="importantThing blueVelvet"&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I immediately wonder why it’s there and go look up the code, and it’s almost always the result of some conditional.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="importantThing blueVelvet"&amp;gt;
  &amp;lt;% if user.city %&amp;gt;
    &amp;lt;%= user.city %&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or what I tend to see in React code is that there won’t even be the conditional, but it’ll have a variable value there that happens to be blank, so you see nothing on the page, but these nodes still are clogging up the DOM for no reason. Now as with anything, there are perfectly good use cases for having placeholder elements in the DOM, like if you know you’re going to be loading something there dynamically, for example. But if that’s not the case then I encourage you to place the HTML elements &lt;strong&gt;within&lt;/strong&gt; the conditional and if there is no conditional, add one!&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the right tool for the job
&lt;/h3&gt;

&lt;p&gt;Sometimes you can reduce the amount of nodes by simply using the proper HTML element, which is why it’s important to be familiar with them and what they do. Every HTML element has inherent properties and semantic value: there are block level elements, inline elements, elements that have more meaning than others (semantics). The elements behave in different ways and if you aren’t using them for what they were meant for, you might have to have extra elements, and you might have to add more styling than would have been necessary. A really extreme example would be putting a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; on a page with some text that you want to click on in order to visit another page by adding an &lt;code&gt;onClick&lt;/code&gt; handler to that &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and then making an AJAX call or calling &lt;code&gt;window.location("/link.html")&lt;/code&gt;. You’re probably not going to do that right? Why go to all that work, when you can simply use a normal &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag for your link that has all that functionality built into it?&lt;/p&gt;

&lt;p&gt;Some less extreme, but common examples are cases like the multiple &lt;code&gt;&amp;lt;br/&amp;gt;&lt;/code&gt; tags I mentioned above. If you are trying to put extra space between two blocks of text, then you probably aren’t using paragraph tags and should be. If you are separating out chunks of text within a single paragraph tag, then you aren’t using enough paragraph tags. Paragraph tags are block level elements that inherently have spacing above and below them.&lt;/p&gt;

&lt;p&gt;Another example would be changing a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; through CSS to be a block-level element instead of just using a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, or adding a bunch of CSS/JS to make a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; act like a button instead of just using the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; tag. You get a lot of functionality for free when you use the proper element. Buttons are inherently tabbable, they can use the &lt;code&gt;disabled&lt;/code&gt; attribute, and they also have many special HTML5 attributes that can do lots of things.&lt;/p&gt;

&lt;p&gt;In general, I encourage you to explore all that different attributes that can be used on a particular element, because that’s how you learn just how powerful HTML can be, which brings me to the next special mention: HTML5.&lt;/p&gt;

&lt;h4&gt;
  
  
  You might not need CSS/JavaScript
&lt;/h4&gt;

&lt;p&gt;You’ve probably seen &lt;a href="http://youmightnotneedjquery.com/" rel="noopener noreferrer"&gt;“You Might Not Need jQuery”&lt;/a&gt; and &lt;a href="http://youmightnotneedjs.com/" rel="noopener noreferrer"&gt;“You Might Not Need JS”&lt;/a&gt;, but I’m here to tell you that &lt;em&gt;you might not need anything but HTML&lt;/em&gt;. If you’re an old school developer, you might not be as familiar with all the fantastic things you can do with plain old HTML elements, and I’m always surprised that HTML5 isn’t used more being that it’s pretty old now. One of the areas it really shines is with forms.&lt;/p&gt;

&lt;p&gt;You have an input field and you only want the user to be able to enter numbers, so you have a backend validation to ensure that the value is numeric when it hits the server. Backend validations are important; they are the last line of defense before it hits the database, but why waste that time traveling all the way to the server initially? So you decide to implement some client-side validations to catch it without making a server call, and that’s pretty easy to do using &lt;code&gt;isNaN(value)&lt;/code&gt; or &lt;code&gt;$.isNumeric(value)&lt;/code&gt;, but if you’re doing that, then you’re working way too hard. All you have to do is tell your field what type it should be: &lt;code&gt;&amp;lt;input type="number"&amp;gt;&lt;/code&gt; and it won’t even &lt;strong&gt;allow&lt;/strong&gt; the user to enter anything but numbers. “But what if I want to make sure they only enter positive numbers? Or limit it?” you might ask. You still don’t need JS. Other attributes you can use on that field are &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is just one example, but there are many other special input types that can be used in forms that almost completely eliminate the need to use JavaScript for validations or to restrict input. Some of them even do fancy things that previously developers would have used a special plugin for. You want the user to input a date and want them to be able to choose from a pop-up calendar? &lt;code&gt;&amp;lt;input type="date"&amp;gt;&lt;/code&gt; will do this in every browser but Safari and Internet Explorer (sadly it falls back to a normal text input field), so plugins aren’t completely obsolete in that case, but it can fit a lot of use cases. Another fun one is &lt;code&gt;&amp;lt;input type="color"&amp;gt;&lt;/code&gt; for letting users pick a color from a pop-up palette. I encourage you to explore all the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input" rel="noopener noreferrer"&gt;different input types and their attributes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility (A11y)
&lt;/h2&gt;

&lt;p&gt;Another very important reason to understand HTML and its proper uses? Accessibility is important. I won’t elaborate all the reasons why because there are &lt;a href="https://www.google.com/search?ei=beFKWozBNcj10wLhqarADw&amp;amp;q=why+web+accessibility+is+important&amp;amp;oq=why+web+accessibility+is+important&amp;amp;gs_l=psy-ab.3..0j0i8i30k1l2.17319.28996.0.29228.25.24.1.0.0.0.148.2417.14j10.24.0....0...1c.1.64.psy-ab..1.24.2315...0i22i30k1j0i67k1j0i22i10i30k1j33i160k1j0i7i30k1j0i8i7i30k1.0.2c5tAmYU_zI" rel="noopener noreferrer"&gt;countless articles&lt;/a&gt; and books that will do that much better, but I will sum it up by saying that your website being accessible &lt;strong&gt;enhances the user experience for everyone&lt;/strong&gt;. I’m also not going to talk about all the techniques to make your site accessible because that’s a huge topic all its own. What I want to focus on, in the spirit of this article, is how using proper HTML elements (the right tool for the job, again) will already make your webpage much more accessible than it would be otherwise.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.thoughtco.com/why-use-semantic-html-3468271" rel="noopener noreferrer"&gt;Semantic HTML&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I suppose having also studied print design and typography, that my love of clean layouts and meaningful structure has also carried over to web development. So I was pretty excited about the increase of semantic tags when HTML5 came around. Providing more meaning to the elements not only helps accessibility but is an all-around win, in my opinion. Long gone are the days where &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s ruled the lands. Now we have &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;, and so on. Even before HTML5 though, there were a large amount of tags that weren’t being used when they should be.&lt;/p&gt;

&lt;p&gt;Let’s take tables for example. Tables no longer rule the web either, but they still have a good purposes and lots of associated tags that go with them. Yet somehow I’ll see table after table only make use of &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;, and &lt;code&gt;td&lt;/code&gt;, oftentimes with the first table row trying to act as headers. If a table has headers, it should at the very least be using &lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt; for the header cells, but ideally using &lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt; as well. The browser will treat these differently than just another table row, and semantically it means something.&lt;/p&gt;

&lt;p&gt;I still see &lt;code&gt;&amp;lt;i&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;b&amp;gt;&lt;/code&gt; used more often than &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt;, probably because old habits die hard. The former still have uses, but the latter should always be used when you’re trying to place actual emphasis on something; not for styling reasons, but because of the meaning it conveys.&lt;/p&gt;

&lt;h3&gt;
  
  
  How proper HTML helps keyboard accessibility
&lt;/h3&gt;

&lt;p&gt;All sites should be fully accessible by keyboard, and there are certain keys that users expect to be able to use to do this, because it’s the standard. Most people know they can tab through form elements and tend to do it without thinking about it. This is another case where you want to use the right tool for the job, because the exact kinds of things on the page that the user would want to navigate to are tabbable by default, without you having to do anything. This is why structure is important, and this is why the right element is important. Links, buttons, and input fields all have that functionality built in. This is why you don’t want to use a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; in place of a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, or a link that doesn’t actually use an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag. It is also why the order of elements matter, because tabbing follows DOM structure, and not the visual structure on the page. So if you’re floating &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;s and they appear in a different order on the page because of it, that’s going to confuse the user when the element they expect to be selected does not actually get selected.&lt;/p&gt;

&lt;p&gt;Sometimes that’s not going to cut it. You might have a link menu hidden as a dropdown, and then you’re going to have to make that parent element open and close when tabbed to, but by being mindful of using the right elements for the job, you’re still halfway there.&lt;/p&gt;

&lt;p&gt;Links also accept the “Enter” key by default. So if you are focused on a link and hit enter, it will go to that link. In forms, if you are focused on any input field within a form and hit enter, unless there is underlying code telling it to not behave like normal (&lt;a href="https://www.tjvantoll.com/2013/01/01/enter-should-submit-forms-stop-messing-with-that/" rel="noopener noreferrer"&gt;here’s a nice article about why you should rarely suppress this&lt;/a&gt;), it will automatically submit the form.&lt;/p&gt;

&lt;h3&gt;
  
  
  How proper HTML helps screen-readers
&lt;/h3&gt;

&lt;p&gt;There are a large amount of people in the world who have visibility issues, so they make use of screen-readers, and there is no feature that you as a developer turn on for this to work. A screenreader can read what’s on any website, but how much of that is coherent &lt;em&gt;does&lt;/em&gt; depend on what you as a developer have put there. This is why the aforementioned semantics are important, but there are also some basic HTML attributes that aid screen-readers. One that most people know about is the &lt;code&gt;alt&lt;/code&gt; attribute on images (alternative text), and yet it is so neglected. It’s often left blank when it shouldn’t be, filled in when it shouldn’t be, or the information doesn’t describe the image at all, rendering it useless. Let me hit on each of those points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If it is important that a particular image is conveyed to the user (a graph, a visual representation of something being described, etc) then you absolutely want an &lt;code&gt;alt&lt;/code&gt; attribute.&lt;/li&gt;
&lt;li&gt;If the image is completely unimportant, like a visual flourish, or an icon to represent text that comes immediately before or after it, then you &lt;em&gt;do not want an &lt;code&gt;alt&lt;/code&gt; attribute&lt;/em&gt;. Why? You’re not only throwing a mess of unimportant information at the user, but in many cases you’re just making it repeat the same word twice, which is confusing. This is also where ARIA roles come into play, but the most basic thing you can do in this situation is to intentionally identify a blank &lt;code&gt;alt=""&lt;/code&gt; attribute. If you don’t put in any &lt;code&gt;alt&lt;/code&gt; attribute at all, the screenreader/browser will just guess it by reading the file name or &lt;code&gt;title&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you have an image of the user and your &lt;code&gt;alt&lt;/code&gt; text is “User”, or it’s the logo of your company and it just says “Logo” or “Company Name”, you are not helping anyone. At the very least be a little more descriptive: “Your profile picture”, “Company Name’s logo”, but even better, be really descriptive if it’s an important visual. “Image of a brown horse with black hair” helps you imagine something much more than “Pic of horse”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another common misuse of HTML I come across is not labeling input fields. All input fields should have an associated label element and this is not accomplished by just having text near an input field. It may look fine to you visually and you might be able to deduce that they go together, but screen-readers won’t. Screen-readers expect that any input field that is selected should be able to tell them what that input field is for. There are two main ways to make sure your fields are labeled properly. The first is to simply wrap your input field in the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; element like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label&amp;gt;
  Your name
  &amp;lt;input type="text" name="name"/&amp;gt;
&amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know some developers might not like to use that method because they have special styling on all &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;s that they don’t want on the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; field and that’s fair enough, you just have to get explicit, and this is where I see the HTML fall way short.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label&amp;gt;Your name&amp;lt;/label&amp;gt;
&amp;lt;input type="text" name="name"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above does not associate the label with the input field. Proximity does not equal association. This is where the &lt;code&gt;for&lt;/code&gt; attribute comes in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label for="userName"&amp;gt;Your name&amp;lt;/label&amp;gt;
&amp;lt;input type="text" name="name" id="userName"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above associates the fields by matching up the &lt;code&gt;for&lt;/code&gt; attribute with the &lt;code&gt;id&lt;/code&gt; of the field. If your &lt;code&gt;for&lt;/code&gt; attribute and &lt;code&gt;id&lt;/code&gt; attribute don’t match up, then it does not work (I see this happen a lot). Sometimes you might not want the label there visually, or have an extra field associated with that same label. No problem, you can either hide the label, or add an ARIA attribute to the input field that specifies the labeling, but never just leave a field label-less. Screen-readers don’t read placeholders. I should also note that if you want your form elements to be fully accessible for all screen-readers then it’s best to cover your bases and have both the &lt;code&gt;for&lt;/code&gt; attribute AND nest your &lt;code&gt;input&lt;/code&gt; inside the &lt;code&gt;label&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An added benefit of labeling inputs properly: they’re easier to select and click, which makes them more accessible! Especially checkboxes and radio buttons, which have a very small click area. This is because it allows you to be able to click on the label text to select the element. Also note that for radio buttons, you should use the &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt; tag to group the radio inputs together, where the &lt;code&gt;&amp;lt;legend&amp;gt;&lt;/code&gt; serves as the parent label while each input still has its own.&lt;/p&gt;

&lt;p&gt;These are things that should be considered the basics of HTML, making use of the built in attributes and structure to better serve a diverse user base.&lt;/p&gt;

&lt;h2&gt;
  
  
  You don’t have to work as hard
&lt;/h2&gt;

&lt;p&gt;If anything else, understanding HTML should be encouraged because it makes your work easier. It can reduce the need for both styling and scripting, and makes the world wide web a happier place.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Abbreviations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML: HyperText Markup Language&lt;/li&gt;
&lt;li&gt;DOM: Document Object Model&lt;/li&gt;
&lt;li&gt;ARIA: Accessible Rich Internet Applications&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>html</category>
    </item>
  </channel>
</rss>
