<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bansal</title>
    <description>The latest articles on Forem by Bansal (@bansal).</description>
    <link>https://forem.com/bansal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F203302%2F8fdf8d42-4015-4c50-b98e-6a9f145ff1a7.png</url>
      <title>Forem: Bansal</title>
      <link>https://forem.com/bansal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bansal"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Bansal</dc:creator>
      <pubDate>Tue, 17 Feb 2026 12:06:34 +0000</pubDate>
      <link>https://forem.com/bansal/-35kp</link>
      <guid>https://forem.com/bansal/-35kp</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/bansal" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F203302%2F8fdf8d42-4015-4c50-b98e-6a9f145ff1a7.png" alt="bansal"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/bansal/turning-missing-avatars-into-a-design-opportunity-2ahl" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Turning Missing Avatars into a Design Opportunity&lt;/h2&gt;
      &lt;h3&gt;Bansal ・ Feb 17&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ui&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ux&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#design&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>ui</category>
      <category>ux</category>
      <category>design</category>
    </item>
    <item>
      <title>Turning Missing Avatars into a Design Opportunity</title>
      <dc:creator>Bansal</dc:creator>
      <pubDate>Tue, 17 Feb 2026 11:59:53 +0000</pubDate>
      <link>https://forem.com/bansal/turning-missing-avatars-into-a-design-opportunity-2ahl</link>
      <guid>https://forem.com/bansal/turning-missing-avatars-into-a-design-opportunity-2ahl</guid>
      <description>&lt;p&gt;We’ve all seen it — the awkward blank circle, the grey silhouette, or the predictable two-letter initials when someone hasn’t uploaded a profile photo.&lt;/p&gt;

&lt;p&gt;Missing avatars feel like a tiny detail, but they influence how polished a product appears. When an interface handles these moments thoughtfully, it feels intentional. When it doesn’t, it feels unfinished.&lt;/p&gt;

&lt;p&gt;While building UI components recently, I found myself wanting something better than initials.&lt;/p&gt;

&lt;p&gt;That’s how the mesh gradient placeholder idea began.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Initials
&lt;/h2&gt;

&lt;p&gt;Initial-based avatars are everywhere because they’re simple.&lt;/p&gt;

&lt;p&gt;But after working with dense lists and profile-heavy interfaces, the drawbacks become obvious. They look repetitive. They add visual noise. Multiple users with the same initials become indistinguishable. And visually, they feel purely functional rather than pleasant.&lt;/p&gt;

&lt;p&gt;When a screen fills with identical “JS” or “AK” bubbles, the placeholder stops helping.&lt;/p&gt;

&lt;p&gt;I wanted something that felt cleaner, more distinctive, and easier on the eyes.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Different Approach
&lt;/h2&gt;

&lt;p&gt;Instead of showing initials when an avatar is missing, I tried replacing them with soft mesh gradients.&lt;/p&gt;

&lt;p&gt;The idea was simple: map a gradient to the first letter of a name and keep it consistent. “A” always receives the same gradient, “B” another, and so on through the alphabet.&lt;/p&gt;

&lt;p&gt;This preserves recognizability while making the interface feel more alive. The result doesn’t feel like a fallback — it feels like a design decision.&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.amazonaws.com%2Fuploads%2Farticles%2Fj0edaainjec7gwy7djux.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0edaainjec7gwy7djux.jpg" alt="Different Avatar Choices" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Mesh Gradients Work
&lt;/h2&gt;

&lt;p&gt;Mesh gradients have a softness that flat colors lack. They feel organic and modern without demanding attention. The gentle blending avoids harsh edges and sits comfortably within both light and dark themes.&lt;/p&gt;

&lt;p&gt;More importantly, they introduce variation without adding clutter. Instead of repeating identical shapes, the interface gains subtle depth and warmth.&lt;/p&gt;

&lt;p&gt;It’s a small change, but it removes the mechanical feel that placeholders often introduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Set That Feels Balanced
&lt;/h2&gt;

&lt;p&gt;To make this practical, I generated hundreds of mesh gradients and curated a set of twenty-six — one for each letter. The goal wasn’t randomness; it was harmony. Each gradient needed to feel calm, distinct, and consistent with the others.&lt;/p&gt;

&lt;p&gt;I used a &lt;a href="https://generate-mesh-gradient.vercel.app" rel="noopener noreferrer"&gt;mesh gradient generator&lt;/a&gt; to explore variations and refine the palette&lt;/p&gt;

&lt;p&gt;Once mapped to letters, missing avatars retained a visual identity without requiring any extra input from users.&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.amazonaws.com%2Fuploads%2Farticles%2F6q4bn3vuqq4sr04pqzpm.png" 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.amazonaws.com%2Fuploads%2Farticles%2F6q4bn3vuqq4sr04pqzpm.png" alt="twenty-six mesh gradients" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond Avatars
&lt;/h2&gt;

&lt;p&gt;After using gradients for avatars, I began noticing other places where the same idea worked just as well.&lt;/p&gt;

