Skip to content

Semantic HTML: Why it matters and top tips on how to apply it

Semantic HTML: Why it matters and top tips on how to apply it

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

Semantic HTML: Why it matters and top tips on how to apply it

HTML is the backbone of the web, and while it may be overlooked quite often, it is an essential language to know if you want to be a web developer. HTML5 brought us some nice changes and gave us the possibility of writing more semantic code than before.

For clarification, code is “semantic” when you attribute more meaning to it using tags that have particular roles, instead of throwing everything inside divs and spans, and hoping for the best.

Why does Semantic HTML matter?

Writing semantic HTML makes your code easier to understand, making the source code more readable for other developers. Screen readers and browsers can interpret Semantic HTML better, which makes it more accessible.

It affects your page's SEO, giving it a better ranking on search engines weighing the most important content appropriately.

Now that you know what semantic HTML is and why to write your code with that in mind, here are some tips that you can easily apply to your daily code to leverage the benefits of semantic HTML.

Top Tips

The <div> tag has its uses, but think twice before using it. Chances are, there is a semantic alternative. Can we use a semantic tag instead?

<section>, for example, may be a good substitute. It’s a tag that defines elements in a document, such as chapters, headings, or any other area of the document with a common tag or <article>, that holds content that makes sense on its own like blog posts and comments.

Instead of using <span>, you can use <strong> or <em>, which will not only allow you to style your content differently, but will also give it semantic emphasis?

The <div> tag is commonly used to hold images, but instead we can use the <figure> tag. You can use this tag as a holder for media elements other than image as well, like illustrations, diagrams or code snippets, for example. A great complement to the <figure> tag is the <figcaption> tag that we can use to describe the content of the figure tag. If the figure gets moved, the fig-caption will move with it.

While using classes and IDs, be mindful about the names you choose, and be specific. A button with a class <button> doesn't give much context for another dev reading your code, while a button with a class of <download-button> will tell them that this button is related to a download.

Try to “read” your code, and see if it makes sense to you. A common web page structure is as we see below:

<header> 
<nav></nav>
</header>
<main></main>
<footer></footer>

If the flow of your tags make sense even without content, you are on the right track.

As you can see, using Semantic code has several benefits to your projects, making them more readable, accessible, and improving its ranking on search engines. And you can start using it today. All you need is to follow some tips, be mindful and of course, some practice, and soon it will become a habit.

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

How to add Dark Mode in your Web Application  cover image

How to add Dark Mode in your Web Application

