DEV Community

Stas Melnikov
Stas Melnikov

Posted on • Updated on

6 HTML and CSS Good Coding Habits

Not all text is a heading

Headings are a very important part of HTML that helps people with navigation issues. Especially, when screen readers show quickly page navigation they make it using the list of page headings.

So we have to pay attention to how we use headings. There is a bad practice of using the h1-h6 elements anywhere. As a result, users of screen readers get a mess of headings and have to spend more effort to understand that.

For example, we can avoid that if we think if really we need to use the headings for a heading and subheading. Maybe instead of using two headings, we can use only one by combining them.

don't do this

<h2>iPad Pro</h2>
<h3>Supercharged by the Apple My chip.</h3>
Enter fullscreen mode Exit fullscreen mode

you can use it instead

<h2>
  <span>iPad Pro</span>
  <span>Supercharged by the Apple My chip.</span>
</h2>
Enter fullscreen mode Exit fullscreen mode

The alt attribute isn't a duplication heading text

If you want to make user-friendly interfaces for users of screen readers the alt attribute is the power tool.

Unfortunately, a lot of developers use this attribute inefficiently. For example, they copy the text from a heading in the alt when creating the markup with img and heading. That leads to users of screen readers will hear it twice.

Instead of that, you can give more information about img to people with vision disabilities. Just make the alt is an addition to text from a heading.

I do that in my example. As result, screen readers will voice "adidas Originals Superstar, heading, level 3". "trainers with branded tongue and cuff, adidas 3-stripe logo and slim sole, picture".

don't do this

<header>
  <h3>adidas Originals Superstar</h3>
  <img src="picture.jpg" alt="adidas Originals Superstar">
</header>
Enter fullscreen mode Exit fullscreen mode

you can use it instead

<header>
  <h3>adidas Originals Superstar</h3>
  <img src="picture.jpg" alt="trainers with branded tongue and cuff, adidas 3-stripe logo and slim sole">
</header>
Enter fullscreen mode Exit fullscreen mode

button type=button is better than a href="#"

There is the practice of using a href="#" for creating an interactive element. People disable the default behavior of a link using JS. As a result, you will get an element that behaves like a button.

Yes, it's the working solution at first sight. But the problem is this element has not become a button for browsers. If you click a right mouse button on this element you will see the following options in the context menu: "Open link in new tab", "Open link in new window", "Open link in incognito window".

When users see these options they wait they can open a link in a new tab or window. So they want to use these browsers features. But when they push on this link they will get the unexpected result.

Users will see just the start of a page. So the button element is a better solution because you get already an interactive accessible element. Also if users click on this element the context menu will not have options of a link. So you will not confuse your users.

don't do this

<a href="#">Show my order</a>
Enter fullscreen mode Exit fullscreen mode

you can use this instead

<button type="button">Show my order</button>
Enter fullscreen mode Exit fullscreen mode

justify-content: space-between leads to unexpected layout

I'm tired to see that developers use the space-between or space-around value to position the grid's elements. It's a bad practice that leads to incorrect displaying. When people do that they don't think that number of items may be changed.

For example, if add more elements in a grid from 4 columns they will not be displayed at the start of the line. Thus I see the broken grids.

There is a nice approach using the column-gap property. This property with Flexbox and you can just define a gap between of elements. And browsers will do all the rest of the work. So you'll get safe grids with any number of elements.

don't do this

<div class="grid">
  <div class="item"><span>item 1</span></div>
  <div class="item"><span>item 2</span></div>
  <div class="item"><span>item 3</span></div>
  <div class="item"><span>item 4</span></div>
  <div class="item"><span>item 5</span></div>
</div>
Enter fullscreen mode Exit fullscreen mode
.grid {
  display: flex;
  justify-content: space-between; /* or space-around */
}

.item {
  width: 30%;
}
Enter fullscreen mode Exit fullscreen mode

you can use this instead

<div class="grid">
  <div class="item"><span>item 1</span></div>
  <div class="item"><span>item 2</span></div>
  <div class="item"><span>item 3</span></div>
  <div class="item"><span>item 4</span></div>
  <div class="item"><span>item 5</span></div>
</div>
Enter fullscreen mode Exit fullscreen mode
.grid {
  display: flex;
  column-gap: 5%;
}

