<?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: Gulshan</title>
    <description>The latest articles on DEV Community by Gulshan (@gzamann).</description>
    <link>https://dev.to/gzamann</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%2F163364%2F8ce3d995-cf61-4502-b7a0-8cde832dff70.jpg</url>
      <title>DEV Community: Gulshan</title>
      <link>https://dev.to/gzamann</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gzamann"/>
    <language>en</language>
    <item>
      <title>Retro desktop website - show-and-tell</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Tue, 24 Feb 2026 04:18:22 +0000</pubDate>
      <link>https://dev.to/gzamann/retro-desktop-website-show-and-tell-1g1b</link>
      <guid>https://dev.to/gzamann/retro-desktop-website-show-and-tell-1g1b</guid>
      <description>&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/DPhrtzKFw8Y"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;This is a little show-and-tell, it's a retro desktop inspired website.&lt;/p&gt;

</description>
      <category>portfolio</category>
      <category>website</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>lights off - reading in dark with a flashlight [codepen]</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Sun, 25 Jan 2026 17:40:55 +0000</pubDate>
      <link>https://dev.to/gzamann/lights-off-reading-in-dark-with-a-torch-codepen-1af8</link>
      <guid>https://dev.to/gzamann/lights-off-reading-in-dark-with-a-torch-codepen-1af8</guid>
      <description>&lt;p&gt;Just for fun&lt;/p&gt;

&lt;p&gt;

&lt;iframe height="600" src="https://codepen.io/gulshancss/embed/raLGLjR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;


&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>css</category>
      <category>spongebob</category>
    </item>
    <item>
      <title>Design System with CSS</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Sun, 28 Dec 2025 15:35:15 +0000</pubDate>
      <link>https://dev.to/gzamann/design-system-with-css-5bbh</link>
      <guid>https://dev.to/gzamann/design-system-with-css-5bbh</guid>
      <description>&lt;h2&gt;
  
  
  Quick Summary
&lt;/h2&gt;

&lt;p&gt;If you have set out on using a design system for your website without the help of any popular framework or library but just pure CSS, then you've come to the right place.&lt;br&gt;
This is still relevant if you're using any javascript framework, including react.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;To begin with implementing a design system with CSS we should have it documented somewhere, maybe on Figma. We can then pick up those tokens and styles and starting working.&lt;/p&gt;

&lt;p&gt;What are the essentials?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Colors&lt;/li&gt;
&lt;li&gt;Typography&lt;/li&gt;
&lt;li&gt;Iconography&lt;/li&gt;
&lt;li&gt;Spaces&lt;/li&gt;
&lt;li&gt;Components&lt;/li&gt;
&lt;li&gt;Patterns/images/logos&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can use a open-source design system for this exercise. &lt;a href="https://carbondesignsystem.com/designing/kits/figma/#external-users" rel="noopener noreferrer"&gt;Carbon by IBM&lt;/a&gt; is one such open-source, well designed and documented design system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up design tokens
&lt;/h3&gt;