How to Create Dark/Light Mode in your JavaScript project? Providing our visitors with the ability to toggle between white and dark themes has become one of the most important features of all time. In this article, we will cover the requirements to develop a persistent theme for your website successfully. The code provided as part of this article will be technology agnostic and can be used with all major front-end frameworks such as Vue, React, or Svelte. TL;DR If you are in a rush and just want access to the code, you can grab it from this Stackblitz: Light / Dark theme functionality in Vanilla JS. What is White/Dark Mode Before we jump into the code, we should first explain what the meaning behind the feature name "White/Dark Mode is". This feature was first introduced in our Operating system by allowing users to change their default theme into Dark Mode, After this, Dark Mode has slowly made its way into our most used applications and websites as users expected to have a consistent look from their native application to Web App equivalent. Providing "White/Dark mode" in your site means giving the user the ability to toggle their theme to either align to the Operating system theme settings or override it from the Web App UI. The above example shows the feature on thisdot.co triggered by the little toggle button available within the main navbar. Implementing Dark Mode with Javascript This feature has two main implementation levels. The first is the ability to assign the theme directly from the Operating System preferences, while the second combines the feature of the first plus the ability to override that feature from the UI. Some websites just offer the first option and allow the site to emulate the OS preferences, even if this is mostly fine for most users, in this post, we will develop the second option as it is the most complicated approach and, therefore the most complete. The development of this feature is going to be divided into the following steps: - Ensure CSS variables drive our application - Create a second set of variables for a dark theme - Create logic to read user preferences - Create logic to override the theme preference - Make our theme selection persistent Let's dive into the code with our first step and initialize our application. Move all styles into CSS variables We are going to start our application by initializing a plain VanillaJs Stackblitz. This creates a simple project with an index.js file that includes our HTML and a style.css file that includes our global styles. To be able to have a good starting point for our post, we are going to add some more elements on the main page of the app and then define some CSS variables to make our example more appealing. First, we are going to clean our index.js and just leave the style import: ` Then, we are going to change our index.html with the following content: ` And finally, define some CSS variables and styles in style.css: ` If you are new to CSS variables, you can read more about them in the MDN docs: Using CSS custom properties. There is one point to clarify regarding CSS variables and their naming convention. Because the color held within our variables will change (for example from red to blue), the variable name should be based on the color "role" (eg primary, shadow, border") and not on the actual color "blue, green". In our example, we can see this naming convention in action as the variables are called "primary", "secondary" and "background". The above should output a very simple but colorful design: Create a second set of variables for the dark theme Now that our basic application is set, it is time to create a second set of variables to be able to define the difference between the light and dark theme. As you may notice, the CSS variables are not a must for this to work, but having all the variables set makes the maintenance of the site much easier than having to update color and styles scattered around. We are returning to our style.css file and updating a few of the CSS properties. These variables will just be updated if the body has a specific class dark associated with it: ` As the above code shows, because we are just overriding the variables, we do not actually need to redeclare them all and we can just declare the variables that we wish to update. If we would go back and add a class of "dark" to our body in index.html we would see the following output: As you can see, both white themes are fully set up and working. All that is left is creating the logic that can handle the theme toggle, but before we do so, there is one more change to add to our CSS. In fact, some components, such as form controls and scrollbar, use a property called "color-scheme" to change their theme, to give this a try, we will add an in our HTML: ` Then, let's see how this would look in our design: The input is showing a white theme even if the dark theme is selected, and this is happening because we are not changing the "color-scheme" that is what is used for the form input. Let's fix this by adding another CSS variable and a CSS declaration within our body: ` With the above code, the "color-scheme" variable will be changed to align with our overall theme, as shown below: Note that settings can be overridden on a component-by-component level. In fact, if you would like to always display the white theme for a button or field, you can just redeclare the "color-scheme" and apply it to the CSS selection of your choice. It is now time to move forward and include some JS to make the toggling automatic. Create logic to read user preferences It is now time to write some JavaScript and make our application dynamic. In this first logical step, we are going to read our Operating System color preference and use it to toggle the class assigned to our body. To do so, we are going to use the "matchMedia" method to read the "prefer-color-scheme" just like shown in the code below: ` The next step is to assign or remove the class from our body depending on the preferred scheme: ` Let's see if this works. If you are on Mac you can change the preferences by following the following steps: 1) System settings 2) Appearance 3) Change the appearance If you change the preferences and refresh your application, you should be able to see the application changing on the fly. Create logic to override the theme preference Having to change the full OS just for a single Website theme preference may be a little bit too much. So, in this step, we are going to enhance our logic to be able to override the preferences. First, we are going to add a simple button in the HTML called Toggle Theme: ` Now, it is time to update the logic. First, we need to allow a way to override the preferences. We can do this by adding an argument to our updateScheme function: ` The above code just adds a global variable called selectedTheme and then, as we previously mentioned, adds a parameter of overrideScheme to our method and finally makes sure we use this variable if available selectedTheme = overriddenScheme || preferredScheme. The next step requires us to be able to update our selectedTheme on a button click: ` With the above code added to our application, we could override the system preferences, but unfortunately, our work is not completed. The logic we wrote above is not persistent, and the theme selection will be lost if we refresh the page. Make our theme selection persistent In this last step, we are going to save our selectedTheme in localStorage using the documentation provided in the MDN documentation: Local Storage. First, let's save the selectedTheme into local storage by using localStorage.setItem: ` Then make sure we read this value on load using localStorage.getItem: ` After the above changes, you should be able to toggle the theme, refresh the page and be able to see the correct theme loaded up for you. NOTE: Due to the way StackBlitz loads the JS, there will be a small flash, but if you would place this code in the head that flash should be extremely minimal. What about the images You may have noticed that we have left the image unchanged between the different themes. This was, unfortunately not by choice, as there is no native way to swap images when using class-based theming. If you were just to implement the theme based on System Preference, you could declare different images using the media query (prefers-color-scheme: dark). This would allow you to declare images like this: ` The above code will show day.jpg if your theme settings are light or night.jpg if dark. If you would like to implement something similar with a class-based theme, you will have to create a custom image component in your framework of choice that loads the correct theme, but this is outside this tutorial's scope. Conclusion It is now time to conclude this post and leave you to go and apply what we learned in your Web applications. Implementing this feature is quite simple, and it helps to improve your user's experience. The code we have written above is available on StackBlitz: Light / Dark theme functionality in Vanilla JS. But let's see it in action in: So, in this article, we have introduced CSS variables and ensured our design colors were driven solely by them. We created an override for this variable using a class-based approach; we then learned how some elements, such as input fields, can change the theme using the "color-theme" property. We then moved into the JS, where we used the media query "prefers-color-scheme" to read the user Operating System theme preferences and, last but not least, created a live toggle that would create and save a personal preference in LocalStorage....

