<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rock</title>
    <description>The latest articles on DEV Community by Rock (@rock-randy).</description>
    <link>https://dev.to/rock-randy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3996079%2F2b90273e-a9c9-460e-a119-848dc7d97163.png</url>
      <title>DEV Community: Rock</title>
      <link>https://dev.to/rock-randy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rock-randy"/>
    <language>en</language>
    <item>
      <title>Building a Fast Product Filter with Vanilla JavaScript</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Tue, 21 Jul 2026 04:51:37 +0000</pubDate>
      <link>https://dev.to/rock-randy/building-a-fast-product-filter-with-vanilla-javascript-5a71</link>
      <guid>https://dev.to/rock-randy/building-a-fast-product-filter-with-vanilla-javascript-5a71</guid>
      <description>&lt;p&gt;One of the easiest ways to improve an e-commerce store is by making it easier for customers to find what they're looking for. A slow or confusing filtering experience often leads to visitors leaving before they ever reach a product page.&lt;/p&gt;

&lt;p&gt;While working on a clothing store, I spent some time simplifying the product filtering experience. The goal wasn't to build a complex search engine—it was simply to let shoppers narrow products by size, color, and price without refreshing the page.&lt;/p&gt;

&lt;p&gt;The product data looked something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Slim Fit Jeans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;49.99&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;High Waist Skinny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;L&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Black&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;59.99&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Straight Leg Jeans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;S&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;44.99&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of writing separate logic for every filter, I created a single function that checks the active filter values and returns only the matching products.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;filterProducts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sizeMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colorMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;priceMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxPrice&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxPrice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sizeMatch&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;colorMatch&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;priceMatch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever a shopper changes one of the filters, the product list updates immediately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;size-filter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;renderProducts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;filterProducts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;renderProducts()&lt;/code&gt; function simply clears the existing product cards and displays the filtered results. Since everything happens in the browser, there's no need to reload the page, making the shopping experience feel much faster.&lt;/p&gt;

&lt;p&gt;A few things made the biggest difference during testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the filtering logic in one place instead of scattering conditions throughout the code.&lt;/li&gt;
&lt;li&gt;Store the current filter state in a single object so multiple filters work together naturally.&lt;/li&gt;
&lt;li&gt;Only re-render the product grid after filtering is complete.&lt;/li&gt;
&lt;li&gt;If you're adding a price slider, debounce the input so the page isn't constantly re-rendering while the user drags the handle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach scales surprisingly well for small and medium-sized catalogs. For larger stores, you can move the filtering logic to an API while keeping the same frontend structure.&lt;/p&gt;

&lt;p&gt;I used a similar pattern while working on a &lt;strong&gt;&lt;a href="https://frishay.com/collections/women-jeans" rel="noopener noreferrer"&gt;women's jeans&lt;/a&gt;&lt;/strong&gt; category, where shoppers typically want to narrow results by size, color, and budget before browsing individual products. Making those filters quick and responsive reduced unnecessary clicks and helped visitors get to the products they actually wanted much faster.&lt;/p&gt;

&lt;p&gt;The implementation itself isn't complicated. The challenge is keeping the experience simple enough that customers never have to think about how it works—they just find what they're looking for.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Build a Better Kids’ Clothing Store: A Simple JavaScript Size Filter That Improves Shopping Experience</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Mon, 20 Jul 2026 05:46:55 +0000</pubDate>
      <link>https://dev.to/rock-randy/build-a-better-kids-clothing-store-a-simple-javascript-size-filter-that-improves-shopping-50hg</link>
      <guid>https://dev.to/rock-randy/build-a-better-kids-clothing-store-a-simple-javascript-size-filter-that-improves-shopping-50hg</guid>
      <description>&lt;p&gt;Here’s a quick tip for any parent or developer building a small e-commerce site for kids’ clothes: &lt;strong&gt;size filters can make or break the user experience.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I was working on the product listing page for a clothing collection aimed at active boys, I noticed something. Parents weren't just browsing; they were on a mission. They wanted to filter by size immediately, and they wanted to see durable, comfortable fabrics at a glance.&lt;/p&gt;

