<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Keith Williams</title>
        <link>https://keithwilliamsjr.com</link>
        <description>Keith Williams Jr. - Software engineer and designer</description>
        <lastBuildDate>Wed, 29 Apr 2026 09:16:09 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Keith Williams</title>
            <url>https://keithwilliamsjr.com/favicon.ico</url>
            <link>https://keithwilliamsjr.com</link>
        </image>
        <copyright>All rights reserved 2026</copyright>
        <item>
            <title><![CDATA[Focus vs Focus-within: The Battle for Attention on Your Web Page]]></title>
            <link>https://keithwilliamsjr.com/articles/focus</link>
            <guid isPermaLink="false">https://keithwilliamsjr.com/articles/focus</guid>
            <pubDate>Tue, 18 Apr 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Theres a lot to focus on in this one! 😂 Oh man that was a good one!!!!]]></description>
            <content:encoded><![CDATA[<h2>Focus on the details 👀</h2>
<p>CSS (Cascading Style Sheets) is a powerful tool that web developers use to control the layout and appearance of web pages. CSS provides a range of selectors that allow developers to target specific HTML elements and apply styling to them. Two selectors that are often used are the :focus and :focus-within selectors. While both selectors are used to target elements that have focus, they have different applications.</p>
<p>The :focus Selector
The :focus selector is used to target an element that currently has keyboard focus. This selector is often used to provide visual feedback to users when they interact with a web page using the keyboard. When an element has focus, it is highlighted, and any CSS styles applied to the :focus selector are applied to the element.</p>
<p>Here is an example of how the :focus selector can be used to style an input element:</p>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.form-group</span><span class="token pseudo-class">:focus-within</span></span> <span class="token punctuation">{</span>
  <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">2</span><span class="token unit">px</span> solid <span class="token hexcode color">#0066cc</span><span class="token punctuation">;</span>
  <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode color">#f2f2f2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>n this example, when any descendant element of the .form-group element has focus, the .form-group element will have a blue border and a light gray background color.</p>
<p>The key difference between :focus and :focus-within selectors is that the former targets only the element with focus, while the latter targets the element with focus as well as any of its descendants that have focus. This means that the :focus-within selector can be used to apply styling to multiple elements when any of their descendants have focus.</p>
<p>In conclusion, the :focus and :focus-within selectors are both useful for styling elements that have focus on a web page. The :focus selector targets the element with keyboard focus, while the :focus-within selector targets the element with focus as well as any of its descendants that have focus. Knowing the difference between these two selectors can help web developers apply the right styles to the right elements on a web page.</p>]]></content:encoded>
            <author>me@keithwilliamsjr.com (Keith Williams)</author>
        </item>
        <item>
            <title><![CDATA[Oh snaps!]]></title>
            <link>https://keithwilliamsjr.com/articles/oh-snap</link>
            <guid isPermaLink="false">https://keithwilliamsjr.com/articles/oh-snap</guid>
            <pubDate>Fri, 17 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[One Little Known CSS Feature: The Scroll Snap Property]]></description>
            <content:encoded><![CDATA[<p>CSS is a powerful language that allows designers and developers to create visually appealing and interactive web experiences. From basic styling to complex animations and transitions, CSS has a wide range of features and properties that can be used to create stunning web pages. However, there is one little known CSS feature that can take your web design skills to the next level: the scroll snap property.</p>
<p>The scroll snap property is a relatively new feature in CSS that allows you to create a smooth scrolling effect on web pages. This feature is particularly useful for pages with long scrolling content, such as image galleries or product listings, where users can easily get lost in the content. With the scroll snap property, you can create a snap-to-grid effect that makes it easier for users to navigate through the content.</p>
<p>How does it work?</p>
<p>The scroll snap property works by dividing the scrolling container into multiple snap points. Each snap point represents a specific location in the content, such as the start or end of an image or a specific product in a listing. When the user scrolls through the content, the scroll snap feature snaps the view to the nearest snap point, creating a smooth and seamless scrolling experience.</p>
<p>To use the scroll snap property in CSS, you need to define the scroll snap type and the scroll snap alignment. The scroll snap type defines the behavior of the snap points, such as whether they should be mandatory or optional, and the scroll snap alignment defines the position of the snap points within the scrolling container.</p>
<p>Here's an example:</p>
<pre class="language-css"><code class="language-css"><span class="token selector"><span class="token class">.container</span></span> <span class="token punctuation">{</span>
  <span class="token property">scroll-snap-type</span><span class="token punctuation">:</span> y mandatory<span class="token punctuation">;</span>
  <span class="token property">scroll-snap-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>In this example, we are defining a scrolling container with a vertical scroll snap type that is mandatory, meaning that the container will always snap to a snap point when the user scrolls through the content. We are also aligning the snap points to the center of the container.</p>
<p>The scroll snap property is a powerful yet little known CSS feature that can greatly improve the user experience on web pages with long scrolling content. By creating a snap-to-grid effect, you can make it easier for users to navigate through the content and find what they are looking for. So next time you're designing a page with lots of scrolling content, don't forget to try out the scroll snap property and take your web design skills to the next level!</p>]]></content:encoded>
            <author>me@keithwilliamsjr.com (Keith Williams)</author>
        </item>
        <item>
            <title><![CDATA[Knolling: Organize your space]]></title>
            <link>https://keithwilliamsjr.com/articles/knolling</link>
            <guid isPermaLink="false">https://keithwilliamsjr.com/articles/knolling</guid>
            <pubDate>Thu, 27 Apr 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Get Your Knoll on: How to Turn Your Clutter into a Work of Art (or at Least Something that Looks Instagram-Worthy)]]></description>
            <content:encoded><![CDATA[<img alt="" loading="lazy" width="1000" height="600" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fknolling.b110aa31.jpeg&amp;w=1080&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fknolling.b110aa31.jpeg&amp;w=2048&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fknolling.b110aa31.jpeg&amp;w=2048&amp;q=75">
<a href="https://images.app.goo.gl/3hxujhLtchEZHNAa6">Credit</a>
<h2>Theres a word for that?</h2>
<p>Knolling is a term used to describe the process of arranging objects in a parallel or 90-degree angle, giving them a clean and organized appearance. This technique is commonly used in photography, design, and architecture, but it can also be used in everyday life to keep your workspace neat and tidy.</p>
<p>The term "knolling" was first used by Andrew Kromelow, a janitor at Frank Gehry's furniture fabrication shop, who began arranging the tools and materials in a parallel grid-like pattern on a flat surface to make them easier to locate and access. The term "knolling" was later popularized by Tom Sachs, an American artist known for his meticulous attention to detail and focus on craftsmanship.</p>
<p>The process of knolling involves laying out items so that they are visually pleasing and easy to access. This is typically done by arranging them in a symmetrical or grid-like pattern, with each item spaced evenly apart from the others. The items are often organized by size, shape, or color to create a cohesive visual effect.</p>
<p>In addition to its aesthetic benefits, knolling can also improve productivity and efficiency. By organizing your workspace in this way, you can quickly locate the tools and materials you need, reducing the time spent searching for them. This can be especially useful in creative fields such as art, design, and architecture, where the ability to quickly access materials and tools can make a significant difference in the creative process.</p>
<p>Knolling can also be used as a tool for mindfulness and stress reduction. Taking the time to organize your workspace and create a visually pleasing arrangement can help you feel more in control of your environment and reduce feelings of stress and anxiety. This can be especially useful for people who work in high-stress environments or who have a tendency to feel overwhelmed by clutter and disorganization.</p>
<p>In conclusion, knolling is a useful technique for organizing your workspace and creating a visually pleasing arrangement of objects. Whether you are a designer, artist, or simply someone who wants to keep their workspace tidy, knolling can be a valuable tool for improving productivity, reducing stress, and enhancing your overall sense of well-being. So next time you find yourself surrounded by clutter, take a few minutes to try knolling and see how it can transform your space and your mindset.</p>]]></content:encoded>
            <author>me@keithwilliamsjr.com (Keith Williams)</author>
        </item>
        <item>
            <title><![CDATA[Jakob's Law: The Law of the Internet Jungle]]></title>
            <link>https://keithwilliamsjr.com/articles/jakobs-law</link>
            <guid isPermaLink="false">https://keithwilliamsjr.com/articles/jakobs-law</guid>
            <pubDate>Sun, 05 Mar 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[The art of making every website feel the same 🤝]]></description>
            <content:encoded><![CDATA[<img alt="" loading="lazy" width="1024" height="538" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fjakobs-law.652cdd96.png&amp;w=1080&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fjakobs-law.652cdd96.png&amp;w=2048&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fjakobs-law.652cdd96.png&amp;w=2048&amp;q=75">
<p>Jakob's Law is like the wild west of the internet - users have their six-shooters loaded with expectations from other websites, and they're ready to draw if your website doesn't meet those expectations. It's up to web designers and developers to cowboy up and understand what users want, so they can create websites that are the quickest draw in the west, but also unique enough to stand out from the crowd of other websites on the range.</p>
<h2>Jakob knows best</h2>
<p>In the wild and wacky world of the internet, users have become accustomed to certain standards of design and functionality. These standards have been shaped by years of experience, and they are now so ingrained that users expect them to be present in every website they visit. This is where Jakob's Law comes in.</p>
<p>Jakob's Law is a simple yet powerful principle that states that users spend most of their time on other websites, and therefore, they expect your website to work in the same way. In other words, users expect your website to conform to the standards set by other websites in your industry or niche.</p>
<p>This law may seem straightforward, but it has profound implications for web designers and developers. If your website is too different from what users expect, they may become frustrated and leave. On the other hand, if your website is too similar to other websites, you may be seen as unoriginal or uninspired.</p>
<p>So, how can you strike the right balance? The key is to understand your users and what they expect from your website. This requires research, testing, and a willingness to adapt and evolve as your users' needs change over time.</p>
<p>For example, if you're designing a website for an e-commerce store, users will expect to see a shopping cart icon in the top right corner of the screen. If you're designing a social media platform, users will expect to see a news feed with posts from their friends and followers. By understanding these expectations, you can design a website that is both familiar and unique.</p>
<p>In conclusion, Jakob's Law is a powerful principle that can help you design websites that meet the expectations of your users. It reminds us that the internet is a jungle, and users have evolved to expect certain standards of design and functionality. By understanding these expectations and adapting to them, you can create a website that stands out from the crowd while still feeling familiar and intuitive. So, the next time you're designing a website, remember to follow the law of the internet jungle.</p>]]></content:encoded>
            <author>me@keithwilliamsjr.com (Keith Williams)</author>
        </item>
        <item>
            <title><![CDATA[Shopify Functions: The Secret Sauce to Spice Up Your E-commerce Game!]]></title>
            <link>https://keithwilliamsjr.com/articles/shopify-functions</link>
            <guid isPermaLink="false">https://keithwilliamsjr.com/articles/shopify-functions</guid>
            <pubDate>Wed, 13 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Shopify Functions: Supercharging Your Store with Custom Logic (No Capes Required)]]></description>
            <content:encoded><![CDATA[<img alt="" loading="lazy" width="1634" height="1200" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fshopify-functions-flow.004e8eba.png&amp;w=1920&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fshopify-functions-flow.004e8eba.png&amp;w=3840&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fshopify-functions-flow.004e8eba.png&amp;w=3840&amp;q=75">
<a href="https://shopify.dev/docs/apps/build/functions">Credit</a>
<h2>Shopify Functions: Customization, Code, and Superpowers</h2>
<p>Ah, Shopify. The friendly neighborhood platform that lets anyone build an online store faster than you can say "Add to cart!" But what if you want to go beyond the standard features and take full control over how your store behaves? Enter Shopify Functions—the secret sauce that lets developers supercharge their Shopify stores with custom logic.</p>
<h2>What Are Shopify Functions?</h2>
<p>Shopify Functions are the latest way to extend and customize your Shopify store. Think of them as your store's personal trainer—except instead of lifting weights, they lift custom logic into your store's checkout, pricing, discounts, and more.</p>
<p>Shopify Functions are different from traditional Shopify apps because they run on Shopify's servers. This makes them faster than a caffeine-fueled coder at 3 AM and allows them to scale with your store's needs without breaking a sweat.</p>
<p>Think of Shopify Functions like your favorite playlist: flexible, customizable, and able to bring a smile to your face (or in this case, a smile to your store's checkout page).</p>
<h2>When Should You Use Shopify Functions?</h2>
<p>Ever wanted to create custom pricing rules, add dynamic discounts, or offer "buy one, get one free… but only on Tuesdays if the customer's name starts with an 'S'"? Then Shopify Functions are your new best friend. They're designed for:</p>
<ul>
<li>Checkout customizations: Change the rules at checkout like a true cart ninja.</li>
<li>Dynamic discounts: Serve up deals more personalized than your morning playlist.</li>
<li>Complex pricing logic: Adjust prices based on things like order volume or the phase of the moon. (Okay, maybe not that last one… yet.)</li>
</ul>
<h2>Getting Started with Shopify Functions</h2>
<p>To get started with Shopify Functions, you'll need to brush up on a few essentials. But don't worry, it's not like learning a new dance on TikTok—though it might make you just as popular among merchants!</p>
<p>Since Shopify Functions are basically custom apps with some flavor, you'll go through the same flow:</p>
<ol>
<li>Install Shopify CLI: Think of it as your superhero cape that lets you interact with Shopify projects effortlessly.</li>
<li>Set up a custom app: If you haven't created a Shopify app before don't worry—it's easier than explaining what NFTs are to your grandparents. You'll be creating a custom app that houses your Shopify Function.</li>
<li>Write your Function: I mean this the whole point you're doing this thing, right?</li>
</ol>
<p>Once you're all set up, it's time to write some code!</p>
<h2>Example: Creating a Custom Discount Shopify Function</h2>
<p>Let's create a Shopify Function that applies a 10% discount when the total cart quantity exceeds 5 items. It's simple, effective, and makes customers feel like they're getting a <em>steal of a deal</em> 🤑. Here's brief look at the main script code:</p>
<pre class="language-js"><code class="language-js"><span class="token comment">// @ts-check</span>
<span class="token keyword module">import</span> <span class="token imports"><span class="token punctuation">{</span> <span class="token maybe-class-name">DiscountApplicationStrategy</span> <span class="token punctuation">}</span></span> <span class="token keyword module">from</span> <span class="token string">"../generated/api"</span><span class="token punctuation">;</span>

<span class="token comment">// Use JSDoc annotations for type safety</span>
<span class="token doc-comment comment">/**
 * <span class="token keyword">@typedef</span> <span class="token class-name"><span class="token punctuation">{</span><span class="token keyword module">import</span><span class="token punctuation">(</span><span class="token string">"../generated/api"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>RunInput<span class="token punctuation">}</span></span> <span class="token class-name">RunInput</span>
 * <span class="token keyword">@typedef</span> <span class="token class-name"><span class="token punctuation">{</span><span class="token keyword module">import</span><span class="token punctuation">(</span><span class="token string">"../generated/api"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>FunctionRunResult<span class="token punctuation">}</span></span> <span class="token class-name">FunctionRunResult</span>
 * <span class="token keyword">@typedef</span> <span class="token class-name"><span class="token punctuation">{</span><span class="token keyword module">import</span><span class="token punctuation">(</span><span class="token string">"../generated/api"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Target<span class="token punctuation">}</span></span> <span class="token class-name">Target</span>
 * <span class="token keyword">@typedef</span> <span class="token class-name"><span class="token punctuation">{</span><span class="token keyword module">import</span><span class="token punctuation">(</span><span class="token string">"../generated/api"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>ProductVariant<span class="token punctuation">}</span></span> <span class="token class-name">ProductVariant</span>
 */</span>

<span class="token doc-comment comment">/**
 * <span class="token keyword">@type</span> <span class="token class-name"><span class="token punctuation">{</span>FunctionRunResult<span class="token punctuation">}</span></span>
 */</span>
<span class="token keyword">const</span> <span class="token constant">EMPTY_DISCOUNT</span> <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">discountApplicationStrategy</span><span class="token operator">:</span> <span class="token maybe-class-name">DiscountApplicationStrategy</span><span class="token punctuation">.</span><span class="token property-access"><span class="token maybe-class-name">First</span></span><span class="token punctuation">,</span>
  <span class="token literal-property property">discounts</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token doc-comment comment">/**
 * <span class="token keyword">@param</span> <span class="token class-name"><span class="token punctuation">{</span>RunInput<span class="token punctuation">}</span></span> <span class="token parameter">input</span>
 * <span class="token keyword">@returns</span> <span class="token class-name"><span class="token punctuation">{</span>FunctionRunResult<span class="token punctuation">}</span></span>
 */</span>
<span class="token keyword module">export</span> <span class="token keyword">function</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token parameter">input</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> totalQuantity <span class="token operator">=</span> input<span class="token punctuation">.</span><span class="token property-access">cart</span><span class="token punctuation">.</span><span class="token property-access">lines</span><span class="token punctuation">.</span><span class="token method function property-access">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">sum<span class="token punctuation">,</span> line</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> sum <span class="token operator">+</span> line<span class="token punctuation">.</span><span class="token property-access">quantity</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>totalQuantity <span class="token operator">&lt;</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">error</span><span class="token punctuation">(</span><span class="token string">"Not enough items for the discount"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword control-flow">return</span> <span class="token constant">EMPTY_DISCOUNT</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword control-flow">return</span> <span class="token punctuation">{</span>
        <span class="token literal-property property">discounts</span><span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token punctuation">{</span>
            targets<span class="token punctuation">,</span>
            <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token punctuation">{</span>
            <span class="token literal-property property">percentage</span><span class="token operator">:</span> <span class="token punctuation">{</span>
                <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token string">"10.0"</span><span class="token punctuation">,</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">]</span><span class="token punctuation">,</span>
        <span class="token literal-property property">discountApplicationStrategy</span><span class="token operator">:</span> <span class="token maybe-class-name">DiscountApplicationStrategy</span><span class="token punctuation">.</span><span class="token property-access"><span class="token maybe-class-name">First</span></span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>This function calculates the total quantity of items in the cart. If the quantity exceeds 5, it applies a 10% discount. Simple, right? You can tweak this logic to create more complex discount rules or even set up dynamic pricing based on customer behavior or product type.</p>
<p>Why Shopify Functions Are a Game-Changer</p>
<p>Shopify Functions don't just let you add custom logic; they let you do it fast. Because these functions run server-side on Shopify's own infrastructure, they are faster than refreshing Twitter for the latest memes. (Okay, maybe not that fast, but pretty close.)</p>
<p>The Perks:</p>
<ul>
<li>Less bloat: Instead of installing multiple apps for custom logic, you can use one streamlined function.</li>
<li>Better performance: Functions run directly on Shopify's servers, so you don't have to worry about slowing down your store.</li>
<li>Infinite possibilities: Well, almost. From dynamic discounts to custom checkout processes, Shopify Functions give you the flexibility to make your store truly your own.</li>
</ul>
<p>Essential Resources (AKA, Your Coding Lifeline)</p>
<p>Before you get too far down the coding rabbit hole, here are a few resources to keep handy:</p>
<ul>
<li><a href="https://shopify.dev/docs/apps/functions">Shopify Functions Documentation</a></li>
<li><a href="https://shopify.dev/docs/apps/tools/cli">Shopify CLI Documentation</a></li>
<li><a href="https://nodejs.org/en/docs/">Node.js Documentation</a></li>
</ul>
<p>Now you're equipped to go forth and function-ize your store! (Yes, we just made that a word.)</p>
<h2>Wrapping Up</h2>
<p>Shopify Functions are like the hidden gears behind a smooth-running eCommerce machine. They give you the power to customize your store's logic in ways that weren't possible before—all while keeping your store faster than a shopping cart on Black Friday. So, the next time you want to impress your customers (and maybe even yourself), remember: it's all about function over form.</p>]]></content:encoded>
            <author>me@keithwilliamsjr.com (Keith Williams)</author>
        </item>
    </channel>
</rss>