State of A11y Wrap-up | April 19th, 2022 cover image

State of A11y Wrap-up | April 19th, 2022

In this wrap-up for State of A11y, we will talk about the key points presented by our hosts and panelists. I'll lay out who our hosts were and who was a part of our list of speakers. Our experts spoke about how we can improve developer tools like CMS' to improve the accessibility development process for those who use no-code tools. They also gave their thoughts on the top 1,000,000 homepages from an accessibility perspective; you can view that report here. In case you missed the event or want to rewatch, you can head over to Youtube to rewatch State of A11y otherwise, keep reading! First, here is a list of everyone who attended State of A11y: Hosts - Rob Ocell, Team Lead, and Software Architect, @robocell - Jesse Tomchak, Senior Software Engineer, @jtomchak Panelists - Anna E. Cook, Senior Accessibility Designer, Northwestern Mutual, @annaecook - Adrián Bolonio, Accessibility Software Engineer, GitHub, @bolonio - Amy Carney, Accessibility Specialist, Digilou, @click2carney - Amina Aweis, Accessibility Advocate and Founder of RecipeMate, @yeahshewrites - Albert Kim, Accessibility Lead, Korn Ferry, @djkalbert - Crystal Preston-Watson, Senior Digital Accessibility Analyst, Salesforce, @ScopicEngineer - Beatriz González Mellídez, Head of Accessibility & Digital Inclusion, Central Europe at Atos, @b_atish Accessibility is an after-thought for most, but why? In recent months, WebAIM released a report named "The WebAIM Million" which focuses on the state of accessibility for the top one million homepages. This report indicated a few key points that our panelists spoke about. Most websites being built in recent years are by those who might not be entirely technically inclined. The developers building these web pages might be using no-code solutions that don't entirely support the creation of web elements with accessibility in mind. On the other hand, out-sourcing development is not an uncommon practice. You might run into working with developers who haven't made web accessibility, a priority. This goes hand-in-hand with how accessibility has taken a back seat in development. The most common reason behind accessibility not being important is largely due to ignorance. If there was a focus on educating developers and creators (not excluding managers either), there would be a greater focus on making sure your websites work for every kind of person. A lack of education is one of the larger theories on why accessibility is lacking in most cases. The web does move fast; faster than it has in recent points in history. So many tools and websites are being created on a daily basis that often things like accessibility get left behind in favor of development speed and lack of priorities. The problem doesn't explicitly lie with developers. "Blame" (for a lack of a better word) can also be attributed to individual users too. For example, when posting images on social media websites, alt text isn't used nearly enough. To be a champion for web accessibility, one might take advantage of such opportunities to improve the overall integration of accessible tools. How culture and complexity impact accessibility There's a growing gap between accessibility and usability - you need one with the other. If you don't have accessibility, you won't have usability because, without accessibility, you limit the usability of your website for users who require accessibility. It sort of goes full circle. Designers and developers must keep the entire scope of usability in mind when creating their designs and developing their websites. But, it's not easy to keep these aspects a priority, so how do we do that? Some would argue that we need a culture shift that emphasizes user empathy. If you have empathy for all users of your site regardless of their limitations or not, you will consider all types of people. When you have empathy for your users, you will consider those who might require accessible features. With a culture change, comes compassion, empathy, and a greater focus on prioritizing those aspects that may have been left aside. Similarly, an increase in homepage complexity has also contributed to the fall of accessibility. While the number of elements and interactions increase on any given webpage, the state of accessibility falls or is largely forgotten. However, while these complexities increase, so should a focus on accessibility. How Twitter is helping normalize accessibility Twitter has, for the most part, always had the ability for you to add ALT text to your images. However, you could only see this ALT text (or see if a particular image had ALT text to begin with) if you were using a screen-reader. They've added a small badge to each image to show that ALT text has been added. This lets you know if the image you're about to retweet has accessibility in mind. By putting this feature in front of the eyes of every user, they are helping contribute to the normalization of accessibility features which in turn will encourage others to do the same. If you need a little accessibility accountability, check out this fun bot on Twitter named: Caption Clerk. When should I think about it? In short: from the start. It should be a priority during the early design and developing stages of whatever you're building. Rather than have it as an afterthought, make it a priority from the start and ensure it never loses focus. You might consider hiring people with disabilities to gather valuable feedback from them and allow them to contribute to the overall growth of your product. Having people with disabilities directly involved in the building or designing of your product ensures that accessibility will always be impactful. Building a career in accessibility Being in this space can be boring. There's a lot to learn and while it is universally helpful, it's not too thrilling. While lacking in the entertainment department, it emphasizes a deeper, human aspect: integrity. Designing with integrity is crucial for making the web more accessible. It forces you to account for users who might benefit greatly from accessible components. When you design and develop with integrity, you automatically include accessibility on your priority list. Teaching accessibility to others is not an "us vs. them" situation. We need to come alongside each other and prop each other up to teach us the importance of accessibility and growing in the areas we lack. It can be taught, and likewise, it can be learned. But it needs to happen in a team environment. Furthermore, prioritizing accessibility goes further up the chain than just developers and project managers. It goes all the way up to the C-Suite level (CEOs / CTOs). If they make it a priority, then it will trickle down to the rest of the teams. However, as a developer, don't feel forced to learn accessibility. Instead, lean on those who are experts in the space already to help you develop more usable applications. If needed, you might also look to find an accessibility mentor. Conclusion In the end, accessibility should always be a priority for you and your teams. Designing and developing with integrity allows you to provide a greater usability experience for all kinds of different users. Usability without accessibility isn't very usable at all....