&lt;p&gt;Here’s a simple, lightweight approach using vanilla JavaScript to create a dynamic filter for a "Boys Clothing" collection. No frameworks, just clean DOM manipulation.&lt;/p&gt;

&lt;p&gt;First, assume your HTML has a list of products, each with a &lt;code&gt;data-size&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;


Graphic Tee



Size: 5-6







Joggers



Size: 7-8




&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, a filter button group:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;All Sizes
5-6 Years
7-8 Years
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JavaScript logic is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.size-filter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.product-card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedSize&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;selectedSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. In under 20 lines, you give parents instant control. I used this exact pattern while building out a "Boys Clothing" section for a project. It’s perfect for a collection like the one on Frishay, where you want to quickly show school-ready outfits or playtime gear without clutter.&lt;/p&gt;

&lt;p&gt;The key takeaway? Keep the code minimal and the user goal clear. Active kids mean active parents; they don’t have time to scroll. Give them filters, and they’ll find that durable jogger set in seconds.&lt;a href="https://frishay.com/collections/boys-clothing" rel="noopener noreferrer"&gt;https://frishay.com/collections/boys-clothing&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Parenting Hack That Ended Our Daily Wardrobe Battles: Durable, Comfortable Boys’ Clothing That Kids Actually Want to Wear</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Mon, 20 Jul 2026 05:45:18 +0000</pubDate>
      <link>https://dev.to/rock-randy/the-parenting-hack-that-ended-our-daily-wardrobe-battles-durable-comfortable-boys-clothing-that-35n8</link>
      <guid>https://dev.to/rock-randy/the-parenting-hack-that-ended-our-daily-wardrobe-battles-durable-comfortable-boys-clothing-that-35n8</guid>
      <description>&lt;p&gt;Ever struggled to get your kid to actually &lt;em&gt;like&lt;/em&gt; what you pick out for them? I've been there. The "battle of the wardrobe" used to be a daily event in my house. Then I realized the secret isn't just about finding clothes that look good—it's about finding clothes that &lt;em&gt;work&lt;/em&gt; for their lifestyle.&lt;/p&gt;

&lt;p&gt;Here's what I learned from trial and error (and a few ruined shirts):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Fabric is Everything&lt;/strong&gt;&lt;br&gt;
For active kids, look for cotton blends with a bit of spandex. They stretch, breathe, and survive the playground. Avoid 100% stiff cotton for everyday wear—it restricts movement and fades fast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo3r77radbtg2l01afz8a.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo3r77radbtg2l01afz8a.webp" alt=" " width="360" height="360"&gt;&lt;/a&gt;&lt;strong&gt;2. The "Double Knee" Trick&lt;/strong&gt;&lt;br&gt;
Jeans with reinforced knees? Game changer. They last twice as long without looking worn out. Perfect for crawling, climbing, or just being a kid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Prints That Hide Stains&lt;/strong&gt;&lt;br&gt;
Dark patterns or camo prints are your best friend. Yes, they look cool, but they also mask grass stains and dirt between washes. A win-win.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjex6dvo8m8gzlltejk7.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjex6dvo8m8gzlltejk7.webp" alt=" " width="360" height="360"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;4. Layering Without the Bulk&lt;/strong&gt;&lt;br&gt;
Opt for lightweight hoodies and zip-up jackets. They're easy to take on and off (less arguing), and they pack small for trips.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The "Test Run" Rule&lt;/strong&gt;&lt;br&gt;
Before buying a full outfit, let them wear the shirt or pants for an hour at home. If they don't complain about tags, seams, or fit—you've found a winner.&lt;/p&gt;

&lt;p&gt;I've been curating a small collection of durable, stylish options for my own kids. If you're looking for reliable boys' clothing that checks all these boxes, I found some great picks at Frishay's Boys Clothing Collection. They focus on comfort and durability without sacrificing style.&lt;/p&gt;

