aboutsummaryrefslogtreecommitdiff
path: root/_posts
diff options
context:
space:
mode:
authorBradley Taunt <bt@btxx.org>2024-01-22 13:06:19 -0500
committerBradley Taunt <bt@btxx.org>2024-01-22 13:06:19 -0500
commitd2e4da10c806d815eded44ade076babb78802c16 (patch)
tree7494261e22f3255926204164449c7345f5b500e5 /_posts
Initial commit to new cgit platform
Diffstat (limited to '_posts')
-rw-r--r--_posts/2018-03-24-css-variables.md52
-rw-r--r--_posts/2018-09-20-pure-css-simple-dropdown-plugin.md83
-rw-r--r--_posts/2019-04-26-minimal-css-menu.md62
-rw-r--r--_posts/2019-06-08-html-like-1999.md74
-rw-r--r--_posts/2019-06-11-responsive-tables.md151
-rw-r--r--_posts/2019-06-14-hamburger-menu-alternative.md133
-rw-r--r--_posts/2019-06-25-they-wont-wait.md78
-rw-r--r--_posts/2019-07-17-styling-empty-table-cells.md75
-rw-r--r--_posts/2020-06-22-keynote-slides-with-pure-css.md112
-rw-r--r--_posts/2020-11-09-bidirectional-scrolling.md47
-rw-r--r--_posts/2021-10-15-batch-webp-conversion.md88
-rw-r--r--_posts/2021-11-09-default-html-style-updates.md99
-rw-r--r--_posts/2022-06-16-club-updates.md47
-rw-r--r--_posts/2022-06-27-https-redirects.md66
-rw-r--r--_posts/2022-07-09-macos-convert-to-html.md115
-rw-r--r--_posts/2022-07-18-reflection.md39
-rw-r--r--_posts/2022-10-26-html-tables.md120
-rw-r--r--_posts/2023-07-24-purge.md46
18 files changed, 1487 insertions, 0 deletions
diff --git a/_posts/2018-03-24-css-variables.md b/_posts/2018-03-24-css-variables.md
new file mode 100644
index 0000000..2212854
--- /dev/null
+++ b/_posts/2018-03-24-css-variables.md
@@ -0,0 +1,52 @@
+---
+title: CSS Variables
+date: 2018-03-24 00:00:00 Z
+layout: post
+description: How to properly use variables in vanilla CSS
+summary: CSS preprocessors have allowed developers to use variables for quite some
+ time, but we now have the ability to use these properties in plain vanilla CSS.
+redirect_from: "/2018/03/24/css-variables/"
+---
+
+The CSS language is becoming even more awesome and powerful everyday. In this quick article I'd like to focus specifically on the "new" CSS variable function that you can start using in your projects *right now*.
+
+### Getting started is easy
+
+Let's just jump right in - this is how you create variables in vanilla CSS:
+
+```css
+:root {
+ --base-color: #e0e0e0;
+ --text-color: #111;
+}
+```
+
+We are using the `:root` selector at the very top of our CSS file in order to call these variables into any elements in the rest of our document. This is normally the safest way to include variables.
+
+As for the variables themselves, you declare that they are variables using the `--` tags, followed by the variable's name and it's property. Pretty simple stuff, right?
+
+Now let's use those variables:
+
+```css
+.header {
+ border: 1px solid var(--base-color);
+}
+
+.main-container {
+ background-color: var(--base-color);
+ color: var(--text-color);
+}
+```
+
+That's it! It's also good to know that CSS variables have pretty decent [browser support](https://caniuse.com/#feat=css-variables) (who likes IE11 anyway).
+
+
+### Why not just use a preprocessor?
+
+I'm a pretty big fan of Sass and Stylus, but sometimes it's refreshing to just use vanilla CSS for certain projects. Most preprocessors have had the ability to use variables and mixins for a while, but I prefer to avoid build scripts when not absolutely necessary.
+
+Get out there and have fun with some variables!
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
+
diff --git a/_posts/2018-09-20-pure-css-simple-dropdown-plugin.md b/_posts/2018-09-20-pure-css-simple-dropdown-plugin.md
new file mode 100644
index 0000000..9dba9ec
--- /dev/null
+++ b/_posts/2018-09-20-pure-css-simple-dropdown-plugin.md
@@ -0,0 +1,83 @@
+---
+title: Pure CSS Simple Dropdown Plugin
+date: 2018-09-20 00:00:00 Z
+layout: post
+column: single
+description: Learn how to implement a custom select dropdown with CSS
+summary: A simple, JavaScript-free way to implement a custom styled, plug-and-play
+ select dropdown with pure CSS.
+redirect_from: "/2018/09/20/pure-css-simple-dropdown-plugin/"
+---
+
+I find myself blowing away default browser `select` styling and implementing my own custom dropdowns far more often than I'd like. So, I recently created a very simple and clean component using just pure CSS.
+
+You can find the HTML & CSS for the three different variations below:
+
+## The HTML
+
+```html
+<div class="select-container">
+ <select name="" id="">
+ <option value="Option 1">Option 1</option>
+ <option value="Option 2">Option 2</option>
+ <option value="Option 3">Option 3</option>
+ </select>
+</div>
+
+<div class="select-container shadow">
+ <select name="" id="">
+ <option value="Option 1">Option 1</option>
+ <option value="Option 2">Option 2</option>
+ <option value="Option 3">Option 3</option>
+ </select>
+</div>
+
+<div class="select-container shadow depth">
+ <select name="" id="">
+ <option value="Option 1">Option 1</option>
+ <option value="Option 2">Option 2</option>
+ <option value="Option 3">Option 3</option>
+ </select>
+</div>
+```
+
+## The CSS
+
+```css
+.select-container {
+ background: #fff url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAYCAYAAACIhL/AAAAAAXNSR0IArs4c6QAAAWBJREFUSA3Nl00OgjAQRmnDeQhwBjcu3HIIXXgZ8SpuvAJh7yW8AAnO1zTElkHaWn6a1DJ22nk2fSGKpmluSZJcqO+x1aLv+7Rt2weNhz0RCiGeRVEcJT10aZpWNL72AggWzdRJQGVZ9pZSnmjivTUkGMACJrAoQDzkeY4TrKh3iDdqqF1pFoUwACIqy/JJ9Fc1s8EHaoPhu7QBiAm6mHca6u+klZ5rXdsoJ4xIB2ubTfdOGUvj6HqNThCMSFzLbKo1GMsdFguIxDXMJjjDWC9AJC9s9shYb0AsWMpsztggQCzSdsHuWO3OGcttzlrMJcYym+7dpLFc3UlJ7OQYZs8Za9dE7AyI5H/MdjEWNezmBYjFgWY7GWvDIfYGxCJfs12Nxd52CwLEJh5mOxtrwyF2tphbPGe2r7FcjeATVL/uxzs7xNjogNiQMzvU2EUAsalldrCxHGDU7+jf4Rk95qYfkiGLtr7wLgYAAAAASUVORK5CYII=') no-repeat calc(100% - 10px) center;
+ background-size: 10px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ cursor: pointer;
+ display: inline-block;
+ overflow: hidden;
+}
+.select-container select {
+ background: none;
+ border: 0;
+ cursor: pointer;
+ outline: none;
+ padding: 10px 40px 10px 10px;
+ width: 100%;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+}
+
+.select-container.shadow {
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
+}
+.select-container.depth {
+ background-color: #F8F8F8;
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1), inset 0 2px 5px rgba(255,255,255,1), inset 0 -2px 5px rgba(0,0,0,0.05);
+}
+```
+
+Check out the CodePen below and feel free to morph it as you see fit for your own projects!
+
+<p data-height="465" data-theme-id="0" data-slug-hash="rZPzWy" data-default-tab="result" data-user="bradleytaunt" data-pen-title="Plug & Play Dropdown (Pure CSS)" class="codepen">See the Pen <a href="https://codepen.io/bradleytaunt/pen/rZPzWy/">Plug & Play Dropdown (Pure CSS)</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>) on <a href="https://codepen.io">CodePen</a>.</p>
+
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
diff --git a/_posts/2019-04-26-minimal-css-menu.md b/_posts/2019-04-26-minimal-css-menu.md
new file mode 100644
index 0000000..cb18c5e
--- /dev/null
+++ b/_posts/2019-04-26-minimal-css-menu.md
@@ -0,0 +1,62 @@
+---
+title: 'Minimal CSS: Dropdown Menu'
+date: 2019-04-26 00:00:00 Z
+layout: post
+description: Creating CSS menu dropdowns with as little code as possible
+summary: Simple demo on how to develop CSS menu dropdowns with as little code as possible,
+ while still maintaining proper accessibility support.
+redirect_from: "/2019/04/26/minimal-css-menu/"
+---
+
+*I love the idea of stripping away as much CSS as possible*, while still maintaining the original UI concept. Let's build out a demo example with a simple menu dropdown element.
+
+Interesting facts about our final CSS menu:
+
+- Total weight 121 bytes minified! (not including any resets etc.)
+- No complex HTML structures
+- Accessibility support
+
+Now to see the final code in all it's glory:
+
+### HTML
+```html
+<nav>
+ <ul>
+ <li><a href="">Home</a></li>
+ <li><a href="">About</a></li>
+ <li><a href="">Services</a>
+ <ul>
+ <li><a href="">Design</a></li>
+ <li><a href="">Development</a></li>
+ <li><a href="">Custom Pizzas</a></li>
+ </ul>
+ </li>
+ <li><a href="">Contact</a></li>
+ </ul>
+</nav>
+```
+
+### CSS
+```css
+/* resets - optional */
+ul { list-style: none; padding: 0; }
+ul li { display: inline-block; position: relative; }
+
+/* minimal dropdown CSS */
+ul li > ul {
+ left: -9999px;
+ position: absolute;
+ visibility: hidden;
+}
+ul li:hover > ul, ul li:focus-within > ul {
+ left: 0;
+ visibility: visible;
+}
+```
+
+## Live demo on CodePen
+
+Feel free to check out the live demo on CodePen [here](https://codepen.io/bradleytaunt/pen/MRLevy).
+
+* footnotes will be placed here. This line is necessary
+{:footnotes} \ No newline at end of file
diff --git a/_posts/2019-06-08-html-like-1999.md b/_posts/2019-06-08-html-like-1999.md
new file mode 100644
index 0000000..28cbe31
--- /dev/null
+++ b/_posts/2019-06-08-html-like-1999.md
@@ -0,0 +1,74 @@
+---
+title: Write HTML Like It's 1999
+date: 2019-06-08 00:00:00 Z
+layout: post
+description: Breaking down some easy steps to ensure you are writing clean and semantic
+summary: New web tools make the lives of developers easier but can sometimes break
+ away from proper HTML structure.
+redirect_from: "/2019/06/08/html-like-1999/"
+featured: true
+---
+
+*I am sure it's safe to say that most developers love* to use the latest and greatest web tools available. Helpful resources such as preprocessors, template engines, syntax formatters - you name it - can all make a developer's life easier. Unfortunately, this sometimes comes at a cost: the HTML structure.
+
+This is why I try my best to write HTML as if I'm stuck with the constraints of the 90s (within reason). What does this mean exactly? It means that `tables` are coded with `table` elements. Navigations are coded with `nav` and ordered/unordered list-items. Form inputs are not set with `display: none` and replaced with custom containers. You know, *semantic* HTML.
+
+To be clear, I'm not advocating for creating projects that *look* like they belong in the 1990s. I would just prefer developers / designers be more conscious of their HTML *skeleton*.
+
+## Bad HTML practices
+
+Let's do a very simple breakdown of some of the more common HTML no-nos:
+
+<ul>
+<li>Using <code>span</code> or <code>div</code> elements for navigations or list components</li>
+<li>Implementing custom <code>div</code> layouts for forms while removing items like <code>select</code> or <code>radio</code></li>
+<li>Creating tables built out of custom <code>div</code> elements</li>
+<li>Over-nesting elements or making overly complex depth to simple components</li>
+<li>Content being heavily reliant on JavaScript "injection"</li>
+</ul>
+
+## Good HTML practices
+
+So what should you do in place of these bad HTML implementations?
+
+<ul>
+<li>Use proper <code>nav</code>, <code>ul</code> and <code>ol</code> for navigations or list components</li>
+<li>Style form elements directly <a href="https://www.filamentgroup.com/lab/select-css.html">this is already supported in browsers</a></li>
+<li>Build tables using <code>table</code> element structure (mind-blowing, I know!)</li>
+<li>Keep element hierarchy as slim and top level as possible</li>
+<li>Avoid injecting <i>any</i> content via JavaScript (I understand this is difficult for certain apps, but try to minimize this as much as possible)</li>
+</ul>
+
+## My basic "structure" test
+
+I've found a pretty simple starting point for testing the *bones of a website* by using the following single line of CSS:
+
+```css
+* {
+ border: 2px dotted black;
+}
+```
+
+This property simply outlines all elements on the current page in a dotted border. By placing a border on every HTML element you can instantly see how overly complex or *ugly* your structure might be under the hood.
+
+## "Thanks, Captain Obvious!"
+
+I know, this stuff is pretty basic. The point of this post isn't to tell you (developers) something brand new or mind-blowing, but instead should inspire you to keep things simple.
+
+Don't forget that there is always someone new into the world of design and development. Hopefully this post steers others towards keeping HTML code semantic and clean. ✌️
+
+## Update to this article
+
+Since this post received [so much more attention](https://news.ycombinator.com/item?id=20133817) than I ever expected, I've decided to touch on a few small points brought up in the comments.
+
+1. **What is the benefit of semantic HTML?**
+ - Accessibility. Programs like screen readers are built around the foundation of proper HTML hierarchy. I highly recommend testing all your projects with a screen reader - it will open your eyes to a lot of issues users with disabilities suffer through.
+
+2. **Tables not being responsive**
+ - This simply isn't true. It is much more semantic to layout your tables as you would normally, then for mobile devices you can target specific inner elements and alter them with `flexbox` etc. (You can see responsive tables in action [here](/blog/responsive-tables))
+
+3. **Instead of the CSS one-liner, simply use Firefox debugger**
+ - Fair point. Firefox is great!
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
diff --git a/_posts/2019-06-11-responsive-tables.md b/_posts/2019-06-11-responsive-tables.md
new file mode 100644
index 0000000..77aa469
--- /dev/null
+++ b/_posts/2019-06-11-responsive-tables.md
@@ -0,0 +1,151 @@
+---
+title: Making Tables Responsive With Minimal CSS
+date: 2019-06-11 00:00:00 Z
+layout: post
+description: Learn how to easily implement responsive table layouts with only CSS
+summary: Building responsive tables can often become a nightmare. Learn how to easily
+ implement responsive table layouts with only CSS.
+redirect_from: "/2019/06/11/responsive-tables/"
+featured: true
+---
+
+
+<strong>Update (Oct 2019):</strong> <a href="https://twitter.com/aardrian">@aardrian</a> wrote a previous post about how changing the <code>display</code> properties on tables can impact screen readers. I highly recommend his excellent article <a href="https://adrianroselli.com/2018/02/tables-css-display-properties-and-aria.html">Tables, CSS Display Properties, and ARIA</a>
+
+---
+
+*I find that the need to create responsive table layouts* pops up far more often than most developers would expect. The gut reaction might to be implement some sort of custom grid-system or pull in a pre-built library. Don't do this - just use tables and some simple CSS.
+
+My recent article, [Write HTML Like It's 1999](/blog/html-like-1999), received far more attention than I ever expected on HackerNews. With this attention came a few comments mentioning how `table` elements don't play nice with mobile devices or that it's not possible to have a useable layout on smaller screens. *This simply isn't true*.
+
+Included below are two separate demos showing how to optimize `table` HTML for mobile devices using only a minimal amount of CSS. These implementations may not be perfect, but they are far superior to injecting a bunch of custom `div` elements to *look* like tables.
+
+## Demo 1: Just let them scroll
+
+Okay I will admit, this implementation isn't the *greatest* but I find it does work well with huge datasets. Simply set a `min-width` on your parent `table` element and the browser will just require the user to scroll the contents horizontally.
+
+```css
+table {
+ min-width: 800px; /* Set your desired min-width here */
+}
+```
+
+Check out the CodePen below to see it in action:
+
+<p class="codepen" data-height="419" data-theme-id="0" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="ewObbW" style="height: 419px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Responsive Tables #1: Horizontal Scrolling">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/ewObbW/">
+ Responsive Tables #1: Horizontal Scrolling</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+I actually prefer this method because of its simplicity and function. Users on mobile are familiar with scrolling since it is one of the most basic actions required. Seeing a "cut-off" table gives them an instant visual cue that they have the ability to scroll the content.
+
+## Demo 2: More <u>flex</u>ible than you think
+
+Using something like `flexbox` tends to work better when you are working with smaller table datasets. All you need to do is add some minor `flexbox` layout at your targeted mobile screen size.
+
+```css
+/* Using 800px as mobile screen in this example */
+@media(max-width: 800px) {
+ /* Hide the table headings */
+ table thead {
+ left: -9999px;
+ position: absolute;
+ visibility: hidden;
+ }
+ table tr {
+ border-bottom: 0;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ margin-bottom: 40px;
+ }
+ table td {
+ border: 1px solid;
+ margin: 0 -1px -1px 0; /* Removes double-borders */
+ width: 50%;
+ }
+}
+```
+
+Check out the CodePen demo below:
+
+<p class="codepen" data-height="462" data-theme-id="0" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="mZbvOb" style="height: 462px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Responsive Tables #2: Flexbox">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/mZbvOb/">
+ Responsive Tables #2: Flexbox</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+There are some caveats with this approach:
+
+1. We currently hide the `thead` row when in mobile view (only visually - screen readers can still scan it)
+2. Some more custom work might be needed depending on how many items per `flexbox` row makes sense (based on project and dataset)
+
+You could keep the table headings and style them the same as the `tbody` contents, but I find hiding them a little cleaner. That choice is entirely up to your personal preference. You can also decide to add heading `span` elements inside the main `tbody` elements like so:
+
+```css
+/* Default span styling - hidden on desktop */
+table td span {
+ background: #eee;
+ color: dimgrey;
+ display: none;
+ font-size: 10px;
+ font-weight: bold;
+ padding: 5px;
+ position: absolute;
+ text-transform: uppercase;
+ top: 0;
+ left: 0;
+}
+
+/* Simple CSS for flexbox table on mobile */
+@media(max-width: 800px) {
+ table thead {
+ left: -9999px;
+ position: absolute;
+ visibility: hidden;
+ }
+ table tr {
+ border-bottom: 0;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ margin-bottom: 40px;
+ }
+ table td {
+ border: 1px solid;
+ margin: 0 -1px -1px 0;
+ padding-top: 35px; /* additional padding to avoid heading overlap */
+ position: relative;
+ width: 50%;
+ }
+ /* Show the heading span */
+ table td span {
+ display: block;
+ }
+}
+```
+
+<p class="codepen" data-height="445" data-theme-id="0" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="mZdzmZ" style="height: 445px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Responsive Tables #2.5: Flexbox">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/mZdzmZ/">
+ Responsive Tables #2.5: Flexbox</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+**Updated**: As pointed out by user [mmoez](https://news.ycombinator.com/user?id=mmoez), it is far less repetitive to use `:nth-child` pseudo selectors to implement the heading fields on mobile (as outlined in this [CSS-Tricks article](https://css-tricks.com/responsive-data-tables/)).
+
+## Why should I care to use `table` elements?
+
+Simply put: **accessibility** and **proper semantics**.
+
+Why use a screwdriver when you need a hammer? Sure, you can make that screwdriver look and *almost* work the same as a hammer, but for what purpose? Just use the damn hammer[^1].
+
+Have fun making your tables responsive!
+
+[^1]: I know, this is a terrible analogy...
+
+* footnotes will be placed here. This line is necessary
+{:footnotes} \ No newline at end of file
diff --git a/_posts/2019-06-14-hamburger-menu-alternative.md b/_posts/2019-06-14-hamburger-menu-alternative.md
new file mode 100644
index 0000000..7538b8f
--- /dev/null
+++ b/_posts/2019-06-14-hamburger-menu-alternative.md
@@ -0,0 +1,133 @@
+---
+title: Using Hamburger Menus? Try Sausage Links
+date: 2019-06-14 00:00:00 Z
+layout: post
+description: Hamburger menus have become the norm for mobile navigation systems but
+ are they always the best way?
+summary: Hamburger menus have become the go-to implementation for mobile navigation
+ systems - but are they always the best solution?
+redirect_from: "/2019/06/14/hamburger-menu-alternative/"
+featured: true
+---
+
+*When designing medium to large sized menu navigations on the mobile* web the default go-to, for some time now, has been hamburger menus. This isn't necessarily a <i>bad</i> thing, but there is a simpler alternative for certain use cases.
+
+Before we get into the nitty-gritty details (and a simple demo) of the *sausage link* concept, let's take a quick look at the pros and cons of hamburger menus.
+
+## Hamburger Menus
+
+The concept of the [hamburger menu](https://codepen.io/search/pens?q=hamburger%20menu&page=1&order=popularity&depth=everything) isn't *horrible* by any means, in fact it does solve a lot of problems from a visual perspective. Unfortunately, that doesn't mean it exists without some annoying flaws.
+
+### The Good
+
+- Minimizes the amount visual space the menu requires
+- Fairly commonplace now that a good portion of users understand it's functionality
+- Makes the lives of designers easier by tucking all items away on mobile 😛
+
+### The Bad
+
+- Requires extra testing/work to ensure the menu will play nice with screen readers and keyboard-only users
+- Can get overly complex with the presence of children dropdown elements, help text etc.
+- Adds bloat to projects that might require additional JavaScript to render these menus (CSS only hamburger menus avoid this issue)
+- Adds an additional point of interaction from the user (click to open, then proceed to read through available options)
+
+As you can see, the bad points listed above aren't *that* bad. I see them more as minor potholes along the UX journey for your end-users. A good portion of hamburger menu examples in the wild work perfectly fine and should remain as they are. However, those outliers who abuse or misuse the hamburger concept should be introduced to **sausage links**.
+
+## Sausage Links
+
+I should start by mentioning that this concept is far from **new**. There are a good number of websites that already implement this menu type in some form or another. The point of this post isn't to blow your mind with some new-never-thought-of navigation design. I'm just trying to bring awareness to another available menu concept.
+
+Enough chit-chat, let's take a look at sausage links in action:
+
+<p class="codepen" data-height="328" data-theme-id="0" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="QXjjbE" style="height: 328px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Scrolling Navigation (Sausage Links)">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/QXjjbE/">
+ Scrolling Navigation (Sausage Links)</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+The above CodePen adds a good amount of visual design fluff, so let's take a look at the bare minimum HTML &amp; CSS needed to accomplish this menu:
+
+```html
+<nav class="sausage-links">
+ <ul>
+ <li><a href="">Homepage</a></li>
+ <li><a href="">Categories</a></li>
+ <li><a href="">Filter Properties</a></li>
+ <li><a href="">Edit Optional Tags</a></li>
+ <li><a href="">Research Papers</a></li>
+ <li><a href="">Contact Our Team</a></li>
+ </ul>
+</nav>
+```
+
+```css
+/* Sausage Links Nav Container */
+.sausage-links {
+ position: relative;
+}
+
+/* The left and right "faded" pseudo elements */
+.sausage-links:before, .sausage-links:after {
+ content: '';
+ height: calc(100% - 2em);
+ pointer-events: none;
+ position: absolute;
+ top: 1em;
+ width: 10px;
+ z-index: 2;
+}
+.sausage-links:before {
+ background: linear-gradient(to right, rgba(255,255,255,0) 0%, white 100%);
+ right: 0;
+}
+.sausage-links:after {
+ background: linear-gradient(to left, rgba(255,255,255,0) 0%, white 100%);
+ left: 0;
+}
+
+/* Basic flexbox to prevent items from breaking lines */
+.sausage-links ul {
+ display: flex;
+ flex-wrap: nowrap;
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+.sausage-links ul li {
+ white-space: nowrap;
+}
+
+.sausage-links ul li a, .sausage-links ul li a:visited {
+ display: inline-block;
+}
+```
+
+Pretty simple, eh?
+
+**Update**: Thanks to [@dany0w](https://twitter.com/dany0w) for pointing out that I forgot to include `-webkit-overflow-scrolling: touch` for momentum scrolling on iOS.
+
+### The Good
+
+- Extremely minimal amount of CSS required
+- Screen reader / keyboard-only safe
+- Zero JavaScript needed
+- No need for hacky hidden `radio` inputs for toggling parent containers etc.
+- Users can see first few available options without any interaction
+
+### The Bad
+
+- May not look the most visually appealing for certain project designs (ugly scrollbar in some instances)
+- Better suited for small to medium menu lists compared to massive sitemaps
+- Without proper fade / cut off visual cues, users may not understand they can scroll
+
+## So, should I use hamburger menus or sausage links?
+
+That really depends on your project or overall mobile design (I know, such a helpful answer). I'm sure there are even a few use cases where it would make sense to have sausage links within a toggle-based hamburger menu. The menu possibilities could be endless!
+
+That's it. I hope I've inspired you to try out sausage links in the near future or at least made you think more deeply about mobile navigation design!
+
+<small>...is anyone else really hungry now?</small>
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
diff --git a/_posts/2019-06-25-they-wont-wait.md b/_posts/2019-06-25-they-wont-wait.md
new file mode 100644
index 0000000..7be3c88
--- /dev/null
+++ b/_posts/2019-06-25-they-wont-wait.md
@@ -0,0 +1,78 @@
+---
+title: 'They Won''t Wait: A Warning for Slow Websites'
+date: 2019-06-25 00:00:00 Z
+layout: post
+description: Your website is probably slow - learn how you can make it faster
+summary: Speed and performance are critical to having a solid experience for your
+ users. Learn how to implement simple performance wins without the stress.
+redirect_from: "/2019/06/25/they-wont-wait/"
+---
+
+*Your website is probably slow*. I'm not trying to make you feel bad or dismiss all the hard work you've put into your project. Heck, performance might have been a core value of the design. But websites can always be faster.
+
+People have become increasingly more impatient over the last decade when it comes to technology, specifically non-native web-based interactions. Users expect your website to load almost instantly or they will leave and try another site, probably one of your competitors. Why should they stick around if your competitors' websites load half a second faster?
+
+Users are tired of being bombarded with tracking scripts, having to download massive component libraries, forced to deal with "accept cookies" prompts, playing a small mini-game of "close those ads!", and then being subjected to never-ending loading screens. This is not the internet we were promised.
+
+> It's in my nature, I always liked **speed**.
+>
+> <cite>- Guy Lafleur<cite>
+
+## We can do better
+
+If there is only one thing that you learn from this post, hopefully it's knowing to better value the **time and money of your users**. It's a user's *choice* to visit your website, so taking advantage of their time is extremely careless. Don't be arrogant and ignore the cost of data on most mobile plans either. Eating up a chunk of someone's data just for hitting your website is rage-inducing. That's how you can lose customers permanently.
+
+Let's do an analogy, because **I love stupid analogies**:
+
+Imagine going to your local hardware store because you need to buy a new hammer. Once you get to the entrance a woman holds the the door closed and asks you if it's alright for someone to follow you around the store today. You say no. She then follows up by asking if you accept their hardware store agreement before proceeding inside - you tell her "sure". She finally opens the door and lets you in. As you walk into the store she quickly stuffs a few advertisements for other local businesses into you hand. "Thanks", you mutter.
+
+Once inside you realize the hardware store is *very big* and manually looking for a hammer might take a while. You walk up to the front desk to ask where you can find a hammer but notice the cashier is playing with their phone behind the counter. You try to get their attention but they simply raise their hand and shout "Be with you in a minute". After a short while they get off their phone and *finally* listen to your question. They then tell you where to find the hammers.
+
+Does this sound like a *fast* and easy experience?
+
+As silly as this hypothetical trip to the hardware store might be, it's exactly what many current websites are putting their users through. Users - read *customers* - are coming to your website with a specific goal in mind; checking out a product, consuming information or just satisfying their curiosity. Stop putting so many blockers and excessive bloat in front of them.
+
+## Data doesn't lie
+
+If my terrible analogy wasn't enough to convince you to implement better performance on your website, then maybe some "BIG DATA" will.
+
+- [Amazon (PowerPoint, slide #15)](https://web.archive.org/web/20081117195303if_/http://home.blarg.net/~glinden/StanfordDataMining.2006-11-29.ppt): 100 ms of latency resulted in 1% less sales.
+- [Google (video)](https://youtu.be/6x0cAzQ7PVs?t=936): 500 ms caused a 20% drop in traffic.
+- [Walmart (slide #46)](https://www.slideshare.net/devonauerswald/walmart-pagespeedslide): a 100 ms improvement brought up to 1% incremental revenue
+- [Mozilla](https://blog.mozilla.org/metrics/2010/04/05/firefox-page-load-speed-%E2%80%93-part-ii/): Shaving 2.2 seconds off page load time increased downloads by 15.4%
+- [Yahoo](https://www.slideshare.net/stubbornella/designing-fast-websites-presentation/23-1_Create_a_component_library): 400 ms resulted in a 5 to 9% drop in traffic
+
+<small><sup>*</sup>All data taken from [instant.page](https://instant.page) (which I am a huge fan of &hearts;)</small>
+
+The fact something as small as 100 ms can have such a profound impact on your bottom-line should be eye-opening. You're leaving money of the table by not tackling even the low-hanging, easy performance wins. You need to start valuing your users' time and stop serving them excessive garbage they never asked for.
+
+## Small and easy wins
+
+Not all of these suggestions can work for every project (due to restrictions, brand guidelines, required marketing targets, etc.) but for most developers/designers they should be easy to implement: (in no particular order of importance)
+
+1. Reduce the number of web requests
+ - [HTTP Requests](https://developers.google.com/web/fundamentals/performance/get-started/httprequests-5)
+2. Use web-safe fonts when available or if using custom fonts utilize the `font-display` property
+ - [CSS Font Stack](https://www.cssfontstack.com/)
+ - [Font Display for the Masses](https://css-tricks.com/font-display-masses/)
+3. Make proper use of *critical CSS*
+ - [How to Use Critical CSS](https://alexwright.net/web-design-secrets/how-to-use-critical-css/)
+ - Automatically generate CSS based on "above the fold": [criticalCSS](https://github.com/filamentgroup/criticalCSS)
+4. Process all media (images / videos) through 3rd party tools
+ - [Cloudinary](https://cloudinary.com/)
+ - [Kraken.io](https://kraken.io/)
+ - [Piio](https://piio.co/)
+ - Sidenote: this blog uses the [jekyll-cloudinary](https://nhoizey.github.io/jekyll-cloudinary/) plugin to automatically process images
+5. Use "just-in-time" preloading (highly recommended for improved UX)
+ - [Instant Page](https://instant.page/)
+6. Avoid using heavy tech-stacks whenever possible
+ - Unless it is a critical use-case, users should not have to process or download extra resources
+ - This also includes remove ads, pop-ups, 3rd party sign-up prompts, cookie notifications, over-the-top element animations, and all other **garbage**. This impacts *UX* performance, which is just as crucial as website loading speed
+
+## No need to be extreme
+
+These quick "guidelines" are just a solid jumping-off point when tackling new projects or re-working current websites. There isn't some agreed upon *golden standard* when it comes to web performance, but I find these rules work as a great place to start. Hopefully it can help others as well.
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
+
diff --git a/_posts/2019-07-17-styling-empty-table-cells.md b/_posts/2019-07-17-styling-empty-table-cells.md
new file mode 100644
index 0000000..f3140f3
--- /dev/null
+++ b/_posts/2019-07-17-styling-empty-table-cells.md
@@ -0,0 +1,75 @@
+---
+title: Styling Empty Table Cells
+date: 2019-07-17 00:00:00 Z
+layout: post
+description: Taking a quick look at how to target and style empty table cells
+summary: Tables can often times have blank pockets of data. Let's take a quick look
+ at how to target and style empty table cells.
+---
+
+*Often when designing tables on the web you're bound to come across* empty pockets of data. These will be rendered as "blank" table cells, which isn't always the intended outcome. Let's take a quick look at how to target and style empty table cells.
+
+## The easy `:empty` way
+
+The most popular way to target *any* empty element is by using - you guessed it - the `empty` pseudo-class. This pseudo-class is incredibly simple. You target an element's `empty` state that same way you would target `hover` or `active`:
+
+```css
+table tr td:empty {
+ opacity: 0;
+}
+```
+
+Check out the CodePen examples below for more advanced styling options:
+
+<p class="codepen" data-height="353" data-theme-id="0" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="EBBLEx" style="height: 353px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Styling Empty Tables Cells with :empty">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/EBBLEx/">
+ Styling Empty Tables Cells with :empty</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+You can also include additional pseudo elements to give the user more context about what the empty cells represent:
+
+<p class="codepen" data-height="365" data-theme-id="0" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="bPXqLa" style="height: 365px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Styling Empty Tables Cells with :empty &amp;amp; pseudo elements">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/bPXqLa/">
+ Styling Empty Tables Cells with :empty &amp; pseudo elements</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+## More specific `empty-cells` property
+
+Although using the `:empty` pseudo-class can be helpful, it isn't used just for tables. It can be used for any HTML elements that have a lack of content. So, is there a CSS specific property that can target *just* table cells?
+
+Let's take a look at the `empty-cells` property:
+
+```css
+table {
+ empty-cells: hide;
+}
+```
+
+<p class="codepen" data-height="368" data-theme-id="0" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="XLLqOW" style="height: 368px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Styling Empty Tables Cells with empty-cells property">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/XLLqOW/">
+ Styling Empty Tables Cells with empty-cells property</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+Pros of using `empty-cells`:
+
+- Only one CSS property
+- Targets the table elements specifically
+- No need for custom styles since it simply *hides* empty cell borders
+
+Some downsides to using this property:
+
+- No styling customization
+- Trickier to use pseudo-element helpers without invoking the `:empty` state
+
+## Pick your preference
+
+It doesn't matter semantically which option you decide to take when styling / hiding empty table cells. Using the `:empty` state gives you a lot more flexibility in terms of what you can target (full rows, columns etc), but using the `empty-cells` property let's you simply hide the cells and focus on more important items.
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
diff --git a/_posts/2020-06-22-keynote-slides-with-pure-css.md b/_posts/2020-06-22-keynote-slides-with-pure-css.md
new file mode 100644
index 0000000..da458f8
--- /dev/null
+++ b/_posts/2020-06-22-keynote-slides-with-pure-css.md
@@ -0,0 +1,112 @@
+---
+id: 596
+title: Keynote Slides with Pure CSS
+date: 2020-06-22T09:47:48-04:00
+author: Bradley Taunt
+layout: post
+categories:
+ - Web Design
+summary: Building out a reusable keynote slide plugin with only pure CSS
+---
+
+*There are a great deal of options available on the web and built* into most operating systems when you need to create presentation / keynote slides. You could use native software like LibremOffice Impress, Powerpoint, Apple&#8217;s Keynote, etc. You could also decide to use preexisting web-based apps like Google Slides or an open source project such as RevealJS. All of these are good options.
+
+But thinking more about how overly &#8220;complex&#8221; these apps are implemented, it got me wondering if I could quickly code up a presentation slide &#8220;framework&#8221; with pure CSS and barely any code&#8230;
+
+This is what I came up with:
+
+## The Demo
+
+<p class="codepen" data-height="512" data-theme-id="dark" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="jOWBJZb" style="height: 512px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Presentation / Keynote Slides (Pure CSS)">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/jOWBJZb">
+ Presentation / Keynote Slides (Pure CSS)</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+Yes, I know this is _ugly_, but this was created as a barebones skeleton for others to build upon. The demo uses a simple set of `radio` inputs that correspond to their own individual `slide` element. The &#8220;framework&#8221; looks at the currently `checked` input, then changes the `opacity` and `z-index` of it&#8217;s corresponding slide item. Pretty straightforward stuff!
+
+Let&#8217;s break down each piece:
+
+## The HTML
+
+```
+<div class="slider">
+ <input type="radio" name="pagination" value="1" checked>
+ <input type="radio" name="pagination" value="2">
+ <input type="radio" name="pagination" value="3">
+ <input type="radio" name="pagination" value="4">
+ <input type="radio" name="pagination" value="5">
+
+ <div class="slide">
+ <h2>Slide 1</h2>
+ </div>
+ <div class="slide">
+ <h2>Slide 2</h2>
+ </div>
+ <div class="slide">
+ <h2>Slide 3</h2>
+ </div>
+ <div class="slide">
+ <h2>Slide 4</h2>
+ </div>
+ <div class="slide">
+ <h2>Slide 5</h2>
+ </div>
+</div>
+```
+
+There isn&#8217;t a whole lot going on here. We are just including a set of `radio` inputs (based on how many slides are desired) along with their corresponding `slide` class elements. You might notice we don&#8217;t do anything to specifically target each individual slide item &#8211; you&#8217;ll see why we don&#8217;t need to in the CSS section!
+
+## The CSS (SCSS)
+
+```
+/* Basic default styles */
+.slider {
+ height: 100%;
+ left: 0;
+ position: fixed;
+ top: 0;
+ width: 100%;
+
+ .slide {
+ height: 100%;
+ opacity: 0;
+ position: absolute;
+ width: 100%;
+ z-index: -2;
+ }
+}
+
+input[type="radio"] { cursor: pointer; }
+
+/* Target slide item based on currently checked radio */
+input[type="radio"]:nth-of-type(1):checked ~ .slide:nth-of-type(1),
+input[type="radio"]:nth-of-type(2):checked ~ .slide:nth-of-type(2),
+input[type="radio"]:nth-of-type(3):checked ~ .slide:nth-of-type(3),
+input[type="radio"]:nth-of-type(4):checked ~ .slide:nth-of-type(4),
+input[type="radio"]:nth-of-type(5):checked ~ .slide:nth-of-type(5) {
+ opacity: 1;
+ z-index: 1;
+}
+
+/* Individual slide styling */
+.slide:nth-of-type(1) { background: dodgerblue; }
+.slide:nth-of-type(2) { background: crimson; }
+.slide:nth-of-type(3) { background: rebeccapurple; }
+.slide:nth-of-type(4) { background: goldenrod; }
+.slide:nth-of-type(5) { background: pink; }
+```
+
+Again &#8211; not much to see here. We use CSS to look down through the DOM for each `radio` elements slide &#8220;partner&#8221;. We do this by targeting the `nth-of-type` on both elements. Simple stuff.
+
+Some drawbacks to this approach:
+
+ * You need to manually target each new slide you add (color, styling, content, etc.)
+ * Lack of animations might require extra work to implement (maybe 3rd party libraries like AOS?)
+ * Probably won&#8217;t be best for extremely long/complex presentation slides
+
+That&#8217;s it! Hope you enjoy playing around with it.
+
+* footnotes will be placed here. This line is necessary
+{:footnotes} \ No newline at end of file
diff --git a/_posts/2020-11-09-bidirectional-scrolling.md b/_posts/2020-11-09-bidirectional-scrolling.md
new file mode 100644
index 0000000..132d15c
--- /dev/null
+++ b/_posts/2020-11-09-bidirectional-scrolling.md
@@ -0,0 +1,47 @@
+---
+title: "Bidirectional Scrolling: Why Not Both?"
+layout: post
+summary: Discussing the design decisions of bidirectional scrolling in regards to performance
+---
+
+*I recently came across Adam Silver's post [about the merits and pitfalls of bidirectional scrolling](https://adamsilver.io/articles/bidirectional-scrolling-whats-not-to-like/)* and found myself conflicted with the design arguments put forth in the article. It's a very good article overall, and I suggest giving it a read before digging deeper into my post here.
+
+## The Premise
+
+The original article argues that displaying page content via horizontal scrolling (and therefore slightly hiding interactive content) creates a few major issues:
+
+- it increases the chance users won't see it
+- there's a greater reliance on digital literacy
+- it's generally more labour intensive for users
+
+Adam also makes a solid statement here:
+
+> Having to scroll down and across in a zig zag fashion can be tiresome, especially for people with motor impairments.
+
+But I don't believe these issues create a need to completely remove the horizontal "scrolling" design altogether. You can still implement the `See All Items` category link, while allowing the horizontal content to load in *dynamically*. Balance is always key.
+
+## Not All At Once, Please!
+
+So what exactly do I mean by *dynamically* loading in horizontal content?
+
+- The user is shown the top 4 items in a given category
+- From there, the user can use the `See All Items` link to jump into a full category page
+- If they so desire, they can begin scroll horizontally in a given category row
+ - Once they reach the end of the row, 4 more items will load in automatically to expand the list
+ - To avoid a never-ending list, it might be best to limit total row items to ~20 items. At this point the UI could prompt the user to `View All Items` in that category.
+
+By loading the row content in piece-by-piece, initial loads for users will be faster and subsequent list items will load quickly as well (since they would limit to a set default - in this case only 4).
+
+## Final Improvements
+
+Below you can find a quick, static version of this concept. Here you can see the horizontal list items, along with their corresponding `See All Items` links. You'll have to use your imagination for how new items would load once you each the end of a horizontal row. (I'm too lazy to spend extra time building out that functionality for a hypothetical blog post)
+
+<p class="codepen" data-height="844" data-theme-id="dark" data-default-tab="result" data-user="bradleytaunt" data-slug-hash="pobxpXz" style="height: 844px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Bidirectional Scrolling CSS">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/pobxpXz">
+ Bidirectional Scrolling CSS</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
diff --git a/_posts/2021-10-15-batch-webp-conversion.md b/_posts/2021-10-15-batch-webp-conversion.md
new file mode 100644
index 0000000..47697a8
--- /dev/null
+++ b/_posts/2021-10-15-batch-webp-conversion.md
@@ -0,0 +1,88 @@
+---
+title: "Batch Converting Images to webp with macOS Automator"
+layout: post
+summary: "An easy-to-follow tutorial on setting up batch webp conversion of images on macOS"
+imgnum: 2
+size: 79.3
+---
+
+A great deal of my time working as a web/UI designer is spent exporting and/or converting images for software products and websites. Although a lot of modern applications can render image conversions at build time, a custom conversion is sometimes requested for an image to be set as `webp`.
+
+You *could* download one of the many native apps from the Mac App Store to do this for you - but why not create your own script and run it with a simple right-click directly inside Finder? **Let's do just that!**
+
+## Basic requirements
+
+**Important!**: As of this time of writing, the official `libwebp` package release is *libwebp-1.2.1-mac-10.15*. If this has been updated since then, change the command below to match that of the proper release version.
+
+1. First you will need to download the `libwebp` package to your Downloads folder: [libwebp package](https://developers.google.com/speed/webp/download)
+ - *Look for the "Download for macOS link"*
+
+2. Next we will need to copy the `cwebp` folder to our `/usr/local/bin` directory:
+ - Open macOS Terminal
+ - Run `sudo cp /Downloads/libwebp-1.2.1-mac-10.15/bin/cwebp /usr/local/bin`
+ - *Note:* if the `/usr/local/bin` directory doesn't exist, simply create it by running: `sudo cd /usr/local && mkdir bin`
+
+## Creating our custom Automator script
+
+1. Open the macOS Automator from the Applications folder
+
+2. Select `Quick Option` from the first prompt
+
+3. Set "Workflow receives current" to `image files`
+
+4. Set the label "in" to `Finder`
+
+5. From the left pane, select "Library > Utilities"
+
+6. From the presented choices in the next pane, drag and drop `Run Shell Script` into the far right pane
+
+7. Set the area "Pass input" to `as arguments`
+
+8. Enter the following code below as your script and type `⌘-S` to save (name it something like "Convert to webp")
+
+```
+for f in "$@"
+do
+/usr/local/bin/cwebp -q 85 "$f" -o "${f%.*}.webp"
+done
+```
+
+For visual reference, it should look something like this:
+
+<figure>
+ <img src="/public/images/automator.png" alt="macOS Automator">
+ <figcaption>(<a href="/public/images/automator.webp">link to hi-res image</a>)</figcaption>
+</figure>
+
+And when right-clicking an image file in the Finder window, it should now give you the option to convert:
+
+<figure>
+ <img src="/public/images/automator-2.png" alt="Right click to convert">
+ <figcaption>(<a href="/public/images/automator-2.webp">link to hi-res image</a>)</figcaption>
+</figure>
+
+## Making edits to your script
+
+If you ever have the need to edit this script (for example, changing the default `85` quality parameter), you will need to navigate to your `~/Library/Services` folder and open your custom webp Quick Action in the Automator application.
+
+Simple as that!
+
+## Possible Hiccups
+
+I was contacted by the very helpful [Kev Quirk](https://kevq.uk) about a minor problem he encountered while following this tutorial. When trying to run `cwebp` he received the following error message:
+
+```
+cwebp cannot be opened because it's from an unverified developer
+```
+
+Doing the next steps seemed to have fixed this issue for him:
+
+1. Click on the "Open in Finder" in the error message prompt
+2. Double-click on the `cwebp` utility to open in Terminal
+3. You'll then be prompted with a pop-up asking if you wish to execute
+
+After following these steps, the issue should be resolved.
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
+
diff --git a/_posts/2021-11-09-default-html-style-updates.md b/_posts/2021-11-09-default-html-style-updates.md
new file mode 100644
index 0000000..557bb5f
--- /dev/null
+++ b/_posts/2021-11-09-default-html-style-updates.md
@@ -0,0 +1,99 @@
+---
+title: "Modern Improvements for Default Browser Styles"
+layout: post
+summary: "Taking a look at some minor improvements that could be made to default browser styling"
+imgnum: 0
+size: 14.3
+---
+
+This website *almost* exclusively uses the browser's (whichever one that might be) default styling to render it's HTML. I firmly believe, and have [stated in a previous post](/css-js-mistake/), that the default HTML styling across all browsers is a thing of beauty. "Consistent and boring" is how I tend to refer to default browser styles - and I mean that in a *good way*.
+
+But that doesn't mean some minor, modern improvements couldn't be made...
+
+## Boosting Margins and Increasing Font Size
+
+A little extra breathing room for a website's content never hurts. Browser defaults set the inner content too close to the main window borders, creating mild eye strain to focus on the far edges of the screen when reading. Pair this with a typeface set too small and you've got a recipe for disaster (in terms of user experience and accessibility). Luckily for us, adding two basic CSS properties fixes all of our readability woes. All that is required is a simple boost to the existing `margin` property set on the `body` element (I personally lean towards a very specific `1.5em`) and overriding the default `font-size` to `18px`[^1]:
+
+```
+body {
+ font-size:18px;
+ margin:1.5em;
+}
+```
+
+There is one *small* caveat with setting the `font-size` across the whole `body` element: code elements set in `monospace`. They will stand out larger than the other fonts found in the document (due to variations in different typeface heights, spacing etc.) so we will need to target these elements specifically:
+
+```
+code {
+ font-size:14px;
+ /* Word wrap is optional if you plan to have long inline code snippets */
+ word-wrap:break-word;
+}
+```
+
+## Code & Pre Tags
+
+Since we've mentioned `code` elements, let's fix those as well. The existing styling for inline code snippets and larger pre-formatted text sections leave a lot to be desired. They don't provide any means to wrap their inner content or make use of `overflow` properties to avoid vertically scrolling on smaller device screens. Sharing code examples becomes quite a pain when your webpage's flow and layout is broken just by including them. Browsers could fix this easily enough by defaulting to:
+
+```
+pre {
+ overflow:auto;
+}
+```
+
+## Basic Dark Mode Support
+
+Barebones styling in current web browsers have no sane defaults[^2] for system-level dark mode. What a huge letdown. This is where the most "drastic" changes will be implemented with our browser default updates. We will need the browser to change the main `background-color`, along with resetting both the text and anchor link `color` for improved accessibility. Browser defaults for anchor link color in "light mode" are blue/purple - so I've opted towards using gold, orange and orangered in dark mode respectively:
+
+```
+/* Dark mode */
+@media (prefers-color-scheme: dark) {
+ @media not print {
+ html {background:#0e0e0e;color:#e1e1e1; }
+ a {color: gold;}
+ a:visited {color: orange;}
+ a:hover,a:focus{color: orangered;}
+ }
+}
+```
+
+That is probably the most streamlined dark mode on the web...
+
+## The "Reading Length" Debate
+
+Proper reading length tends to be quite the point of contention on the web. Hell, even I've [written about it quite a bit](/character-unit/) in the past (and many of my side projects follow that standard). The main problem I have with this is lack of *user control*. I don't think the browser (or designers for that matter) should determine the best reading length for my own personal reading preferences. UX testing and group feedback has (somewhat) agreed upon 66-75 characters per line to be the most optimal reading experience. That is good to know. I *still* believe it should come down to user preference.
+
+Do you want to know an incredible feature built into browsers? *Window resizing*. Abandon the idea that you "know better" than your users and give them the power to adjust as they see fit. The web was meant to be personal and flexible.
+
+## Conclusion
+
+There isn't much else to say, really. I think these tiny tweaks would greatly improve the default browser experience and maybe even convince others to just *use* these defaults instead of falling down the CSS rabbit hole (as fun as that might be sometimes). For easier convenience, I'll leave the full set of CSS changes below:
+
+```
+body {
+ font-size:18px;
+ margin:1.5em;
+}
+code {
+ font-size:14px;
+}
+pre {
+ overflow:auto;
+}
+@media (prefers-color-scheme: dark) {
+ @media not print {
+ html {background:#0e0e0e;color:#e1e1e1; }
+ a {color: gold;}
+ a:visited {color: orange;}
+ a:hover,a:focus{color: orangered;}
+ }
+}
+```
+
+<hr data-content="footnotes">
+
+[^1]: `18px` seems to be the perfect sweet spot between "almost too large, yet not small enough to strain my eyes"
+[^2]: At the time of this article's publish date
+
+* footnotes will be placed here. This line is necessary
+{:footnotes}
diff --git a/_posts/2022-06-16-club-updates.md b/_posts/2022-06-16-club-updates.md
new file mode 100644
index 0000000..3c11ace
--- /dev/null
+++ b/_posts/2022-06-16-club-updates.md
@@ -0,0 +1,47 @@
+---
+title: "Fresh Coat of Paint, Hall of Fame, and Blog Posts"
+layout: post
+summary: "Explaining the recent changes and additions to the 1MB Club project website"
+---
+
+Things are looking a little different around here. In case it wasn't obvious already, 1MB Club has received a visual overhaul. New pages have also been added to the project website. These include an [about page](/about), the new [official blog](/blog) and a more streamlined [submission page](/submit).
+
+My hope is that this makes the project more approachable for those less knowledgeable about web technology. Moving some of my older posts (and also adding new ones) here seemed like a better place for them to call home. I'll still write on my [personal blog](https://tdarb.org), but all web-based articles/tutorials will be posted here instead.
+
+This just makes more sense since most web tutorials and experiments require live demos / code examples. My personal website is generated using only plain text files - so that makes rendering demos somewhat difficult. (Not to mention less accessible)
+
+## Visual Inspiration
+
+Some readers might already recognize the design influence used for this update: the Apache2 Ubuntu Default Page. It's a small piece of nostalgia since I so frequently saw that page in my earlier days of web development. It just feels like a simpler time of the internet.
+
+I've even uploaded a static version for comparison here: [https://apache-index.netlify.app](https://apache-index.netlify.app/)
+
+You might have also noticed that the members are once again listed in order of page size. I had originally placed a simple script on the homepage that would randomize the order on every page visit. This was added in hopes to deter those wishing to simply "game the system" or have their links placed at the very top (because that's so important?). But changing the order on refresh ended up hurting the *fun* of exploring the club's websites. Having things set in a formatted list just makes the experience cleaner. Also, the homepage is now JavaScript free!
+
+We'll keep it this way for now and circle back if any issues come up.
+
+## "Hall of Fame" Explained
+
+I need to make one thing clear before moving on: **the "Hall of Fame" is completely optional**.
+
+Anyone can still freely [submit](/submit) their website for membership to the 1MB Club. This resource will always remain completely free and the source code is available on [Github](https://github.com/bradleytaunt/1mb-club).
+
+The inclusion of this "Hall of Fame" section on the homepage allows those who wish to support this project to do so. These donations also help fund the creation of new blog posts.
+
+I should stress this again: **this is completely optional**.
+
+This idea originally came to me when I was reviewing previous donations on my [Buy Me a Coffee page](https://www.buymeacoffee.com/WQTMtn7ir) and realized I should thank these people more than with a simple 'chat' message. So, I thought up a way to "immortalize" them by placing their existing membership websites in a [Hall of Fame](/#hof)[^1] at the top of the main homepage. Some might find it tacky but I like it.
+
+## Moving Forward
+
+I wish to have this project continue to grow indefinitely. The "dream" would be to have this online resource live beyond my own lifetime[^2]. But a more realistic goal would to have this project inspire even *one single developer* to better optimize their projects and make a better web.
+
+Either way, it will be fun to see where this project goes...
+
+---
+
+[^1]: I also thank them and link to the same websites at the end of every blog post.
+[^2]: I know how crazy this sounds...
+
+* footnotes will be placed here. This line is necessary
+{:footnotes} \ No newline at end of file
diff --git a/_posts/2022-06-27-https-redirects.md b/_posts/2022-06-27-https-redirects.md
new file mode 100644
index 0000000..6df0f8f
--- /dev/null
+++ b/_posts/2022-06-27-https-redirects.md
@@ -0,0 +1,66 @@
+---
+title: "Consider Disabling HTTPS Auto Redirects"
+layout: post
+summary: "Depending on your use case, not every website needs to enable HTTPS auto redirects"
+---
+
+If you run your own website or blog, odds are that you have HTTPS auto redirects enabled by default. While not a bad thing from a security standpoint, in many cases it might be overkill and limiting to those with restricted access to updated software (in this case - browsers). In these instances I would strongly suggest disabling those redirects.
+
+## HTTPS is (Mostly) Overrated
+
+Don't bust out the torches and pitchforks just yet. Websites and applications storing data, collecting user information or handling payments should **most definitely** use only HTTPS to serve all traffic. No one is arguing for a less secure web when it comes to sensitive data.
+
+Everyone still levelheaded? Good.
+
+My main issue with HTTPS redirects comes from it's overuse for simple content consumption (blogs, research papers, video essays etc). Websites that do not collect any user data or process any sensitive information. Applications that do not process payments or collect credit card details. Purely static, non-dynamic websites that only serve up text and media.
+
+"But what about sites like [https://doesmysiteneedhttps.com](https://doesmysiteneedhttps.com/)?" While this website makes a few valid points, it still relies heavily on "fear tactics" that honestly don't apply for the vast majority of users. It's overkill.
+
+I won't re-hash the counter-points brought up by others, but feel free to read through the discussion [on Hacker News](https://news.ycombinator.com/item?id=30150749).
+
+## Worse Performance
+
+Let's use my own personal blog as an example to compare both HTTPS and HTTP versions based on performance:
+
+| Site Version | Transferred Data | Seconds to Load |
+|--------------|------------------|-----------------|
+| HTTPS | 3.8 kB | 1.16 |
+| HTTP | 2.9 kB | 0.62 |
+
+
+By using HTTPS my website **increases it's overhead by almost 100%**. It should be mentioned that my personal website is also plain text based and tiny. Imagine the impact of a blog article or research paper with significantly more content. I understand that security is important - but so is performance. (And again, no user data is collected or payments processed on my personal blog).
+
+"What about SEO?" I hear some of you ask. I'm probably not the best person to answer this since I **don't give a shit about optimizing for search engines**. You shouldn't either. This is part of the reason why search results have become worthless over the past few years. Just make good, accessible content.
+
+Speaking of accessibility...
+
+## Human Accessible
+
+Another core issue I have with forced HTTPS is lack of accessibility. A great deal of the world doesn't have access to the latest or most up-to-date technologies. Some are stuck with decade old hardware running long forgotten software. You instantly exclude those users from accessing your content with no real gain. Users with supported software can still visit your website or application through HTTPS. The responsibility is placed on the users running the outdated software - not you.
+
+Let's take an example of the Powerbook G4, which was released in 2002. The OSX version of that device is limited to 10.5.8 and is not compatible with the modern TLS version used on most websites. Now I understand that this device is 20 years old but what happened to sustainable technology? A great deal of people pushing so hard for "HTTPS Everywhere!" are often times the same people advocating for a reduction in e-waste and rant about environmental issues.
+
+So why force users to toss away perfectly viable devices in favor of more expensive (did I mention some users don't have the luxury of upgrading?), modern machines? Why are we suddenly excluding demographics? Let users take on the risk if they so desire.
+
+Again, *you* shouldn't be making these decisions for them.
+
+## Disable the Redirects (But Keep HTTPS)
+
+It's important to remember I'm not advocating for disabling HTTPS *completely*. I'm simply suggesting you disable your website from *automatically* forwarding all HTTP requests to HTTPS. There is a pretty big difference there.
+
+**Helpful Tips**:
+
+- If users are nervous of links set in standard `http://` format, they can add `s` themselves or better yet, use a browser extension like [HTTPS Everywhere](https://addons.mozilla.org/en-CA/firefox/addon/https-everywhere/) (highly recommend)
+- Be sure to use relative URL structures in most of your web documents. Hard-setting HTTPS links will also make things more difficult and break things for unsupported users.
+- Avoid outsourcing 3rd party assets (fonts, imagery, scripts). Hosting all these yourself gives you the ability to serve everything via HTTP and HTTPS easily.
+- (Should be obvious) Keep all stored data, login portals, payment processing behind HTTPS-only. The security risks in those instances outweigh the ability to support those on older hardware/software.
+
+## Practice What You Preach
+
+You can freely view this website on both HTTPS and HTTP. All websites added will also be tested against this. Those that support both will be given a small badge beside their listed website. This addition will be rolled slowly over time - so please have patience if your website already supports it!
+
+---
+
+That's about all I have to say about HTTPS redirects for now. I'm sure this post will piss off quite a few people but that's fine. People have separate preferences when it comes to the web. My personal opinion is that we all jumped aboard the "secure everything" train a little too hastily. By doing so, your website indirectly excludes a great deal of internet users.
+
+Just something to think about. \ No newline at end of file
diff --git a/_posts/2022-07-09-macos-convert-to-html.md b/_posts/2022-07-09-macos-convert-to-html.md
new file mode 100644
index 0000000..065737c
--- /dev/null
+++ b/_posts/2022-07-09-macos-convert-to-html.md
@@ -0,0 +1,115 @@
+---
+title: "Convert Files to HTML with macOS Automator Quick Actions"
+layout: post
+summary: "Setting up macOS Automator scripts to convert files to HTML"
+---
+
+Since a few people have reached out and thanked me for my previous post [Batch Converting Images to webp with macOS Automator](/blog/batch-webp-conversion/), I thought I would continue to share more of my own custom Automator Quick Actions. Today's post will cover the ability to convert *any* text-based document into pure HTML.
+
+I know - there are over 6 billion conversion apps that do this very same thing. But our way of doing it is *cooler*. Our conversion tool:
+
+- Will run directly inside macOS Finder (right-click actions FTW)
+- Can batch convert multiple files at once
+- Can convert mixed files types at the same time
+
+And it can do all of this for free on your existing macOS system. No apps required. So, enough chit-chat, let's get started!
+
+## The Dependencies
+
+Unfortunately, setting things up isn't as simple as clicking a single `Install` button and calling it a day. But don't start to panic! I assure you everything we'll be doing is actually quite easy to breeze through - *trust me*.
+
+Our main requirements will consistent of the following:
+
+- Homebrew
+- Pandoc
+- Ability to open Terminal
+
+## Installing Homebrew
+
+Homebrew is a simple package manager for macOS. The beauty of having Homebrew is the flexibility in the future for installing other custom packages. Overall it's just a nice piece of software to have on your machine.
+
+If you have already installed Homebrew in the past, ignore this step and continue down the page. If not, simply open your Terminal and run:
+
+```
+/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+```
+
+Let that finish and you're done! Also feel free to read more about Homebrew on the [official website](https://brew.sh). Knowledge is power!
+
+## Installing Pandoc
+
+The package that is going to be doing all the heavy-lifting for us is [pandoc](https://pandoc.org). Because we have Homebrew on our machine now, installing this package is as simple as opening our Terminal again and running:
+
+```bash
+brew install pandoc
+```
+
+Wait for everything to finish and you're done!
+
+## Our Custom Automator Quick Action
+
+Next you'll want to open the macOS Automator app and create a new "Quick Action" when given the prompt to do so.
+
+<figure>
+ <img src="/public/images/new-automator.webp" alt="Toggle prompt for new automation in macOS Automator">
+ <figcaption>After opening Automator, select "Quick Action" from the menu.</figcaption>
+</figure>
+
+Now do the following (reference the image further below to make sure your parameters match):
+
+1. Set "Workflow receives current" to <strong>documents</strong> in <strong>any application</strong>
+2. In the search bar type in "Run Shell Script"
+3. Drag-and-drop the "Run Shell Script" from the left pane into the right pane
+4. Set the "Shell" parameter to <strong>/bin/bash</strong>
+5. Set "Pass input" as <strong>as arguments</strong>
+
+Once all that is done, simply paste the following in the open text field within the "Run Shell Script" item:
+
+```bash
+for f in "$@"
+do
+/opt/homebrew/bin/pandoc -o "${f%.*}.html" "$f"
+done
+```
+
+If you've done everything correctly it should look something like this:
+
+<figure>
+ <img src="/public/images/new-automator-2.webp" alt="Automator quick action details for converting to HTML">
+ <figcaption>This is what your finished Automator quick action should look like.</figcaption>
+</figure>
+
+Save this new Quick Action (Name is something like "Convert to HTML" to keep things simple). That's it! Amazing, right?
+
+## Time to Convert
+
+Now it is finally time to see our Quick Action is *action*! Navigate to any document file in a Finder window and follow along.
+
+1. First, right-click on the file you wish to convert. ([Figure 1](#fig-1))
+2. In the pop-up container, scroll down and hover over `Quick Actions`.
+3. A secondary pop-out will appear. Look for the action `Convert File to HTML` and click it. ([Figure 2](#fig-2))
+
+<figure id="fig-1">
+ <img src="/public/images/macos-convert-1.webp" alt="A markdown file in macOS Finder">
+ <figcaption><strong>Figure 1:</strong> Finding and right-clicking on your desired file.</figcaption>
+</figure>
+
+<figure id="fig-2">
+ <img src="/public/images/macos-convert-2.webp" alt="Convert to HTML action selection">
+ <figcaption><strong>Figure 2:</strong> From the "Quick Actions" menu, select "Convert to HTML".</figcaption>
+</figure>
+
+If everything was set up properly (and depending on the size of the file) you should see your converted HTML file show up right next to your existing document. Time to celebrate!
+
+Don't forget - you can also *batch* convert multiple files and multiple file *types* at once. The possibilities are endless!
+
+<figure>
+ <img src="/public/images/macos-convert-3.webp" alt="Finder window showing a Markdown file and an HTML file">
+ <figcaption>Our converted document is now available in HTML. Absolutely glorious.</figcaption>
+</figure>
+
+## No Limits
+
+Although this article has mainly focused on converting documents to HTML, `pandoc` is so powerful you could do any number of conversions. Re-using these steps above, you have the ability to make as many different conversion quick actions as your heart desires!
+
+Have fun converting!
diff --git a/_posts/2022-07-18-reflection.md b/_posts/2022-07-18-reflection.md
new file mode 100644
index 0000000..d3549e3
--- /dev/null
+++ b/_posts/2022-07-18-reflection.md
@@ -0,0 +1,39 @@
+---
+title: "Two Years and Over 700 Websites Later"
+layout: post
+summary: "Reflecting on the upcoming borthday for 1MB Club"
+---
+
+Although the second "birthday" of the 1MB Club is officially *November 19*, I couldn't help by write down some of my thoughts about this project over the past two years. I honestly have nothing but positive things to say and the amount of interest in this silly side project has been wonderful!
+
+## Some Fun Stats
+
+Let's take a look at some stats that don't mean anything of *real* importance (please note - these figures are based on stats collected at the time of writing):
+
+The **Github** repo has the following:
+
+- 290 stars
+- 197 forks
+- 391 commits
+- 246 contributors
+- 351 pull requests (all closed!)
+
+Some fun facts about the **website** itself:
+
+- 742 total members
+- Total size of all member websites combined: **169.4 MB**
+- Average member website size: **228.3 KB**
+- 8 [Hall of Fame](/#hof) members (thank you!)
+- 3 website redesigns since launch ([read more](/blog/club-updates/))
+- Switched hosting from Netlify to NearlyFreeSpeech.NET
+- Recently added a web-focused [blog](/blog)
+
+## Closing Thoughts
+
+I'm still passionate about making a leaner, more performance-based web. I still get excited seeing another member request pop into my inbox. I love getting to visit those submitted websites and discovering something *new* on the internet. Something I otherwise would have probably missed. It's a good reminder how truly massive the size of the internet is.
+
+I should also mention that the members who have requested to join have been nothing but nice. It's been great interacting with so many others who share the same passion for a "smaller" web footprint. My hope is to keep this collection growing for as long as I possibly can.
+
+Thanks for reading,
+
+-- Brad \ No newline at end of file
diff --git a/_posts/2022-10-26-html-tables.md b/_posts/2022-10-26-html-tables.md
new file mode 100644
index 0000000..b45894a
--- /dev/null
+++ b/_posts/2022-10-26-html-tables.md
@@ -0,0 +1,120 @@
+---
+title: "Customizing HTML Tables"
+layout: post
+summary: "A quick tutorial on how to manipulate tables for better data visualizations"
+---
+
+**Editor's note:** My plan is to have this article exist as a "living document". Corrections and additions will be made whenever it is deemed necessary. Last update: **October 26, 2022**
+
+---
+
+**I love working with HTML tables.**
+
+That isn't something you hear very often in the world of web development, especially from a *designer*. But it's true - I think HTML tables can be awesome. I believe their poor reputation is ill-deserved.
+
+Something I do notice however, whenever I stumble across tables in the wild, is the lack of experimentation or the use of more complex layouts. I've mentioned in a previous article on how to properly [design responsive tables with minimal CSS](/blog/responsive-tables/), so why not expand even further with more table design "tricks"?
+
+**Table of Contents**:
+
+1. [Sticky Table Headers](#sticky-table-headers)
+2. [Child Table Headers](#child-table-headers)
+3. [Table Footers](#table-footers)
+
+## Sticky Table Headers
+
+In the golden age of the web, developers needed to cobble together some JavaScript in order for table headings to "follow" the user as they scrolled. This was particularly useful for large datasets that took up enormous amounts of vertical space.
+
+Luckily for us this can now be achieved with some very basic CSS.
+
+```css
+table {
+ position: relative;
+}
+
+thead {
+ position: sticky;
+ top: 0;
+}
+```
+
+<p class="codepen" data-height="459" data-default-tab="result" data-slug-hash="oNygZXJ" data-user="bradleytaunt" style="height: 459px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/oNygZXJ">
+ HTML Tables: Sticky Table Headers</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
+
+That's it! Best of all, this implementation works across [all major browsers](https://caniuse.com/css-sticky).
+
+## Child Table Headers
+
+I find that "child" header columns are often underutilized when trying to display more detailed datasets in HTML tables. They are relatively easy to implement once you wrap your head around "rows" and "columns".
+
+Let's take a look at the basic HTML:
+
+```html
+<table>
+ <thead>
+ <tr>
+ <th rowspan="2">Table Header 1</th>
+ <th rowspan="2">Table Header 2</th>
+ <th colspan="2">Table Header 3</th>
+ <th rowspan="2">Table Header 4</th>
+ </tr>
+ <tr>
+ <th>Table Header 3.1</th>
+ <th>Table Header 3.2</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Table Body 1</td>
+ <td>Table Body 2</td>
+ <td>Table Body 3.1</td>
+ <td>Table Body 3.2</td>
+ <td>Table Body 4</td>
+ </tr>
+ </tbody>
+</table>
+```
+
+The two HTML parameters that makes the magic happen are `rowspan` and `colspan`. We are essentially telling the browser to make the `th` elements with `rowspan` parameters *taller* and those with `colspan` *wider*. If that oversimplified explanation seems silly, then the [official documentation will suit you better](https://www.w3schools.com/tags/att_td_rowspan.asp).
+
+It is important to remember that the `tbody tr` elements will outnumber the amount of listed `thead tr` elements. This is because the header with the child elements is technically "splitting" itself into additional columns. You can see a live example below:
+
+<p class="codepen" data-height="484" data-default-tab="result" data-slug-hash="rNKajyM" data-user="bradleytaunt" style="height: 484px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/rNKajyM">
+ HTML Tables: Child Table Header Columns</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
+
+## Table Footers
+
+Although not the most useful feature, I find that table footer elements are also overlooked for things like subtotals or final values. You can include these just as you would `thead` or `tbody` elements:
+
+```html
+<tfoot>
+ <tr>
+ <td>Table Footer 1</td>
+ <td>Table Footer 2</td>
+ <td>Table Footer 3</td>
+ <td>Table Footer 4</td>
+ </tr>
+</tfoot>
+```
+
+You can see it in action below. Don't forget - you could always make your `tfoot` *sticky* in order to always show your users a subtotal, etc. even when scrolling through the data.
+
+<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="MWXYpZX" data-user="bradleytaunt" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
+ <span>See the Pen <a href="https://codepen.io/bradleytaunt/pen/MWXYpZX">
+ HTML Tables: Table Footers</a> by Bradley Taunt (<a href="https://codepen.io/bradleytaunt">@bradleytaunt</a>)
+ on <a href="https://codepen.io">CodePen</a>.</span>
+</p>
+<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
+
+## Contribute
+
+If you would like to add any of your own table "hacks" or if you see any glaring mistakes, please reach out to me directly via [my public inbox](https://lists.sr.ht/~tdarb/public-inbox). Thanks!
+
+<br> \ No newline at end of file
diff --git a/_posts/2023-07-24-purge.md b/_posts/2023-07-24-purge.md
new file mode 100644
index 0000000..a4b7da7
--- /dev/null
+++ b/_posts/2023-07-24-purge.md
@@ -0,0 +1,46 @@
+---
+title: "Purging the 1MB Club"
+layout: post
+summary: "I finally got around to testing and purging 1MB Club member websites"
+---
+
+This project has been running for almost 3 years now, and I still enjoy adding more members to the club! The only issue is that I have never been great at ensuring the quality of the members remained consistent. This included removing dead links, sites that now forward to less-than-safe domains, etc.
+
+That all changes today!
+
+## The First Purge
+
+I wrote up a very crude script that checks the status of each existing club member's URL and flags those that error-out. After running the check I found I could remove over 60 websites that were either dead or broken.
+
+> **Note:** If you happen to notice your website has been incorrectly caught in the "purge-crossfire", then don't hesitate to shoot me an email letting me know! I'm only human after all.
+
+## Checking URL Script
+
+This `ruby` script is far from perfect but it works well for my own personal workflow. Feel free to steal this and tweak it for your own purposes as you see fit!
+
+```
+require 'httparty'
+require 'nokogiri'
+
+HTTParty::Basement.default_options.update(verify: false)
+
+response = HTTParty.get('https://1mb.club')
+
+document = Nokogiri::HTML(response.body)
+website_urls = document.css("#container tr")
+
+puts "Scanning website members URLs..."
+website_urls.each do |single_site|
+ begin
+ url = single_site.css("a.site").first.attribute("href").value
+ response = HTTParty.get(url, timeout: 4)
+ puts "Checking: " + url
+ rescue Exception
+ puts "<!-------- ERROR: " + url
+ end
+end
+```
+
+## More Posts to Come
+
+I have been slacking in terms of web-related content on this blog. My plan is to improve that and I even have a few outlines ready to go. I'll be sure to keep you all posted when something new is published!