&lt;p&gt;Blog cards without thumbnails no longer looked broken. Link previews and OG images felt complete instead of empty. Even loading states felt calmer when a subtle gradient filled the space.&lt;/p&gt;

&lt;p&gt;These small adjustments improved the visual rhythm of the interface. Nothing felt missing; everything felt intentional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing for Interfaces with People
&lt;/h2&gt;

&lt;p&gt;If you’re building anything centered around people — comments, teams, founder communities like &lt;a href="https://pitchwall.co" rel="noopener noreferrer"&gt;PitchWall&lt;/a&gt;, or collaboration tools — identity cues become important very quickly. When many profiles appear together, identical placeholders blur into each other. Subtle gradient variations provide differentiation without adding labels, badges, or extra visual clutter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing for Absence
&lt;/h2&gt;

&lt;p&gt;Good interface design isn’t only about what is present. It’s also about how the system behaves when something is missing.&lt;/p&gt;

&lt;p&gt;Users may never consciously notice avatar placeholders. But they do feel the difference between an interface that looks incomplete and one that feels thoughtfully finished.&lt;/p&gt;

&lt;p&gt;Sometimes, improving a product isn’t about adding more — it’s about handling the empty spaces better.&lt;/p&gt;

</description>
      <category>ui</category>
      <category>ux</category>
      <category>design</category>
    </item>
    <item>
      <title>pattern.css</title>
      <dc:creator>Bansal</dc:creator>
      <pubDate>Wed, 29 Apr 2020 05:48:47 +0000</pubDate>
      <link>https://forem.com/bansal/pattern-css-2l23</link>
      <guid>https://forem.com/bansal/pattern-css-2l23</guid>
      <description>&lt;p&gt;Last week I made CSS only library to fill empty background with beautiful patterns.&lt;/p&gt;

&lt;p&gt;Features&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only CSS. No JavaScript!&lt;/li&gt;
&lt;li&gt;&amp;lt; 1KB minified and gzipped!&lt;/li&gt;
&lt;li&gt;Supports all modern browsers&lt;/li&gt;
&lt;li&gt;Built Using SCSS.&lt;/li&gt;
&lt;li&gt;Full color control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Documentation and demo: &lt;a href="https://bansal.io/pattern-css" rel="noopener noreferrer"&gt;https://bansal.io/pattern-css&lt;/a&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/bansal-io/pattern.css" rel="noopener noreferrer"&gt;https://github.com/bansal-io/pattern.css&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you enjoy this product and please let us know what you think.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>css</category>
      <category>design</category>
    </item>
    <item>
      <title>I made this css framework</title>
      <dc:creator>Bansal</dc:creator>
      <pubDate>Tue, 07 Apr 2020 06:05:32 +0000</pubDate>
      <link>https://forem.com/bansal/i-made-this-css-framework-1ddm</link>
      <guid>https://forem.com/bansal/i-made-this-css-framework-1ddm</guid>
      <description>&lt;p&gt;Hello devs,&lt;br&gt;
Last month I launched first version of shorthand css framework. Although I'm still working to make it better, but you can give your feedback.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/shorthandcss/shorthand" rel="noopener noreferrer"&gt;https://github.com/shorthandcss/shorthand&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>github</category>
      <category>css</category>
    </item>
    <item>
      <title>Serverless contact form handling for static websites</title>
      <dc:creator>Bansal</dc:creator>
      <pubDate>Mon, 29 Jul 2019 12:54:21 +0000</pubDate>
      <link>https://forem.com/bansal/serverless-contact-form-handling-for-static-websites-12md</link>
      <guid>https://forem.com/bansal/serverless-contact-form-handling-for-static-websites-12md</guid>
      <description>&lt;p&gt;When you’re making a static website, it means you don’t want to manage the server or want to save on costs. However, a static website can’t process contact forms, meaning you need a backend server to handle contact form requests. But if you need a server, then what is the logic of making a static website? So the simple solution is serverless contact forms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why go serverless?
&lt;/h2&gt;

&lt;p&gt;There are many benefits of making serverless applications, but in short, the main benefits are easy setup, no management, and less cost (free).&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform Selection
&lt;/h2&gt;

&lt;p&gt;There are many ways to run serverless code like aws lambda, Google cloud functions, cloudflare workers. But I have selected the easiest way to run serverless code i.e. Google cloud functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloud.google.com/functions/" rel="noopener noreferrer"&gt;Google Cloud functions&lt;/a&gt; allows you to trigger a function via HTTPS Request. It can also be done with aws lambda, but you need to set up API Gateway additional to trigger the function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost
&lt;/h2&gt;

&lt;p&gt;Google cloud offers free 200,000 GHz-seconds of compute time, 5GB of Internet egress traffic, and 2 million invocations per month. &lt;br&gt;
&lt;a href="https://cloud.google.com/functions/pricing" rel="noopener noreferrer"&gt;https://cloud.google.com/functions/pricing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m using 256MB/0.4GHz runtime and it takes ~800ms to process a form.&lt;/p&gt;