&lt;p&gt;What's your go-to trick for dressing active kids? Drop it in the comments—I'm always looking for new hacks.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Versatile Polo: How to Style Men’s Polo Shirts for Any Occasion</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Sat, 18 Jul 2026 05:19:52 +0000</pubDate>
      <link>https://dev.to/rock-randy/the-versatile-polo-how-to-style-mens-polo-shirts-for-any-occasion-5bnb</link>
      <guid>https://dev.to/rock-randy/the-versatile-polo-how-to-style-mens-polo-shirts-for-any-occasion-5bnb</guid>
      <description>&lt;p&gt;If there’s one item every man should have in his wardrobe, it’s a polo shirt. It bridges the gap between casual and formal, making it perfect for everything from brunch to business casual meetings. Here’s how to make the most of this essential piece.&lt;/p&gt;

&lt;p&gt;First, choose quality materials. A good polo should be made from breathable cotton or a cotton-polyester blend that resists wrinkles. Look for a collar that stays crisp and a fit that’s tailored but not tight. I prefer polos with a two-button placket for a modern look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Femf9yqogcvaubo1o93pq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Femf9yqogcvaubo1o93pq.webp" alt=" " width="360" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a smart-casual outfit, pair a solid-colored polo with chinos and loafers. Add a leather belt for polish. Going for a relaxed vibe? Tuck it into dark jeans with sneakers. The key is balance: if the polo is bright, keep the rest neutral.&lt;/p&gt;

&lt;p&gt;I recently upgraded my collection with a few from Frishay, and I’m impressed by the variety—from classic pique to performance blends that wick moisture. They’re perfect for golf outings or casual Fridays at the office.&lt;/p&gt;

&lt;p&gt;Pro tip: Roll the sleeves once for a more athletic look. And don’t be afraid to experiment with stripes or subtle patterns—they add personality without being loud.&lt;/p&gt;

&lt;p&gt;Whether you’re dressing up or down, a polo shirt is your go-to. Explore the options at &lt;a href="https://frishay.com" rel="noopener noreferrer"&gt;Frishay&lt;/a&gt; and elevate your style effortlessly.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I Finally Stopped Buying Bad T-Shirts</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Fri, 17 Jul 2026 04:39:56 +0000</pubDate>
      <link>https://dev.to/rock-randy/how-i-finally-stopped-buying-bad-t-shirts-3681</link>
      <guid>https://dev.to/rock-randy/how-i-finally-stopped-buying-bad-t-shirts-3681</guid>
      <description>&lt;h1&gt;
  
  
  How I Finally Stopped Buying Bad T-Shirts
&lt;/h1&gt;

&lt;p&gt;For years, buying men's T-shirts felt like a gamble. Some looked great online but lost their shape after a couple of washes. Others were comfortable but fit like a tent. After wasting more money than I'd like to admit, I realized that finding a great T-shirt isn't about chasing trends—it's about knowing what to look for.&lt;/p&gt;

&lt;p&gt;Here are the things that have made the biggest difference for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the Fabric
&lt;/h2&gt;

&lt;p&gt;The fabric determines how a T-shirt feels, how long it lasts, and whether you'll actually enjoy wearing it.&lt;/p&gt;

&lt;p&gt;I usually look for cotton with a small amount of stretch. A little elastane helps the shirt keep its shape without sacrificing comfort. Soft ringspun or combed cotton is another feature worth paying attention to because it feels noticeably better than standard cotton, especially if you're wearing it all day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu6wsktubxuc0cj3iyv8e.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu6wsktubxuc0cj3iyv8e.webp" alt=" " width="600" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Chase Trends—Find the Right Fit
&lt;/h2&gt;

&lt;p&gt;The fit matters more than the logo or the brand.&lt;/p&gt;

&lt;p&gt;A good T-shirt should follow your body's shape without feeling restrictive. The shoulder seams should sit naturally on your shoulders, and the sleeves should end around the middle of your upper arm. If you're active or wear T-shirts to the gym, a slightly athletic fit tends to move better and feels less bulky.&lt;/p&gt;

&lt;p&gt;When the fit is right, even a plain T-shirt looks polished.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pay Attention to the Neckline
&lt;/h2&gt;

&lt;p&gt;It's a small detail, but it changes the overall look.&lt;/p&gt;

&lt;p&gt;Crew necks are the easiest choice because they work with almost everything. If you prefer something a little different, a subtle V-neck or scoop neck can create a cleaner silhouette without looking overdone. The important thing is avoiding necklines that are either too tight or too loose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Around Versatile Colors
&lt;/h2&gt;