What does it actually look like to build software with AI today? Not in theory, but in practice. cover image

What does it actually look like to build software with AI today? Not in theory, but in practice.

What does it actually look like to build software with AI today? Not in theory, but in practice. At the Leadership Exchange, this was the question at the center of the Developer Panel, where leaders from across the industry unpacked what’s really changing inside engineering teams and what organizations need to do right now to keep up. The Developer Panel at the Leadership Exchange explored the cutting edge of AI in software engineering and examined what organizations should focus on today to prepare for the future. Moderated by Jeff Cross, Co-Founder & CEO at Nx, the panel featured Victor Savkin, Cofounder & CTO at Nx, Alex Sover, Vice President of Engineering at OpenAP, Brent Zucker, Senior Director of Engineering at Visa, and Jonathan Fontanez, AI Engineering Lead at This Dot Labs. Panelists shared insights into how AI is transforming the software development lifecycle and how teams can adopt tools effectively while preparing for organizational change. Panelists discussed emerging workflows, including CI-in-the-loop, agentic healing, and context engineering. They examined how validation, code reviews, and PRDs are evolving alongside AI capabilities and how teams are integrating external sources such as production traces to improve quality and reliability. The discussion also covered what the next generation of agentic tools might look like and how these capabilities will shape engineering practices in the near future. Adoption of AI comes with challenges. Teams often rely on plugins or extensions without foundational understanding, and individual contributors may fear displacement. Panelists emphasized that education, governance, and skill-building are essential for teams to manage AI agents effectively while maintaining quality. They also highlighted the need to standardize workflows and ensure organizational alignment to fully leverage AI capabilities. The conversation extended beyond technical challenges to organizational implications. Panelists discussed how teams can avoid issues like Conway’s Law, manage distributed teams effectively, and evolve engineering practices alongside AI adoption. Leadership and management strategies play a crucial role in ensuring that AI integration delivers meaningful outcomes while maintaining efficiency and alignment with business objectives. Key Takeaways - AI workflows require both technical and organizational preparation. - Education, governance, and skill development are essential for successful implementation. - Forward-looking teams are rethinking validation, CI pipelines, and context management to fully leverage agentic AI. The discussion highlighted that adopting AI at the cutting edge is not just about new tools - it is about rethinking processes, workflows, and organizational culture. Companies that embrace this holistic approach are most likely to succeed in leveraging AI to its full potential. Are you interested in more conversations like this? Message us for an invite to the next, or for a private discussion around these topics. Tracy can be reached at tlee@thisdot.co....

Understanding Sourcemaps: From Development to Production cover image

Understanding Sourcemaps: From Development to Production