.item {
  width: 30%;
}
Enter fullscreen mode Exit fullscreen mode

justify-content and align-items lose a close button

When we solve issues of alignment we like to use alignment properties such as justify-content or align-items. But few people know these properties can lead to losing data, particularly frequently, when vertical alignment.

This is due to how these properties work. This process includes the two terms. The first, the alignment container is an element to that you declare the alignment properties.

The second, the alignment subject is elements that are inside of the alignment container. The alignment properties affect them.

So there is the case when the alignment subjects' sizes are larger than the alignment container's sizes. In the default alignment mode, it'll lead to overflow and loss of data. So users will see the cropped element.

I created the example with the modal element to show this behavior. At first, the text is short. But when we make it more we lose the heading and the close button.

We can fix it using auto margins because it uses extra space to align elements and doesn't lead to overflow. Take a look at how elements are no longer lost.

don't do this

<div class="modal">
  <div class="modal__main"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
.modal {
  display: flex;
  justify-content: center;
  align-items: center;
}
Enter fullscreen mode Exit fullscreen mode

you can use this instead

<div class="modal">
  <div class="modal__main"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
.modal {
  display: flex;
}

.modal__main {
  margin: auto;
}
Enter fullscreen mode Exit fullscreen mode

Taking care of users which can experience dizziness, nausea and headaches

I think a lot of designers and developers like to create animation. Yes, interfaces look more interesting in these cases. But, we have to be more careful.

The WCAG 2.2. there is section 2.3.3. which describes some users experience dizziness, nausea and headaches when they see an animation that triggers movement of elements.

Thus if you create an animation of this type you have to use the prefers-reduced-motion media feature. In this case, if people disabled an animation in an operating system your animation will not be displayed and if they didn't do that an animation will work.

So you will take care of your users better.

don't do this

.example {
  animation-name: zoomInDown;
  animation-duration: 1s;
  animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  animation-delay 0.3s;
  animation-fill-mode: both;
}

Enter fullscreen mode Exit fullscreen mode

you can use this instead


@media (prefers-reduced-motion: no-preference) {
  .example {
    animation-name: zoomInDown;
    animation-duration: 1s;
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-delay 0.3s;
    animation-fill-mode: both;
  }
}
Enter fullscreen mode Exit fullscreen mode

P.S.
🖐 I help people fix accessibility mistakes. If you need help chat me on melnik909@ya.ru or dev.to direct. Please, specify the subject of the email "Stas, I need help"

👀 Friends, I tell stories from my career on Substack. Join my free newsletter, if you're interested in my background or you want to get my updates first

🤑 If you want to be the first who get my tips get my paid monthly subscription

Get the subscription

P.S.S. Thank you so much, my sponsors: Ben Rinehart, Sergio Kagiema, Jesse Willard, Tanya Ten.

Discussion (14)

Collapse
hyggedev profile image
Chris Hansen • Edited

Although I agree with your very first point, "Not all text is a heading", I'd like to get your opinion on where you would use the H1 tag? As someone who's just starting to dive into SEO more, I know that the H1 tag should basically be used only once on a page, as it determines priority over all other text. I would think, "Ipad Pro" would be in an H1 tag or am I wrong? Is that example for their page? 🤣

Great article though, I did pick up a few pointers! I like how you mentioned "space-between." can cause unexpected layouts. I use it a lot, but I'm going to look into "column-gap"!

Collapse
brittneypostma profile image
Brittney Postma

This was my thought as well. That should absolutely be an h1 and can be spanned, but iPad Pro is the most important thing on the page. It's the h1, the "Supercharged by the M1 Apple Chip" is the subheading or h2.

These examples are circumstantial too and don't apply to every situation. The grid example with space-between, works in some instances where flex may work better in others.

Accessibility is important and I agree with using prefers reduced motion, but again you can cover yourself there in different ways. This article gives a false sense of "this is the correct way", don't do this other thing. In my opinion, this article has some good practices and some bad practices. We need to show good accessibility and semantic html. I'm not sure this comes across here.

Collapse
melnik909 profile image
Stas Melnikov Author

Let's discuss it more details?

Thread Thread
brittneypostma profile image
Brittney Postma