&lt;p&gt;This free quota is too much to handle a contact form submission.&lt;/p&gt;

&lt;p&gt;0.4 x 0.8s = 0.32 GHz-seconds per invocation&lt;br&gt;
200,000 / 0.32 = 625,000&lt;/p&gt;

&lt;p&gt;You can handle 625,000 Successful form submissions per month for free*.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;*This is just a sample calculation and does not include email cost. Free resources are subjected to Google cloud policies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Create Project
&lt;/h3&gt;

&lt;p&gt;(If you don’t have a Google cloud account, create one then create project)&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.amazonaws.com%2Fuploads%2Farticles%2Fl9e1qn89vxncghjgf16j.png" 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.amazonaws.com%2Fuploads%2Farticles%2Fl9e1qn89vxncghjgf16j.png" alt="create project in google cloud account" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create Function
&lt;/h3&gt;

&lt;p&gt;Click on the menu icon on the left top corner. Scroll down and find Cloud Function under COMPUTE section.&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.amazonaws.com%2Fuploads%2Farticles%2Fu3n02165pnsczu2d9vtd.png" 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.amazonaws.com%2Fuploads%2Farticles%2Fu3n02165pnsczu2d9vtd.png" alt="Create Cloud function" width="800" height="375"&gt;&lt;/a&gt;&lt;br&gt;
Then click on the ‘&lt;em&gt;Create Function&lt;/em&gt;’ button.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Configure Cloud function
&lt;/h3&gt;

&lt;p&gt;Set function name (contact-form).&lt;/p&gt;

&lt;p&gt;Allocate Memory (256MB is enough)&lt;/p&gt;

&lt;p&gt;Set Trigger ‘HTTP’ — it works for https also.&lt;/p&gt;

&lt;p&gt;Authentication is not required, so keep it checked to accept unauthenticated requests.&lt;/p&gt;

&lt;p&gt;Source code can be added inline or ZIP file can be uploaded. You can find zip file here &lt;a href="https://github.com/bansal-io/serverless-contact-form/tree/master/dist" rel="noopener noreferrer"&gt;https://github.com/bansal-io/serverless-contact-form/tree/master/dist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have selected inline editor option here.&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.amazonaws.com%2Fuploads%2Farticles%2Fehwj0h0sh42qzv4ljpip.png" 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.amazonaws.com%2Fuploads%2Farticles%2Fehwj0h0sh42qzv4ljpip.png" alt="Configure Cloud function" width="800" height="923"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Add code to editor
&lt;/h3&gt;

&lt;p&gt;Open the repository &lt;a href="https://github.com/bansal-io/serverless-contact-form" rel="noopener noreferrer"&gt;https://github.com/bansal-io/serverless-contact-form&lt;/a&gt;&lt;br&gt;
Copy the code of &lt;code&gt;index.js&lt;/code&gt; and &lt;code&gt;package.json&lt;/code&gt; files and paste it to respective code editor tabs.&lt;/p&gt;

&lt;p&gt;In the field Functions, to execute type onSubmit&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.amazonaws.com%2Fuploads%2Farticles%2Fiiuhr8jzdgk4q03j0gpm.png" 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.amazonaws.com%2Fuploads%2Farticles%2Fiiuhr8jzdgk4q03j0gpm.png" alt="Import code" width="800" height="892"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Set Environment Variables
&lt;/h3&gt;

&lt;p&gt;All the Environment Variables Related to SMTP are required. The rest of the variables are optional. Check the configuration details &lt;a href="https://github.com/bansal-io/serverless-contact-form/#configure" rel="noopener noreferrer"&gt;https://github.com/bansal-io/serverless-contact-form/#configure&lt;/a&gt;&lt;br&gt;
Click on ‘&lt;em&gt;Create&lt;/em&gt;’ button and your function is ready.&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.amazonaws.com%2Fuploads%2Farticles%2Fhhi4px1kxj7gg40pp5ui.png" 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.amazonaws.com%2Fuploads%2Farticles%2Fhhi4px1kxj7gg40pp5ui.png" alt="Set Environment variables" width="800" height="965"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Instead of setting environment variables, you can also change the config values in &lt;code&gt;index.js&lt;/code&gt; file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Get http endpoint
&lt;/h2&gt;

&lt;p&gt;Once function is deployed, click on the function name (contact-form) then Trigger tab to find the url.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your url will look like this.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/FUNCTION_NAME" rel="noopener noreferrer"&gt;https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/FUNCTION_NAME&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can set this url in action attribute in your HTML form&lt;/p&gt;

&lt;p&gt;Here is a working example of contact form with Google cloud function &lt;a href="https://serverless-contact-form.netlify.com/" rel="noopener noreferrer"&gt;https://serverless-contact-form.netlify.com/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: This code allows to accept requests from any domain. To restrict this with your domain only, you can also change ‘Access-Control-Allow-Origin’ value from ‘*’ to ‘&lt;a href="https://your-website.com%E2%80%99" rel="noopener noreferrer"&gt;https://your-website.com’&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>serverless</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