&lt;p&gt;Instead of filling your wardrobe with bold prints, build a solid foundation first.&lt;/p&gt;

&lt;p&gt;White, black, navy, and grey are the colors I wear most because they work with almost everything. Once you have those covered, adding a few shades like olive, burgundy, or beige gives you more variety without making outfits harder to match.&lt;/p&gt;

&lt;p&gt;Simple colors tend to stay stylish much longer than graphic-heavy designs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take Care of Them Properly
&lt;/h2&gt;

&lt;p&gt;Even a quality T-shirt won't last if it's washed carelessly.&lt;/p&gt;

&lt;p&gt;Turning shirts inside out before washing helps preserve the fabric and color. I also prefer cold water and let them air dry whenever possible. It takes a little longer, but they stay in better condition for much longer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Difference Is in the Details
&lt;/h2&gt;

&lt;p&gt;I've realized that upgrading a wardrobe doesn't require buying dozens of new clothes. Sometimes replacing a few poor-quality basics with well-made essentials makes a bigger impact than following every fashion trend.&lt;/p&gt;

&lt;p&gt;Over the past several months, I've focused on buying fewer but better T-shirts, and getting dressed has become much easier. Everything matches, everything fits, and I don't have to think twice before heading out.&lt;/p&gt;

&lt;p&gt;If you're planning to refresh your collection, take a look at the men's T-shirts from Frishay. The collection focuses on comfortable fabrics, modern fits, and versatile colors that work for everyday wear.&lt;/p&gt;

&lt;p&gt;Sometimes the simplest pieces end up being the ones you wear the most.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Shared Wishlist App for Couples with Flask and SQLite</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Thu, 16 Jul 2026 06:42:49 +0000</pubDate>
      <link>https://dev.to/rock-randy/building-a-shared-wishlist-app-for-couples-with-flask-and-sqlite-7hi</link>
      <guid>https://dev.to/rock-randy/building-a-shared-wishlist-app-for-couples-with-flask-and-sqlite-7hi</guid>
      <description>&lt;p&gt;When you're in a relationship, keeping track of gift ideas for each other can be a fun but chaotic process. You might text links back and forth, forget what you've already seen, or struggle to find something that feels truly personal. Instead of letting those ideas get lost, why not build a simple shared wishlist app? This is a great beginner-to-intermediate project for sharpening your Flask skills, and it solves a real problem.&lt;/p&gt;

&lt;p&gt;We'll create a basic Flask app with SQLite where two people can log in, add items, mark them as purchased, and leave notes. Think of it as a private, collaborative list for anniversaries, birthdays, or just because.&lt;/p&gt;

&lt;p&gt;First, set up your environment. You'll need Flask and Flask-SQLAlchemy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;flask flask-sqlalchemy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a file called &lt;code&gt;app.py&lt;/code&gt;. We'll start with the database model. For a couple, we can keep it simple: one table for users and one for wishes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_for&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flash&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SQLAlchemy&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_login&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LoginManager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;login_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;login_required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;logout_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;your-secret-key-here&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SQLALCHEMY_DATABASE_URI&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sqlite:///wishlist.db&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SQLAlchemy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;login_manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LoginManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;login_manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init_app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wishes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Wish&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lazy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Wish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;purchased&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user.id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, add a route to display the wishlist. This is where the couple can see all their shared ideas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@login_required&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;wishes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Wish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wishes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;wishes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template is where the magic happens. In &lt;code&gt;templates/index.html&lt;/code&gt;, you can loop through wishes and show a toggle button for purchased status. Here's a snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{% for wish in wishes %}



{{ wish.title }}

    {% if wish.url %}
        View Item
    {% endif %}


{{ wish.note }}



        {{ 'Mark as Purchased' if not wish.purchased else 'Unmark' }}