Yeah, absolutely. I made a few points in the comment above if you have any rebuttals on those? I was just trying to point out that the article's claims aren't technically good coding habits in every circumstance.

Thread Thread
melnik909 profile image
Stas Melnikov Author • Edited

I see. I think we can start with headings. I told about if you add headings anywhere you complicate navigation of users with screen readers because the list of headings bacame unnecessarily large.

Why is it the bad practices?

Thread Thread
brittneypostma profile image
Brittney Postma

Each page should have an h1 giving the highest level of importance on the page, which in the example is the iPad Pro. Apple themselves don't even follow this practice, but here is a decent post on why it is important to level correctly. webaim.org/techniques/semanticstru...

Thread Thread
melnik909 profile image
Stas Melnikov Author • Edited

the fragment is a section on the home page. So the h1 can't be used. So I give the fragments of code where h1 isn't. One of them is a fragment from the real website.

Thread Thread
brittneypostma profile image
Brittney Postma • Edited

This is the same snippet of code directly from Apple's site.

<div id="hero-headline-zoom" data-component-list="HeroTextZoom">
                                <h1 id="hero-headline" data-component-list="HeroHeadline" data-focus-expression="{&quot;expression&quot;: &quot;t - 100vh&quot;}" class="hero-headline typography-experience-hero-headline">iPad Pro</h1>
                                <div id="hero-headline-gradient"></div>
                                <h2 id="hero-subhead" class=" typography-experience-hero-subhead" data-focus-expression="{&quot;expression&quot;: &quot;t - 100vh&quot;}" data-component-list="HeroSubHeadline">Supercharged by the Apple M1 chip.</h2>
                            </div>
Enter fullscreen mode Exit fullscreen mode

Here is the snippet from the homepage, which the h2 is correct in.

<div class="unit-copy-wrapper">
                                                    <h2 class="headline">iPad Pro</h2>
                                                    <h3 class="subhead" role="presentation">Supercharged by the Apple&nbsp;M1&nbsp;chip.</h3>


                                        <div class="cta-links">
                                                    <a class="icon icon-after icon-chevronright" href="/ipad-pro/" target="_self" rel="follow" data-analytics-region="learn more" data-analytics-title="Learn more about iPad Pro" aria-label="Learn more about iPad Pro">Learn more</a>
                                                    <a class="icon icon-after icon-chevronright" href="/us/shop/goto/ipad_pro/select" target="_self" rel="follow" data-analytics-region="buy" data-analytics-title="Buy iPad Pro" aria-label="Buy iPad Pro">Buy</a>
                                        </div>

                                    </div>
Enter fullscreen mode Exit fullscreen mode

This is semantically correct, so while your example is technically correct for a page with multiple headings, it does not appear that way in your image. It seems that this is the page view, where there should be an h1 at that level. Your post isn't incorrect, it's just most of it was based on the circumstance you use it in.

Thread Thread
melnik909 profile image
Stas Melnikov Author • Edited

I told about approach that will help people to improve interfaces. Yes, if we consider snippet from Apple website role="presentation" helps. But it's a hack.

ARIA in HTML spec tells "Don't override default roles" w3.org/TR/html-aria/#don-t-overrid...

You told I wrote a bad practice but I don't understand where you found that.

Thread Thread
brittneypostma profile image
Brittney Postma

True, it's probably not bad practice after you explained it's from the home page. The other problem I saw was saying don't use grid with space between. Like I said before that is completely situational and using that is completely fine. I think it's more the wording and how the first example is taken out of context.

Collapse
melnik909 profile image
Stas Melnikov Author

Yes, I added markup for this example. I use only one h2

Collapse
siddharthshyniben profile image
Siddharth

Question: Why shouldn't I do this:

<h2>iPad Pro</h2>
<h3>Supercharged by the Apple My chip.</h3>
Enter fullscreen mode Exit fullscreen mode
Collapse
praveencqr profile image
Praveen Kumar J

Thanks. It will be useful.

Collapse
jeoanand profile image
Anandakumar • Edited

Thanks, I have struck around the flex alignment. Content hiding the screen.
.modal {
display: flex;
}

.modal__main {
margin: auto;
}
it work's for me.