&lt;p&gt;Design tokens are important part of a design system's foundation, here's a &lt;a href="https://m3.material.io/foundations/design-tokens/overview" rel="noopener noreferrer"&gt;overview&lt;/a&gt; about design tokens from material. We can consider these as the source of truth whenever necessary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is important to scope everything under the design tokens and keeping exceptions and one-offs at the minimum, else we could end up with a design system (-system).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In CSS, we can setup these design tokens as variables (i.e. custom properties). Design tokens are usually available globally and thus we can define these variables at &lt;code&gt;:root&lt;/code&gt; pseudo-class like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:root {
  /* Colors */
  --color-bg: #FFF;
  --text-primary: #161616;
  --text-secondary: #525252;
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have all the design tokens set-up, we can proceed for application. Tokens that we have defined are the only possible values to be used anywhere in the styles and hardcoding values should be avoided in-order for the design system to succeed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application and usage patterns
&lt;/h3&gt;

&lt;p&gt;We can any model or patterns that we prefer in CSS, as long as we are referencing property values to the CSS variables we defined.&lt;br&gt;
Using utility classes is a common and popular method. We can also set styles directly to some of the HTML elements. For example, setting up a heading styles&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* common properties of headings */
h1, h2, h3, h4 {
  font-family: var(--font-family-heading);
  font-weight: var(--font-weight-heading);
}
/* typography h1 properties */
h1 {
  font-size: var(--font-size-heading-1);
  line-height: var(--line-height-heading-1);
  letter-spacing: var(--letter-spacing-heading-1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly we can set default styles for other semantic tags like a, img, p and others. This will most of our atom level components styled according to our design system and we won't need to add classes to for these elements across the codebase.&lt;br&gt;
For more complex components, we can start creating classes and use the design tokens there.&lt;/p&gt;

&lt;p&gt;These are some of the very basics of using a design system with plain CSS. We will talk more about the applications and best practices in the upcoming articles.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://carbondesignsystem.com/all-about-carbon/what-is-carbon/" rel="noopener noreferrer"&gt;https://carbondesignsystem.com/all-about-carbon/what-is-carbon/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://m3.material.io/foundations/design-tokens/overview" rel="noopener noreferrer"&gt;https://m3.material.io/foundations/design-tokens/overview&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>designsystem</category>
      <category>css</category>
      <category>design</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Ticket with CSS Grid [old codepen]</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Sat, 25 Oct 2025 15:43:35 +0000</pubDate>
      <link>https://dev.to/gzamann/ticket-with-css-grid-old-codepen-3k99</link>
      <guid>https://dev.to/gzamann/ticket-with-css-grid-old-codepen-3k99</guid>
      <description>&lt;p&gt;Made this pen for fun, a long time ago. Back when CSS Grid was new and I was trying to make everything with it. Fast coded this, hence no point looking at the code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grid Layout of dribble shot &lt;a href="https://dribbble.com/shots/4959941-Webinar-Tickets-Now-Available" rel="noopener noreferrer"&gt;https://dribbble.com/shots/4959941-Webinar-Tickets-Now-Available&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

&lt;iframe height="600" src="https://codepen.io/gulshancss/embed/pYrrmZ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;


&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>css</category>
      <category>fun</category>
    </item>
    <item>
      <title>Error Monitoring for Web Apps</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Mon, 22 Sep 2025 06:43:13 +0000</pubDate>
      <link>https://dev.to/gzamann/error-monitoring-for-web-apps-dni</link>
      <guid>https://dev.to/gzamann/error-monitoring-for-web-apps-dni</guid>
      <description>&lt;h2&gt;
  
  
  Summary💡
&lt;/h2&gt;

&lt;p&gt;Have you ever had an error reported by your web app users but found it difficult to track down or reproduce in your environment? Or do you wonder whether your users are happily using the new feature you just released?&lt;/p&gt;

&lt;p&gt;Adding an error monitoring or real user monitoring solution to your app could help you keep these things (and more) in check!&lt;/p&gt;

&lt;p&gt;In this article, let’s introduce some of the tools to help you do that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Error Monitoring? 🤔
&lt;/h2&gt;

&lt;p&gt;Here, we are discussing two different terms, error monitoring and real user monitoring (RUM). But what are these?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Monitoring&lt;/strong&gt; systems help you collect unexpected crashes and exceptions that occur in an app. They also provide a way to handle exceptions manually in the code and report them to the error monitoring system. These systems usually come with an interface where you can check the error logs along with more specific details such as operating system, browser, app version, sourcemap, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real User Monitoring&lt;/strong&gt; is a more comprehensive solution that not only tracks exceptions and crashes but also helps you analyze how a real user is interacting with your application and learn what affects their user experience. Different RUM solutions may offer various metrics and types of data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Almost every Error monitoring/RUM solution provider would have a blog section where you can learn more about these terms in detail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why do we need this? 🧐
&lt;/h2&gt;

&lt;p&gt;There are many scenarios where we may want to rely on these solutions to get the most accurate report from a user’s encounter with our app.&lt;/p&gt;

&lt;p&gt;A web app with a large number of users and a wide variety of hardware/software environments could be an ideal case. It is almost always impossible to have the same experience as the user who is facing an issue with their hardware and software.&lt;/p&gt;

&lt;p&gt;For example, a user with the Brave browser faces an issue that doesn’t occur in Chrome. This could be due to an unsupported browser API or a CSS property. Knowing the user’s device, browser, and browser version could help us resolve this much faster. (Some tools may even point out the exact code where the issue exists.)&lt;/p&gt;

&lt;p&gt;It is always great to let our users reach out to us directly for any &lt;strong&gt;feedback&lt;/strong&gt;, but we may not rely on that because &lt;strong&gt;our users may be confused, may not have the time to report, may be first-time users&lt;/strong&gt;, and may simply decide not to report it and avoid that feature or the app altogether.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solutions 🔨
&lt;/h2&gt;

&lt;p&gt;Here are some of the tools that I have been familiar with and used in frontend projects.&lt;/p&gt;

&lt;p&gt;Before we get confused between the similar-looking and functioning tools that all claim to be the best, it is perhaps good to know what we should look for. Here’s a list of some of the basic checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ease of use (user-friendly dashboard, navigating through the logs, finding the details you’re looking for)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for your application (frontend, backend)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error tracing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reports and insights&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pricing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sentry
&lt;/h3&gt;

&lt;p&gt;Sentry is one of the most popular and open-source platforms. It comes with good support for almost all types of application stacks. Apart from error monitoring, Sentry also emphasizes performance monitoring and some of the best debugging features.&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%2Fgcief3jebyrpsa87gh4y.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%2Fgcief3jebyrpsa87gh4y.png" alt=" " width="400" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Active open-source community support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy to integrate&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The most usable free plan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tons of free learning content (blog, youtube)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User feedback&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code coverage, error tracing in the source code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support across platforms and support for all major frontend frameworks&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bugsnag
&lt;/h3&gt;

&lt;p&gt;Bugsnag has been around since 2013 and is really simple and user-friendly. It has a good support for mobile apps as well.&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%2Fwjycydu7xgcjnejwb687.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%2Fwjycydu7xgcjnejwb687.png" alt=" " width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fun fact - Bugsnag is now acquired by Smartbear who provides an ecosystem of software testing tools including Cucumber (also acquired).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Simple and easy to use&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only the essential information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good support across platforms&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Datadog
&lt;/h3&gt;

&lt;p&gt;Datadog is an all-in-one solution for a whole range of monitoring and security products. It is more focused on network, cloud, and all backend-related monitoring.&lt;/p&gt;

&lt;p&gt;Out of all the other options available, Datadog would surely find itself at the bottom of the list when it comes to ease of use and user-friendliness.&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%2F2ee9bq5pq0qewlggiel9.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%2F2ee9bq5pq0qewlggiel9.png" alt=" " width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All-in-one solution for one subscription&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great support for backend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decent community support&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Honeybadger
&lt;/h3&gt;

&lt;p&gt;Known for its error tracking and uptime monitoring, Honeybadger comes with good support for all types of backend applications and minimal JavaScript support as well. It has been around for a long time, and I have seen my colleagues (backend devs) rely on it for any production issues/alarms, which makes it worth mentioning.&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%2For97w7jtujzgsvz5dp42.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%2For97w7jtujzgsvz5dp42.png" alt=" " width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Easy and reliable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrations with Slack, GitHub, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Getting started with a free plan 🍻
&lt;/h3&gt;

&lt;p&gt;To get started, consider trying out a few of these tools before hooking them up with your production app. Here’s a quick comparison of the free plans provided by these software tools.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Features&lt;/th&gt;
&lt;th&gt;Bugsnag&lt;/th&gt;
&lt;th&gt;Sentry&lt;/th&gt;
&lt;th&gt;Datadog&lt;/th&gt;
&lt;th&gt;Honeybadger&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Users&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error Monitoring&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alerts&lt;/td&gt;
&lt;td&gt;Weekly&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Retention/Display&lt;/td&gt;
&lt;td&gt;30 Days&lt;/td&gt;
&lt;td&gt;30 Days&lt;/td&gt;
&lt;td&gt;1 Day&lt;/td&gt;
&lt;td&gt;15 Days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error Limit&lt;/td&gt;
&lt;td&gt;7.5k&lt;/td&gt;
&lt;td&gt;50k&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;5k&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;We’ve briefly covered error monitoring for web applications. Each of these software/services has its pros and cons, and we can pick the one that fits best for our specific app.&lt;/p&gt;

&lt;p&gt;Thanks for reading! 👋&lt;/p&gt;

&lt;h3&gt;
  
  
  Links 🔗
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.bugsnag.com/" rel="noopener noreferrer"&gt;https://www.bugsnag.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://sentry.io/welcome/" rel="noopener noreferrer"&gt;https://sentry.io/welcome/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.datadoghq.com/" rel="noopener noreferrer"&gt;https://www.datadoghq.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.honeybadger.io/" rel="noopener noreferrer"&gt;https://www.honeybadger.io/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>errormonitoring</category>
      <category>rum</category>
      <category>debug</category>
      <category>testing</category>
    </item>
    <item>
      <title>Resources: Data Visualisation</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Mon, 22 Sep 2025 06:36:53 +0000</pubDate>
      <link>https://dev.to/gzamann/resources-data-visualisation-237n</link>
      <guid>https://dev.to/gzamann/resources-data-visualisation-237n</guid>
      <description>&lt;h2&gt;
  
  
  A plain list of libraries
&lt;/h2&gt;

&lt;p&gt;Here’s a simple list of the Data visualisation libraries that I came across. You can check these and decide for yourself based on your own likings and requirements. As per my experience, Echarts has been the top pick. It has some of the best documentation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://echarts.apache.org/en/index.html" rel="noopener noreferrer"&gt;Echarts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://d3js.org/" rel="noopener noreferrer"&gt;D3js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.chartjs.org/" rel="noopener noreferrer"&gt;Chartjs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.highcharts.com/" rel="noopener noreferrer"&gt;Highcharts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.react-simple-maps.io/" rel="noopener noreferrer"&gt;react-simple-maps&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://mui.com/x/react-charts/" rel="noopener noreferrer"&gt;mui/react-charts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://commerce.nearform.com/open-source/victory/" rel="noopener noreferrer"&gt;Victory&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.jwilber.me/roughviz/" rel="noopener noreferrer"&gt;roughviz&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.google.com/chart/interactive/docs/gallery" rel="noopener noreferrer"&gt;Google charts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://apexcharts.com/" rel="noopener noreferrer"&gt;Apex charts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://airbnb.io/visx" rel="noopener noreferrer"&gt;Visx&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://altair-viz.github.io/" rel="noopener noreferrer"&gt;Vega-Altair&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://flourish.studio/" rel="noopener noreferrer"&gt;https://flourish.studio/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://canvasjs.com/" rel="noopener noreferrer"&gt;https://canvasjs.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://chartkick.com/vue" rel="noopener noreferrer"&gt;https://chartkick.com/vue&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amcharts.com/" rel="noopener noreferrer"&gt;https://www.amcharts.com/&lt;/a&gt;&lt;a href="https://datavizcatalogue.com/about.html" rel="noopener noreferrer"&gt;l&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.datawrapper.de/" rel="noopener noreferrer"&gt;https://www.datawrapper.de/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://datavizproject.com/" rel="noopener noreferrer"&gt;https://datavizproject.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://primer.style/ui-patterns/data-visualization" rel="noopener noreferrer"&gt;https://primer.style/ui-patterns/data-visualization&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://atlassian.design/foundations/color-new/data-visualization-color" rel="noopener noreferrer"&gt;https://atlassian.design/foundations/color-new/data-visualization-color&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://fossheim.io/writing/posts/accessible-dataviz-design/" rel="noopener noreferrer"&gt;https://fossheim.io/writing/posts/accessible-dataviz-design/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://miro.com/app/board/uXjVMn3WomE=/?moveToWidget=3458764563299736588&amp;amp;cot=14" rel="noopener noreferrer"&gt;https://miro.com/app/board/uXjVMn3WomE=/?moveToWidget=3458764563299736588&amp;amp;cot=14&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.sarasoueidan.com/blog/accessible-data-charts-for-khan-academy-2018-annual-report/#how-accessible-are-svg-data-visualizations-%26-charts%3F" rel="noopener noreferrer"&gt;https://www.sarasoueidan.com/blog/accessible-data-charts-for-khan-academy-2018-annual-report/#how-accessible-are-svg-data-visualizations-%26-charts%3F&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.mapuipatterns.com/" rel="noopener noreferrer"&gt;Design Patterns For Effective Maps UX&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.learnui.design/tools/data-color-picker.html#palette" rel="noopener noreferrer"&gt;https://www.learnui.design/tools/data-color-picker.html#palette&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://m3.material.io/foundations/content-design/alt-text#10c74949-c9e0-46a4-bfd9-eca356430e7d" rel="noopener noreferrer"&gt;https://m3.material.io/foundations/content-design/alt-text#10c74949-c9e0-46a4-bfd9-eca356430e7d&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Bj6XeTg8srU&amp;amp;list=PLNSGxw-xV6Nd88myphRROrYhodrU3m8Hd&amp;amp;index=9" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Bj6XeTg8srU&amp;amp;list=PLNSGxw-xV6Nd88myphRROrYhodrU3m8Hd&amp;amp;index=9&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://visualizingthefuture.github.io/" rel="noopener noreferrer"&gt;https://visualizingthefuture.github.io/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.smashingmagazine.com/2024/02/accessibility-standards-empower-better-chart-visual-design/" rel="noopener noreferrer"&gt;https://www.smashingmagazine.com/2024/02/accessibility-standards-empower-better-chart-visual-design/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://chartability.github.io/POUR-CAF/" rel="noopener noreferrer"&gt;https://chartability.github.io/POUR-CAF/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=UuesXlalJdg" rel="noopener noreferrer"&gt;How to Create Truly Great Charts with NICK DESBARATS — SmashingConf Antwerp 2024&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.atlassian.com/data/charts" rel="noopener noreferrer"&gt;Mastering data charts by Atlassian&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>datavisualisation</category>
      <category>charts</category>
      <category>data</category>
      <category>frontend</category>
    </item>
    <item>
      <title>CSS Media Query in Javascript</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Mon, 22 Sep 2025 06:34:30 +0000</pubDate>
      <link>https://dev.to/gzamann/css-media-query-in-javascript-24ga</link>
      <guid>https://dev.to/gzamann/css-media-query-in-javascript-24ga</guid>
      <description>&lt;h2&gt;
  
  
  Quick Summary
&lt;/h2&gt;

&lt;p&gt;CSS media queries are very effective and optimal for applying styles based on device properties and settings. We’re going to look at a feature in javascript that let’s us use CSS media queries in our JS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s &lt;strong&gt;matchMedia?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;matchMedia&lt;/code&gt; is a method available on the &lt;code&gt;window&lt;/code&gt; object that can be used to match or track a CSS media query on the &lt;code&gt;document&lt;/code&gt;. Read more about it on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia" rel="noopener noreferrer"&gt;MDN&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax
&lt;/h2&gt;

&lt;p&gt;Taking a CSS media query for example&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="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;480px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lightgray&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;We would need what’s written after &lt;code&gt;@media&lt;/code&gt; as it is&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;matchMobileQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(max-width: 480px)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing it on the browser console, here’s what the matchMedia returns&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%2Fn9mt6bsoru537yxtwz6a.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%2Fn9mt6bsoru537yxtwz6a.png" alt="demo of using match-media to toggle theme" width="800" height="192"&gt;&lt;/a&gt;&lt;br&gt;
So we can take the &lt;code&gt;matches&lt;/code&gt; variable to check whether the query matched or not.&lt;/p&gt;

&lt;p&gt;To Track a media query, we can add a &lt;code&gt;change&lt;/code&gt; event listener on the same &lt;code&gt;MediaQueryList&lt;/code&gt; object given by the &lt;code&gt;matchMedia&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s test this with an example of &lt;code&gt;prefers-color-scheme&lt;/code&gt; media query&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;mediaQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;(prefers-color-scheme: dark)&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="nf"&gt;handleChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dark mode&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Light mode&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;mediaQuery&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;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should see a console log whenever the color scheme changes&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%2Fjti7l0r7w37tfqn5t0q9.gif" 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%2Fjti7l0r7w37tfqn5t0q9.gif" alt="Screenshot of matchmedia object from browser console" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To replace &lt;code&gt;window.innerWidth&lt;/code&gt; to find out what device we’re on&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace any element size tracking with &lt;code&gt;resizeObserver&lt;/code&gt;, if it can be solved with a media query&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s not just for screen size—use it to react to dark mode, device orientation, and more&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you made it till here, let’s hear your thoughts on this in the comments!&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>mediaquery</category>
      <category>matchmedia</category>
    </item>
    <item>
      <title>Phantom in Data Visualisation</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Wed, 17 Sep 2025 16:19:14 +0000</pubDate>
      <link>https://dev.to/gzamann/phantom-in-data-visualisation-1iai</link>
      <guid>https://dev.to/gzamann/phantom-in-data-visualisation-1iai</guid>
      <description>&lt;h2&gt;
  
  
  Quick Summary
&lt;/h2&gt;

&lt;p&gt;This article explores how to handle gaps in data and make sure your charts don’t quietly mislead. A must-read if you care about honest visual storytelling.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is The Phantom?
&lt;/h2&gt;

&lt;p&gt;Consider, the case of a line chart: where discrete data points are plotted along X and Y axes and connected to form a continuous line. Though the underlying grid may technically support an infinite number of coordinates, the chart typically displays only a finite set of values. The regularity of intervals between these points—along with axis labels and contextual annotations—enables the viewer to infer patterns and anticipate trends.&lt;br&gt;&lt;br&gt;
On occasion, there exists an unexpected discontinuity—a gap in the data. When such an absence occurs without explanation, it can render the chart misleading, implying continuity where none exists. These absent yet influential voids are termed as &lt;a href="https://www.atlassian.com/data/charts/line-chart-complete-guide#:~:text=be%20interpreted%20as-,phantom%20values,-if%20the%20line" rel="noopener noreferrer"&gt;phantom values&lt;/a&gt; by some.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why care?
&lt;/h2&gt;

&lt;p&gt;Missing data, if not clearly indicated, can lead to incorrect interpretations. In a line chart, for example, the absence of a data point may result in the line being drawn across the gap, implying continuity where none exists. This creates a visual distortion—subtle, but consequential—especially when the viewer assumes the data is complete. In the context of data visualisation, clarity about what is present and what is not is essential to avoid misrepresentation. Marking or addressing such gaps makes the chart more accurate and reduces the risk of false conclusions.&lt;/p&gt;

&lt;p&gt;To be precise, the goal is to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Avoid misinterpretation of the chart&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintain honest and transparent data visualisation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Caution the reader about the missing data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is the solution?
&lt;/h2&gt;

&lt;p&gt;We can not fill the missing data, however there are ways to handle this better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Display points on line
&lt;/h3&gt;

&lt;p&gt;Displaying point markers along the line emphasises the of data points. This visual cue helps distinguish real values from interpolated gaps, avoiding the illusion of completeness.&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%2Fk0vy5qfovwg91lg61n2h.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%2Fk0vy5qfovwg91lg61n2h.png" alt="Example line chart with an arrow pointing towards the visual data points on the line" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the gaps
&lt;/h3&gt;

&lt;p&gt;Leave the gaps visible, rather than interpolating the line, to accurately reflect the absence of data.&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%2F9p9i4f4viojf48ob3wy4.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%2F9p9i4f4viojf48ob3wy4.png" alt="Example of a line chart with a visible gap in between the line where the data is missing" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Highlight the missing data area
&lt;/h3&gt;

&lt;p&gt;Highlight the missing data and allow them to be distinct from the rest of the points.&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%2Fxu83nqzrd6jbnr0yryjf.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%2Fxu83nqzrd6jbnr0yryjf.png" alt="Example line chart with the missing data part being highlighted distinctly using a highlight colour" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Downplay the missing data area
&lt;/h3&gt;

&lt;p&gt;Use visual cues like faded colours or blur effects to indicate missing data segments.&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%2F7wvoph2abk4xilugjlts.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%2F7wvoph2abk4xilugjlts.png" alt="Example line chart with the missing data part being downplayed by fading the colour of the line" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use annotation for the missing data
&lt;/h3&gt;

&lt;p&gt;Annotations can be used to provide context for missing data or imputed values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Missing data in charts can lead to wrong conclusions if it isn’t handled properly. When a line connects across a gap, it may look like the data continues, even when it doesn’t.&lt;/p&gt;

&lt;p&gt;It’s important to make these gaps clear—whether by breaking the line, adding a marker, or showing a note. This helps keep the chart accurate and avoids confusion.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cmci.colorado.edu/visualab/papers/song_VIS_2018.pdf" rel="noopener noreferrer"&gt;https://cmci.colorado.edu/visualab/papers/song_VIS_2018.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://academy.datawrapper.de/article/321-patchy-data" rel="noopener noreferrer"&gt;https://academy.datawrapper.de/article/321-patchy-data&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.datawrapper.de/blog/connect-all-points-in-line-charts" rel="noopener noreferrer"&gt;https://www.datawrapper.de/blog/connect-all-points-in-line-charts&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.atlassian.com/data/charts/line-chart-complete-guide#:~:text=be%20interpreted%20as-,phantom%20values,-if%20the%20line" rel="noopener noreferrer"&gt;https://www.atlassian.com/data/charts/line-chart-complete-guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ux.stackexchange.com/questions/69738/design-pattern-to-display-missing-data-in-line-bar-chart-of-a-daily-data-feed" rel="noopener noreferrer"&gt;https://ux.stackexchange.com/questions/69738/design-pattern-to-display-missing-data-in-line-bar-chart-of-a-daily-data-feed&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dataviz</category>
      <category>charts</category>
      <category>visualisation</category>
    </item>
    <item>
      <title>Access Control in Web Apps: Backend + Frontend</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Wed, 17 Sep 2025 16:02:38 +0000</pubDate>
      <link>https://dev.to/gzamann/access-control-in-web-apps-backend-frontend-5fc8</link>
      <guid>https://dev.to/gzamann/access-control-in-web-apps-backend-frontend-5fc8</guid>
      <description>&lt;h2&gt;
  
  
  Quick Summary
&lt;/h2&gt;

&lt;p&gt;This article is an introduction and exploration of various types of Access Control solutions for a web application. Including the backend strategy and the frontend handling.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;&lt;em&gt;not a tutorial&lt;/em&gt;&lt;/strong&gt; post. We are briefly touching upon the &lt;strong&gt;&lt;em&gt;options and solutions available&lt;/em&gt;&lt;/strong&gt; and some &lt;strong&gt;&lt;em&gt;best practices&lt;/em&gt;&lt;/strong&gt;. You can use AI to help with implementation of a specific solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Access Control?
&lt;/h2&gt;

&lt;p&gt;In summary, Access Control is a security process or framework for your application that enables you to control the accessing and operating over the resources by the users.&lt;/p&gt;

&lt;p&gt;There are more detailed resources available on the basics of Access Control. For instance &lt;a href="https://www.osohq.com" rel="noopener noreferrer"&gt;OSO&lt;/a&gt; (an access control solution provider) provides some good knowledge resources that can be found &lt;a href="https://www.osohq.com/academy/what-is-authorization" rel="noopener noreferrer"&gt;here&lt;/a&gt;. And there are many other blogs, as well as youtube videos available.&lt;/p&gt;

&lt;h3&gt;
  
  
  History of Access Control in Software
&lt;/h3&gt;

&lt;p&gt;The history of Access Control systems goes back to the &lt;strong&gt;60s&lt;/strong&gt; and &lt;strong&gt;70s&lt;/strong&gt; when it was mainly developed and used by OS developers to manage access over data/files. With &lt;strong&gt;DAC&lt;/strong&gt; being used in UNIX and windows.&lt;/p&gt;

&lt;p&gt;Then comes the &lt;strong&gt;Mandatory Access Control (MAC),&lt;/strong&gt; initially used by the US Military and Government. It later became more mainstream and was adapted to make security tools and applications in Linux, MacOS and Windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Role-Based Access Control (RBAC),&lt;/strong&gt; a more familiar name comes along in the early 90s. RBAC is still around and is the most basic/standard type of access control system. In RBAC, we have predefined roles that can be assigned to users and the access permissions are attached to the roles. More about &lt;a href="https://csrc.nist.gov/projects/role-based-access-control/faqs#:~:text=What%20is%20the%20history%20of%20the%20RBAC%20systems%20used%20today%3F" rel="noopener noreferrer"&gt;history of RBAC here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Read more about the origins of these access control models &lt;a href="https://www.packetlabs.net/posts/a-comprehensive-guide-to-access-control-models" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Access Control
&lt;/h3&gt;

&lt;p&gt;Keep in mind, these are just methods, not a programming language or a feature. This means if someone creates a new variation of access control and names it, it would become a new type.&lt;/p&gt;

&lt;p&gt;In the context of Web Applications, here are the main types of access control models:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RBAC -&lt;/strong&gt; Role Based Access Control&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ABAC&lt;/strong&gt; &lt;strong&gt;-&lt;/strong&gt; Attribute Based Access Control&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PBAC&lt;/strong&gt; &lt;strong&gt;-&lt;/strong&gt; Policy Based Access Control&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To make things easier, I have listed only the most popular and commonly used types. One of these, or a combination, will likely suit your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices and Patterns
&lt;/h2&gt;

&lt;p&gt;Here are some best practices, standards and patterns to make sure the access control system is implemented properly&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralised authorisation layer -&lt;/strong&gt; access related logic should not be scattered around in the codebase but maintained in a dedicated authorisation layer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Principle of Least Privilege&lt;/strong&gt; - users must have only the minimum required permissions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deny by default&lt;/strong&gt; - no access unless explicitly granted&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Server-side enforcement&lt;/strong&gt; - never rely on client code (JS, HTML) to protect resources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access logs&lt;/strong&gt; - track and review access events for anomalies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separation of duties&lt;/strong&gt; - prevent single roles from having excessive combined powers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Policy as code&lt;/strong&gt; - manage authorization logic declaratively, versioned, and testable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Short-lived tokens / sessions&lt;/strong&gt; - reduce the window for misuse&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency&lt;/strong&gt; - ensure frontend reflects backend authorisation rules&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Handling Permissions in the Frontend
&lt;/h2&gt;

&lt;p&gt;Most of the heavy lifting around access control is relevant and possible only in the backend but when it comes to the frontend, we have to make sure to update the app to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Maintain good UX&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid unnecessary exposure and access attempts - displaying only relevant options to every user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure access to any static information is managed accordingly&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What are the essentials to handle in the frontend?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Show/hide options to the user based on their role and permissions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Receiving and storing roles and permissions from the backend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling the permissions in the code&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Here are some the questions we can ask to find an optimal frontend solution
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;How could we receive roles and permissions details from the backend?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is there a config API to add these details to? or can we include it in the auth API?&lt;/li&gt;
&lt;li&gt;Do we need a dedicated API for roles and permissions?&lt;/li&gt;
&lt;li&gt;Can we cache this API response?&lt;/li&gt;
&lt;li&gt;How do we make sure that we have the latest details whenever backend is updated?&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;How do we handle permissions in the UI code?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the best way to separate the access logic from UI? (Based on the frontend framework)&lt;/li&gt;
&lt;li&gt;How best can we make sure that it is scalable? (while making minimal or no changes to UI code)&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;What is the technical debt?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does the solution require deep integration?&lt;/li&gt;
&lt;li&gt;Does it depend on a particular backend structure?&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;After this you would have a better idea of what and how to implement access control in the frontend to reflect the backend rules and permissions. To keep things straight forward, here is a standard, scalable and high quality solution &lt;a href="https://casl.js.org/v4/en" rel="noopener noreferrer"&gt;CASL&lt;/a&gt;, that takes care of all the things we’ve discussed above and more.&lt;/p&gt;

&lt;p&gt;💡&lt;br&gt;
&lt;strong&gt;Pro tip&lt;/strong&gt;: Just like how you should not go coding your own state management in React thinking that &lt;code&gt;React Context = Redux&lt;/code&gt;, you should not go writing a access control solution from scratch unless you really know what you’re doing and understand everything about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The optimal access control solution for your application would depend on the requirements and other conditions, it could be a basic or a combination of different models. The article focused on the basics of access control and exploring on the possibilities, as well as some important principles and best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links to Knowledge Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.osohq.com/academy" rel="noopener noreferrer"&gt;https://www.osohq.com/academy&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://csrc.nist.gov/projects/role-based-access-control/faqs#:~:text=What%20is%20the%20history%20of%20the%20RBAC%20systems%20used%20today%3F" rel="noopener noreferrer"&gt;https://csrc.nist.gov/projects/role-based-access-control/faqs#:~:text=What%20is%20the%20history%20of%20the%20RBAC%20systems%20used%20today%3F&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.packetlabs.net/posts/a-comprehensive-guide-to-access-control-models/" rel="noopener noreferrer"&gt;https://www.packetlabs.net/posts/a-comprehensive-guide-to-access-control-models/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.paloaltonetworks.com/cyberpedia/what-is-the-principle-of-least-privilege" rel="noopener noreferrer"&gt;https://www.paloaltonetworks.com/cyberpedia/what-is-the-principle-of-least-privilege&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cyberark.com/what-is/least-privilege/" rel="noopener noreferrer"&gt;https://www.cyberark.com/what-is/least-privilege/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://goteleport.com/blog/authorization-best-practices/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;https://goteleport.com/blog/authorization-best-practices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.f5.com/company/blog/top-10-web-application-security-best-practices?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;https://www.f5.com/company/blog/top-10-web-application-security-best-practices&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>accesscontrol</category>
      <category>security</category>
      <category>role</category>
      <category>permissions</category>
    </item>
    <item>
      <title>Accessibility of Toggle Buttons</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Wed, 17 Sep 2025 15:53:43 +0000</pubDate>
      <link>https://dev.to/gzamann/accessibility-of-toggle-buttons-3ca9</link>
      <guid>https://dev.to/gzamann/accessibility-of-toggle-buttons-3ca9</guid>
      <description>&lt;h2&gt;
  
  
  Quick Summary
&lt;/h2&gt;

&lt;p&gt;A task of making a cool toggle button comes your way and you’re headed down the div lane. What happens next? Sounds like a crime thriller but it could actually be a nightmare for your users. Explore what is the best approach, how to ensure the button is accessible, and what could go wrong when you replace native HTML elements with artificial ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Toggle Button
&lt;/h2&gt;

&lt;p&gt;To begin making a toggle button or an icon button with toggle feature, the easiest and straight forward option is to use a div and style it according to the design. Like this button here&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/gulshancss/embed/NPGQvGo?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;We have a like button with a thumbs-up icon similar to what we see under social media posts, clicking it makes it active and clicking it again makes it inactive or reset. Works well visually and functionally. But right now, it has a few things missing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trap of Artificial Button
&lt;/h3&gt;

&lt;p&gt;Since we used a div and icon to make a toggle button, it does not have the properties of a native HTML button. Which means we would miss out on these built-in features&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Div&lt;/th&gt;
&lt;th&gt;Button&lt;/th&gt;
&lt;th&gt;Comment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tab indexing&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Using keyboard to navigate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Button label&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Users have to guess the usage by icon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keyboard support&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Spacebar support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default focus styles&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Browser doesn’t know if it is a button&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accessibility&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;⚠️&lt;/td&gt;
&lt;td&gt;Button is inherently more accessible but not totally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form features&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These issues could affect the user experience and they are easily be overlook if not tested specifically. Even if we notice and try to fix them, we would need to manually solve them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addressing Accessibility
&lt;/h3&gt;

&lt;p&gt;How do we solve the issues discussed above?&lt;/p&gt;

&lt;p&gt;Well, the best solution would be to use a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; element. Using button in place of the div will restore the built-in button features. This could affect the styles of the icon button due to the default button styles. All browser default button styles can be removed by using a CSS property &lt;code&gt;all: unset&lt;/code&gt;, but this property removes every default style, including the focus styles which we should still keep. Alternatively we can only update the styles that are affecting our button design, such as background, margin and border.&lt;/p&gt;

&lt;p&gt;Using a button, improves the element without any extra work. However, there are still a few more things to address&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It is still a generic button element and not a toggle button&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It still misses the label&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ARIA tags for A11y&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Toggle state&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using Labels to Clearly Describe the Button
&lt;/h3&gt;

&lt;p&gt;The purpose of a button must be clear to the user. An icon on its own may not be clear enough or even accessible. Icons are graphics made of lines and shapes, and their interpretation can be highly subjective. They also limit users to understanding the control only visually.&lt;/p&gt;

&lt;p&gt;Adding a descriptive label to the button improves accessibility, while showing the label on hover can enhance the overall user experience.&lt;/p&gt;

&lt;p&gt;Here’s a list of things to consider for button labelling&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Visible text label next to the icon - Ideally, just include a label if there’s no good reason to hide it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hidden text in the button - Add the text in a span beside the icon and hide it using CSS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using &lt;code&gt;aria-label&lt;/code&gt; - Use the &lt;code&gt;aria-label&lt;/code&gt; tag on the button to add a descriptive label&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tooltip on hover - Use a tooltip to show the label when the user interacts with the button&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Toggle State
&lt;/h3&gt;

&lt;p&gt;Now we have the button more accessible and working fine. But what about the toggle state? Is it accessible to every user yet? Maybe we can see it visually as the design and styles change after it is clicked and we have the state in our JS probably. But how does the browser know in which state the button is currently? So how would users with assistive tech know the state?&lt;/p&gt;

&lt;p&gt;This is where the aria-pressed tag comes in to help. It is meant for using as a state indicator for toggle buttons. We can set the current toggle state of the button in this tag like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;aria-pressed=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡Pro-tip: Do not confuse the user by changing the content of the button when toggled. Also mentioned in MDN docs &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-pressed" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Downsides of Not Using Native Button
&lt;/h2&gt;

&lt;p&gt;Replacing any native HTML element comes with its downsides. Native elements are recognised by the browsers and include a lot of important properties that help with a consistent cross-browser behaviour and accessibility.&lt;/p&gt;

&lt;p&gt;Although we don’t have a dedicated toggle button in HTML but by using a generic button element with proper labels and pressed state, we can get close to the best possible solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;A quick checklist for toggle/icon buttons&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Basic button features (by browser)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Descriptive button label&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accessibility tags&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Toggle state&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Links to resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://design.sis.gov.uk/components/toggle-button/" rel="noopener noreferrer"&gt;https://design.sis.gov.uk/components/toggle-button/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3.org/WAI/ARIA/apg/patterns/button" rel="noopener noreferrer"&gt;https://www.w3.org/WAI/ARIA/apg/patterns/button&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-pressed" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-pressed&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/button_role#icon_buttons" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/button_role#icon_buttons&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>a11y</category>
      <category>toggle</category>
      <category>html</category>
    </item>
    <item>
      <title>TL;DR: Baseline</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Tue, 30 Jul 2024 18:17:37 +0000</pubDate>
      <link>https://dev.to/gzamann/tldr-baseline-4l48</link>
      <guid>https://dev.to/gzamann/tldr-baseline-4l48</guid>
      <description>&lt;h2&gt;
  
  
  What is Baseline? 💭
&lt;/h2&gt;

&lt;p&gt;Web Platform Baseline has been around since 2023, as you can see Una Kravets talk about it at Google I/O 23 in the video below.&lt;/p&gt;

&lt;p&gt;Baseline's purpose is to let the developers know if a new hot feature is ready to use in their project right now.&lt;/p&gt;

&lt;p&gt;It will also help developers discover some interesting and really useful features that are already shipped in the modern browsers.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/gkAYHomO5Hg?start=259"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Browser set 🧭
&lt;/h3&gt;

&lt;p&gt;Baseline includes these browsers as the core browser set. So once a feature (except limited availability feature) is in baseline, we can expect it to work in all these browser without having to check for cross-compatibility.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Chrome (desktop and Android)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Edge&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Firefox (desktop and Android)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safari (macOS and iOS)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Three stages of Baseline 🥽
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Newly Available&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Newly available features are available in the latest browser versions but are still &lt;strong&gt;new&lt;/strong&gt; and may not be supported by the older devices or browsers.&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%2Fudyqk40b4eethlf4s8ca.jpeg" 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%2Fudyqk40b4eethlf4s8ca.jpeg" alt=" " width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Widely Available&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Widely available features are well established features in all the browsers and have been available from more than 30 months ago. These are the most safe to use features from Baseline.&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%2Fao12i53rtupiki6oer0p.jpeg" 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%2Fao12i53rtupiki6oer0p.jpeg" alt=" " width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Limited Availability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Limited availability shows that the feature is not yet available across all the core browsers.&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%2Fgse02l1h6mqigqww65nu.jpeg" 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%2Fgse02l1h6mqigqww65nu.jpeg" alt=" " width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Baseline Year 📅
&lt;/h3&gt;

&lt;p&gt;At the end of the year, all the features that became part of the Baseline in that year are compiled together. Like &lt;a href="https://web.dev/blog/baseline2023" rel="noopener noreferrer"&gt;https://web.dev/blog/baseline2023&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Platform Status 📝
&lt;/h3&gt;

&lt;p&gt;Baseline aims to solve the problem of developers trying to figure out a new feature and it's compatibility, interoperability and sometimes keeping track of a feature that developers would want to use but are still in development.&lt;/p&gt;

&lt;p&gt;We can now quickly track the features at &lt;a href="https://webstatus.dev/" rel="noopener noreferrer"&gt;Web Platform Status&lt;/a&gt; dashboard. It contains the entire web platform features with their browser support and baseline stage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn More 💡
&lt;/h3&gt;

&lt;p&gt;Watch Rachel Andrew's talk at Google I/O '24&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/W8bokbLn1G8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Hear Rachel Andrew talk about it at Smashing Podcast&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://open.spotify.com/embed/episode/2V2pBydelg6eB5yi4jDRAU" width="100%" height="232px"&gt;
&lt;/iframe&gt;
&lt;br&gt;
Check out &lt;a href="https://web.dev/baseline" rel="noopener noreferrer"&gt;https://web.dev/baseline&lt;/a&gt; for more resources.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>baseline</category>
      <category>webdev</category>
      <category>webplatformbaseline</category>
      <category>browser</category>
    </item>
    <item>
      <title>Resources: Learn Git</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Tue, 30 Jul 2024 17:02:34 +0000</pubDate>
      <link>https://dev.to/gzamann/resources-learn-git-kd6</link>
      <guid>https://dev.to/gzamann/resources-learn-git-kd6</guid>
      <description>&lt;p&gt;List of some of the best free resources to learn &lt;strong&gt;Git&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/gittutorial" rel="noopener noreferrer"&gt;Official website&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Fqu9lumzn4xzo8xrr5sxk.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%2Fqu9lumzn4xzo8xrr5sxk.png" alt="Screenshot of git-scm.com docs" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gitkraken.com/learn/git" rel="noopener noreferrer"&gt;Simplest and well organized&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Ftp9h9n29pyjxfyrcxe2j.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%2Ftp9h9n29pyjxfyrcxe2j.png" alt="Screenshot of gitkraken's learn git page" width="800" height="482"&gt;&lt;/a&gt;    &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.git-tower.com/learn/cheat-sheets/git" rel="noopener noreferrer"&gt;Cheat Sheet by git-tower&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Fl0smxcjh9drjai0ns1w9.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%2Fl0smxcjh9drjai0ns1w9.png" alt="screenshot of cheat sheet by git-tower containing some git commands" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.git-tower.com/learn/cheat-sheets/git-branches" rel="noopener noreferrer"&gt;branches cheat sheet by git-tower&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Fuc2sm2f8wzfd7529jufm.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%2Fuc2sm2f8wzfd7529jufm.png" alt="screenshot of cheat sheet by git-tower for git branch commands" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/git" rel="noopener noreferrer"&gt;Comprehensive guide by Atlassian&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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%2Ffhg1fg9w6uikyvablb3v.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%2Ffhg1fg9w6uikyvablb3v.png" alt="screenshot from Atlassian's learn git page" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Share in the comments what are your favorite sources to learn or reference git!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>learning</category>
      <category>cheatsheet</category>
    </item>
  </channel>
</rss>