{% endfor %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a minimal but functional start. You can expand it with categories, images, or even a shared calendar for gifting deadlines.&lt;/p&gt;

&lt;p&gt;The real value here is that you're not just coding for the sake of coding—you're building something that strengthens a relationship. It turns gift-giving into a collaborative, thoughtful experience rather than a last-minute scramble. And if you're looking for inspiration for actual gifts, you might check out curated collections like the one at Frishay for couple gifts, but the app itself is what makes the process personal.&lt;/p&gt;

&lt;p&gt;By the end, you'll have a fully functional app that you and your partner can use daily. It's a perfect weekend project that combines database design, authentication, and front-end logic. Plus, it's way more romantic than another CRUD tutorial.&lt;/p&gt;

</description>
    </item>
    <item>
      <title># Building a Lightweight Product Filter with Vanilla JavaScript</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Wed, 15 Jul 2026 06:32:43 +0000</pubDate>
      <link>https://dev.to/rock-randy/-building-a-lightweight-product-filter-with-vanilla-javascript-4gl4</link>
      <guid>https://dev.to/rock-randy/-building-a-lightweight-product-filter-with-vanilla-javascript-4gl4</guid>
      <description>&lt;h1&gt;
  
  
  Building a Lightweight Product Filter with Vanilla JavaScript
&lt;/h1&gt;

&lt;p&gt;While building a small e-commerce project, I wanted users to filter products instantly without refreshing the page. Instead of relying on a frontend framework, I opted for a simple solution using HTML data attributes, vanilla JavaScript, and a little CSS.&lt;/p&gt;

&lt;p&gt;The goal was straightforward: let visitors filter items by size while keeping the interface fast, responsive, and easy to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML Structure
&lt;/h2&gt;

&lt;p&gt;Each product card stores its information in &lt;code&gt;data-*&lt;/code&gt; attributes. This keeps the markup clean and makes filtering straightforward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"filters"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"filter-btn"&lt;/span&gt; &lt;span class="na"&gt;data-filter=&lt;/span&gt;&lt;span class="s"&gt;"all"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;All&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"filter-btn"&lt;/span&gt; &lt;span class="na"&gt;data-filter=&lt;/span&gt;&lt;span class="s"&gt;"small"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;S&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"filter-btn"&lt;/span&gt; &lt;span class="na"&gt;data-filter=&lt;/span&gt;&lt;span class="s"&gt;"medium"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;M&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"filter-btn"&lt;/span&gt; &lt;span class="na"&gt;data-filter=&lt;/span&gt;&lt;span class="s"&gt;"large"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;L&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-grid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-card"&lt;/span&gt; &lt;span class="na"&gt;data-size=&lt;/span&gt;&lt;span class="s"&gt;"medium"&lt;/span&gt; &lt;span class="na"&gt;data-style=&lt;/span&gt;&lt;span class="s"&gt;"cargo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Cargo Shorts
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"product-card"&lt;/span&gt; &lt;span class="na"&gt;data-size=&lt;/span&gt;&lt;span class="s"&gt;"large"&lt;/span&gt; &lt;span class="na"&gt;data-style=&lt;/span&gt;&lt;span class="s"&gt;"chino"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Chino Shorts
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- More product cards --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using data attributes means you can add new filter categories later without changing your overall structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Filtering Logic
&lt;/h2&gt;

&lt;p&gt;The filtering logic listens for button clicks and simply shows or hides product cards based on the selected size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterButtons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.filter-btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productCards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.product-card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;filterButtons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;productCards&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cardSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filterValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;cardSize&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;filterValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;filterButtons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation is intentionally minimal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No external libraries&lt;/li&gt;
&lt;li&gt;No virtual DOM&lt;/li&gt;
&lt;li&gt;No unnecessary complexity&lt;/li&gt;
&lt;li&gt;Easy to extend with additional filters like color, category, or brand&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding Smooth Transitions
&lt;/h2&gt;

&lt;p&gt;Instead of having products instantly disappear, a small transition creates a smoother user experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.product-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max-height&lt;/span&gt; &lt;span class="m"&gt;0.3s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.product-card.hidden&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These subtle animations make the interface feel much more polished without affecting performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Approach Works
&lt;/h2&gt;

&lt;p&gt;For many projects, especially smaller storefronts or internal dashboards, a lightweight solution is often the better choice.&lt;/p&gt;

&lt;p&gt;Some advantages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast page interactions&lt;/li&gt;
&lt;li&gt;Zero dependencies&lt;/li&gt;
&lt;li&gt;Easy debugging&lt;/li&gt;
&lt;li&gt;Beginner-friendly code&lt;/li&gt;
&lt;li&gt;Excellent browser support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because everything is driven by HTML data attributes, you can easily expand this approach to support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple filter groups&lt;/li&gt;
&lt;li&gt;Search functionality&lt;/li&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;li&gt;Category filtering&lt;/li&gt;
&lt;li&gt;Price ranges&lt;/li&gt;
&lt;li&gt;Combined filters&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Vanilla JavaScript is still an excellent choice for interactive UI components like product filtering. Unless your application truly requires a large framework, simple DOM manipulation can provide an experience that's fast, maintainable, and easy to understand.&lt;/p&gt;

&lt;p&gt;Sometimes the simplest solution ends up being the most reliable. This filtering pattern is reusable across almost any catalog or gallery, making it a handy technique to keep in your frontend toolbox.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Algorithm for the Perfect Casual Shirt: Fit, Fabric &amp; Function</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Tue, 14 Jul 2026 05:36:00 +0000</pubDate>
      <link>https://dev.to/rock-randy/the-algorithm-for-the-perfect-casual-shirt-fit-fabric-function-2h49</link>
      <guid>https://dev.to/rock-randy/the-algorithm-for-the-perfect-casual-shirt-fit-fabric-function-2h49</guid>
      <description>&lt;p&gt;Let's be honest: finding the perfect casual shirt can feel like debugging a complex piece of code. You have to test for multiple variables. But once you find the right one, it's a game-changer.&lt;/p&gt;

&lt;p&gt;Here's the algorithm I use:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Fit (The Most Important Variable)&lt;/strong&gt;&lt;br&gt;
A shirt should follow your body's contour without being tight. The shoulder seam should align with your shoulder bone. The sleeves should end at your wrist bone. If it's too loose, you look sloppy. Too tight, you look uncomfortable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Fabric (The Runtime Environment)&lt;/strong&gt;&lt;br&gt;
Cotton is the standard, but look for blends that offer breathability and wrinkle resistance. A little bit of elastane gives you stretch for movement. Linen is great for summer but wrinkles easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcq9rjkazlz4j9slfybxq.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcq9rjkazlz4j9slfybxq.webp" alt=" " width="600" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Style (The User Interface)&lt;/strong&gt;&lt;br&gt;
Consider the collar: a button-down collar is more casual, while a spread collar is slightly dressier. Pockets add utility, but a clean front is more modern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Color Palette (The API)&lt;/strong&gt;&lt;br&gt;
Neutrals (white, navy, grey) are your core functions. They work with everything. Then add a few accent colors (like olive or burgundy) for variety.&lt;/p&gt;

&lt;p&gt;I recently applied this logic and found a great collection of shirts that meet all these criteria. They're comfortable, durable, and look great for both work and weekends.&lt;/p&gt;

&lt;p&gt;Check them out: &lt;a href="https://frishay.com/collections/men-shirts" rel="noopener noreferrer"&gt;https://frishay.com/collections/men-shirts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's your go-to shirt style?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Perfect Men’s T-Shirt: A Simple Guide to Fit, Fabric, and Timeless Style</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Mon, 13 Jul 2026 11:15:05 +0000</pubDate>
      <link>https://dev.to/rock-randy/the-perfect-mens-t-shirt-a-simple-guide-to-fit-fabric-and-timeless-style-277g</link>
      <guid>https://dev.to/rock-randy/the-perfect-mens-t-shirt-a-simple-guide-to-fit-fabric-and-timeless-style-277g</guid>
      <description>&lt;p&gt;Let's talk about the humble t-shirt. It's the backbone of every guy's wardrobe, but finding the perfect one can be surprisingly tricky. I've gone through my fair share of t-shirts that shrunk after one wash, lost their shape, or just didn't feel right.&lt;/p&gt;

&lt;p&gt;Over time, I've figured out what to look for. First, the fabric. A good quality cotton or a cotton blend is essential. It should feel soft against your skin but durable enough to withstand regular wear and washing. Second, the fit. You want something that's not too tight and not too baggy. A modern fit that skims your body without being restrictive is ideal.&lt;/p&gt;

&lt;p&gt;Style-wise, the options are endless. Solid colors like navy, black, and white are timeless and go with everything. But don't be afraid to experiment with patterns or subtle textures. A well-chosen t-shirt can elevate a simple outfit of jeans and sneakers.&lt;/p&gt;

&lt;p&gt;Another tip: pay attention to the neckline. A crew neck is classic, but a V-neck can add a bit of variety. And for goodness sake, make sure the sleeves aren't too long or too short. It's the little details that make a big difference.&lt;/p&gt;

&lt;p&gt;If you're on the hunt for some new tees, our collection has a variety of modern designs and high-quality fabrics. You'll find something for everyday wear, workouts, or just hanging out.&lt;/p&gt;

&lt;p&gt;Browse the collection here: &lt;a href="https://frishay.com/collections/men-t-shirts" rel="noopener noreferrer"&gt;Shop Men T-Shirts&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  fashion #style #menswear #t-shirts
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>The Ultimate Everyday Shirt Guide: Timeless Fits, Fabrics, and Styles for Men</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Mon, 13 Jul 2026 11:12:55 +0000</pubDate>
      <link>https://dev.to/rock-randy/the-ultimate-everyday-shirt-guide-timeless-fits-fabrics-and-styles-for-men-36g2</link>
      <guid>https://dev.to/rock-randy/the-ultimate-everyday-shirt-guide-timeless-fits-fabrics-and-styles-for-men-36g2</guid>
      <description>&lt;p&gt;Shirts are a staple in any developer's wardrobe, but finding the right one can be tricky. I've spent years trying different fits, fabrics, and styles, and I've finally cracked the code. Here's what I've learned.&lt;/p&gt;

&lt;p&gt;First, fit is king. A shirt that's too baggy looks sloppy, while one that's too tight restricts movement. Look for a slim or regular fit that allows you to move your arms freely without pulling at the buttons. The shoulder seams should align with your shoulders, and the collar should fit comfortably—you should be able to slide two fingers inside.&lt;/p&gt;

&lt;p&gt;Fabric choice matters more than you think. Cotton is breathable and comfortable, but it wrinkles easily. If you're on the go, consider a cotton-poly blend or a wrinkle-resistant fabric. For a more polished look, Oxford cloth or chambray are great options. They're durable, versatile, and look good both tucked and untucked.&lt;/p&gt;

&lt;p&gt;Now, let's talk trends. Classic patterns like checks, stripes, and solid colors are always in style. But don't be afraid to experiment with subtle prints or textured fabrics. A light blue Oxford shirt is a must-have—it goes with everything from jeans to chinos to suits.&lt;/p&gt;

&lt;p&gt;Practical outfit ideas? For a casual day, pair a chambray shirt with dark jeans and sneakers. For a smart-casual look, tuck a checked shirt into khakis and add desert boots. And for those days when you need to look sharp, a white or light blue shirt with a blazer is a winner.&lt;/p&gt;

&lt;p&gt;If you're looking to refresh your shirt collection, I've been checking out the men's shirts at &lt;a href="https://frishay.com/collections/men-shirts" rel="noopener noreferrer"&gt;Frishay&lt;/a&gt;. They have a wide range of styles and fits that are both affordable and durable. It's a great place to start if you're building a versatile wardrobe.&lt;/p&gt;

&lt;p&gt;What's your go-to shirt for everyday wear? Share your favorites in the comments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Effortless Everyday Elegance: Refresh Your Wardrobe with Versatile Styles from Frishay</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Mon, 13 Jul 2026 11:07:45 +0000</pubDate>
      <link>https://dev.to/rock-randy/effortless-everyday-elegance-refresh-your-wardrobe-with-versatile-styles-from-frishay-2e2b</link>
      <guid>https://dev.to/rock-randy/effortless-everyday-elegance-refresh-your-wardrobe-with-versatile-styles-from-frishay-2e2b</guid>
      <description>&lt;p&gt;I've been trying to simplify my wardrobe without sacrificing style, and it's all about finding those key pieces that just work. For me, that means dresses that can go from a Zoom call to a dinner date with a change of accessories, and tops that are comfortable enough for a full day but still look put together. The modern woman's wardrobe needs to be flexible. I've been really into soft fabrics and cuts that flatter without being fussy. Seasonal trends are fun, but I'm more interested in pieces that build confidence. A great pair of trousers or a well-fitted blouse can make you feel unstoppable. I've been shopping around and found a collection that nails this balance of trendy and timeless. It's full of versatile outfits that are both comfortable and fashion-forward. If you're looking to refresh your everyday style with pieces that actually make you feel good, check this out: &lt;a href="https://frishay.com/collections/women-clothes" rel="noopener noreferrer"&gt;https://frishay.com/collections/women-clothes&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Find the Perfect Pair of Women's Jeans</title>
      <dc:creator>Rock</dc:creator>
      <pubDate>Fri, 10 Jul 2026 06:16:00 +0000</pubDate>
      <link>https://dev.to/rock-randy/how-to-find-the-perfect-pair-of-womens-jeans-470k</link>
      <guid>https://dev.to/rock-randy/how-to-find-the-perfect-pair-of-womens-jeans-470k</guid>
      <description>&lt;p&gt;Ever found yourself staring at a pair of jeans in your closet, wondering if they’re actually &lt;em&gt;the one&lt;/em&gt;? I’ve been there. After years of trial and error, I’ve learned that the perfect pair of women’s jeans isn’t just about the brand—it’s about matching the cut to your body type and lifestyle. Let’s break down the three most common fits and how to style them, with a little help from my latest obsession.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Skinny Jeans: The Timeless Classic&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Skinny jeans are a wardrobe staple for good reason. They hug your curves from hip to ankle, making them ideal for pairing with oversized sweaters or structured blazers. Pro tip: Look for a mid-rise with a bit of stretch (try 2% elastane). For a casual look, tuck in a graphic tee and add white sneakers. Need a dressier vibe? Swap the sneakers for ankle boots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ed54ivhlgazeee3bbuw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ed54ivhlgazeee3bbuw.webp" alt=" " width="360" height="360"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;2. Straight-Leg Jeans: The Comfort Hero&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you’re tired of feeling squeezed, straight-leg jeans are your best friend. They offer a relaxed fit through the thigh without being baggy. I love these for running errands or working from home. Style them with a tucked-in blouse and a belt to define your waist. For a modern twist, roll the hem to show off your favorite loafers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Bootcut Jeans: The Retro Comeback&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Bootcut jeans are making a huge comeback, and they’re incredibly flattering. The slight flare balances out wider hips and elongates your legs. Wear them with heeled boots or chunky platform sneakers. A fitted turtleneck or cropped jacket completes the silhouette.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Fit Matters More Than Brand&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I’ve tried premium denim that felt like cardboard and budget pairs that felt like butter. The secret is in the fabric composition. Look for a blend of cotton, polyester, and elastane for that “second skin” feel. And always check the rise—high-waisted styles (10-12 inches) are universally flattering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Current Go-To&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I recently discovered a collection that nails all three fits without breaking the bank. The women’s jeans at &lt;a href="https://frishay.com/collections/women-jeans" rel="noopener noreferrer"&gt;Frishay&lt;/a&gt; have a surprisingly soft hand feel and come in washes that don’t fade after one wash. Their straight-leg pair is my new weekday uniform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Code Tip&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you’re building a product filter for a denim store, here’s a simple function to sort by rise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jeans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;039&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;High&lt;/span&gt; &lt;span class="nx"&gt;Rise&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;039&lt;/span&gt;&lt;span class="p"&gt;;,&lt;/span&gt; &lt;span class="na"&gt;rise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;039&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;Mid&lt;/span&gt; &lt;span class="nx"&gt;Rise&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;039&lt;/span&gt;&lt;span class="p"&gt;;,&lt;/span&gt; &lt;span class="na"&gt;rise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;039&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;Low&lt;/span&gt; &lt;span class="nx"&gt;Rise&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;039&lt;/span&gt;&lt;span class="p"&gt;;,&lt;/span&gt; &lt;span class="na"&gt;rise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;byRise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jeans&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rise&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rise&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The right jeans make you feel unstoppable. What’s your go-to fit? Let me know in the comments.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