What Are Sourcemaps? Modern web development involves transforming your source code before deploying it. We minify JavaScript to reduce file sizes, bundle multiple files together, transpile TypeScript to JavaScript, and convert modern syntax into browser-compatible code. These optimizations are essential for performance, but they create a significant problem: the code running in production does not look like the original code you wrote. Here's a simple example. Your original code might look like this: ` After minification, it becomes something like this: ` Now imagine trying to debug an error in that minified code. Which line threw the exception? What was the value of variable d? This is where sourcemaps come in. A sourcemap is a JSON file that contains a mapping between your transformed code and your original source files. When you open browser DevTools, the browser reads these mappings and reconstructs your original code, allowing you to debug with variable names, comments, and proper formatting intact. How Sourcemaps Work When you build your application with tools like Webpack, Vite, or Rollup, they can generate sourcemap files alongside your production bundles. A minified file references its sourcemap using a special comment at the end: ` The sourcemap file itself contains a JSON structure with several key fields: ` The mappings field uses an encoding format called VLQ (Variable Length Quantity) to map each position in the minified code back to its original location. The browser's DevTools use this information to show you the original code while you're debugging. Types of Sourcemaps Build tools support several variations of sourcemaps, each with different trade-offs: Inline sourcemaps: The entire mapping is embedded directly in your JavaScript file as a base64 encoded data URL. This increases file size significantly but simplifies deployment during development. ` External sourcemaps: A separate .map file that's referenced by the JavaScript bundle. This is the most common approach, as it keeps your production bundles lean since sourcemaps are only downloaded when DevTools is open. Hidden sourcemaps: External sourcemap files without any reference in the JavaScript bundle. These are useful when you want sourcemaps available for error tracking services like Sentry, but don't want to expose them to end users. Why Sourcemaps During development, sourcemaps are absolutely critical. They will help avoid having to guess where errors occur, making debugging much easier. Most modern build tools enable sourcemaps by default in development mode. Sourcemaps in Production Should you ship sourcemaps to production? It depends. While security by making your code more difficult to read is not real security, there's a legitimate argument that exposing your source code makes it easier for attackers to understand your application's internals. Sourcemaps can reveal internal API endpoints and routing logic, business logic, and algorithmic implementations, code comments that might contain developer notes or TODO items. Anyone with basic developer tools can reconstruct your entire codebase when sourcemaps are publicly accessible. While the Apple leak contained no credentials or secrets, it did expose their component architecture and implementation patterns. Additionally, code comments can inadvertently contain internal URLs, developer names, or company-specific information that could potentially be exploited by attackers. But that’s not all of it. On the other hand, services like Sentry can provide much more actionable error reports when they have access to sourcemaps. So you can understand exactly where errors happened. If a customer reports an issue, being able to see the actual error with proper context makes diagnosis significantly faster. If your security depends on keeping your frontend code secret, you have bigger problems. Any determined attacker can reverse engineer minified JavaScript. It just takes more time. Sourcemaps are only downloaded when DevTools is open, so shipping them to production doesn't affect load times or performance for end users. How to manage sourcemaps in production You don't have to choose between no sourcemaps and publicly accessible ones. For example, you can restrict access to sourcemaps with server configuration. You can make .map accessible from specific IP addresses. Additionally, tools like Sentry allow you to upload sourcemaps during your build process without making them publicly accessible. Then configure your build to generate sourcemaps without the reference comment, or use hidden sourcemaps. Sentry gets the mapping information it needs, but end users can't access the files. Learning from Apple's Incident Apple's sourcemap incident is a valuable reminder that even the largest tech companies can make deployment oversights. But it also highlights something important: the presence of sourcemaps wasn't actually a security vulnerability. This can be achieved by following good security practices. Never include sensitive data in client code. Developers got an interesting look at how Apple structures its Svelte codebase. The lesson is that you must be intentional about your deployment configuration. If you're going to include sourcemaps in production, make that decision deliberately after considering the trade-offs. And if you decide against using public sourcemaps, verify that your build process actually removes them. In this case, the public repo was quickly removed after Apple filed a DMCA takedown. (https://github.com/github/dmca/blob/master/2025/11/2025-11-05-apple.md) Making the Right Choice So what should you do with sourcemaps in your projects? For development: Always enable them. Use fast options, such as eval-source-map in Webpack or the default configuration in Vite. The debugging benefits far outweigh any downsides. For production: Consider your specific situation. But most importantly, make sure your sourcemaps don't accidentally expose secrets. Review your build output, check for hardcoded credentials, and ensure sensitive configurations stay on the backend where they belong. Conclusion Sourcemaps are powerful development tools that bridge the gap between the optimized code your users download and the readable code you write. They're essential for debugging and make error tracking more effective. The question of whether to include them in production doesn't have a unique answer. Whatever you decide, make it a deliberate choice. Review your build configuration. Verify that sourcemaps are handled the way you expect. And remember that proper frontend security doesn't come from hiding your code. Useful Resources * Source map specification - https://tc39.es/ecma426/ * What are sourcemaps - https://web.dev/articles/source-maps * VLQ implementation - https://github.com/Rich-Harris/vlq * Sentry sourcemaps - https://docs.sentry.io/platforms/javascript/sourcemaps/ * Apple DMCA takedown - https://github.com/github/dmca/blob/master/2025/11/2025-11-05-apple.md...

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co