The most CSS/HTML common mistakes that is in your project | DevsDay.ru

IT-блоги The most CSS/HTML common mistakes that is in your project

dev.to 24 мая 2021 г.


I help people to check CSS/HTML of their projects. I have noticed that some errors are repeated from project to project. And so I decided to write this article so that you can check if you have them.

Using the placeholder attribute instead of the label element

The popular mistake that I often see is using the placeholder attribute instead of the label element. But the user of screen readers can't fill in fields in this case because screen readers can't read the text from the placeholder attribute.

So I recommend using the label element for a field name and the placeholder attribute for an example of data which user need to fill.

don't do this

<input type="email" placeholder="Enter your email">

You can use this instead

<label>
  <span>Enter your email</span>
  <input type="email" placeholder="e.g. [email protected]">
</label>

Creating decorative graphics using the img element

Nowadays developers often confuse decorative graphics with content images. For example, they mark up social icons using the img element.

But a social icon is a decorative icon that helps users faster to understand the meaning of an element without reading text. If we remove the icon we don't lose the meaning of the element so we can use the background-image property for it.

don't do this

<a href="https://twitter.com" class="social">
  <img class="social__icon" src="twitter.svg" alt>
  <span class="social__name">Twitter</span>
</a>

You can use this instead

<a href="https://twitter.com" class="social">
  <span class="social__name">Twitter</span>
</a>
.social::before {
  background-image: url("twitter.svg");
}

Using the resize: none

I suffer every time developers make small textarea and I can't change it because they disable resizing. They don't think when they add resize: none the form accessibility is worsened and users can't comfortably enter data.

If you want to limit textarea's sizes you can use the min-width, max-width, min-height, and max-height properties. But you should pick up the height value so that the user can fill in fields a comfortable way for himself.

don't do this

textarea {
  width: 100%;
  height: 200px;
  resize: none;
}

You can use this instead

textarea {
  min-width: 100%;
  max-width: 100%;
  min-height: 200px;
  max-height: 400px;
}

Using empty elements

In the web, there is bad practice to use empty HTML elements styling elements. For example, the hamburger markup using the empty div or span elements.

But this issue should be solved using the ::before and ::after pseudo-elements. In this case, HTML looks cleaner. Also, the main thing is adding of text for screen readers so that users can interact with this button.

don't do this

<button class="hamburger">
  <span></span>
  <span></span>
  <span></span>
</button>
.hamburger {
  width: 60px;
  height: 45px;
  position: relative;
}

.hamburger span {
  width: 100%;
  height: 9px;

  background-color: #d3531a;
  border-radius: 9px;

  position: absolute;
  left: 0;
}

.hamburger span:nth-child(1) {
  top: 0;
}

.hamburger span:nth-child(2) {
  top: 18px;
}

.hamburger span:nth-child(3) {
  top: 36px;
}

You can use this instead

<button class="hamburger" type="button">
  <span class="hamburger__text">
    <span class="visually-hidden">Open menu</span>
  </span>
</button>
.hamburger {
  width: 60px;
  height: 45px;
  position: relative;
}

.hamburger::before,
.hamburger::after,
.hamburger__text::before {
  content: "";
  width: 100%;
  height: 9px;

  background-color: #d3531a;
  border-radius: 9px;

  position: absolute;
  left: 0;
}

.hamburger::before {
  top: 0;
}

.hamburger::after {
  top: 18px;
}

.hamburger__text::before {
  top: 36px;
}

.visually-hidden {
  position: absolute !important;
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px !important; 
  height: 1px !important; 
  overflow: hidden;
}

How the justify-content and align-items make users suffer

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 frequent, 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>
.modal {
  display: flex;
  justify-content: center;
  align-items: center;
}

You can use this instead

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

.modal__main {
  margin: auto;
}

You make text unavailable

Nowadays we often use custom fonts so that our interface looks more unique. Custom fonts aren't in our systems so we have to load them but it takes some time and the issue is what to display at this time.

By default, a browser waits while a font is loaded so he displays nothing. But we can change it that a browser uses the fallback for displaying text.

There is the font-display descriptor that determines how a font face is displayed based on whether and when it is downloaded and ready to use.

We can use the swap value that instructs the browser to use the fallback to display the text until the custom font is fully downloaded.

This trick helps an user start to interact with an interface faster and to reach its goals.

don't do this

@font-face {
  font-family: "Baloo Tamma";
  src: url("balotamma.woff2") format("woff2"),
       url("balotamma.woff") format("woff");
}

You can use this instead

@font-face {
  font-family: "Baloo Tamma";
  src: url("balotamma.woff2") format("woff2"),
       url("balotamma.woff") format("woff");
  font-display: swap;
}

Your SVG icons break your interfaces

When you use SVG icons right in a HTML document, pay attention you have to set the width and height attributes. If you don't do it and you rely on you set the width and height properties in CSS your interface will be broken.

Your CSS might not be loaded and at this point, the icons will try to fill all of the available space. So the mistake happens. Just set the width and height attributes and can sleep easy. Your interfaces will be bulletproof!

don't do this

<svg xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 448 512">
  <path fill="currentColor" d="..."></path>
</svg>
svg {
  width: 0.875rem;
  height: 1rem;
}

You can use this instead

<svg xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 448 512"
    width="0.875rem"
    height="1rem">
  <path fill="currentColor" d="..."></path>
</svg>

You don't need to use heavy images for any type of devices

Our users face too heavy images when they take a look at websites. If they have high-speed internet isn't an important problem but often users remained where there are problems with the internet. It's might be the subway, nature, or another country. I think we have to help users use our apps.

The good idea is to help a browser doesn't load heavy images with cell phones or other mobile devices. And I want to share the solution that'll do it.

This solution is known as the picture element that allows defining the set of images' source paths so that a browser can load the most appropriate image for devices.

For example, we can create 2 source elements and define the width media feature to detect pads and desktops. Also, we will use the img element for cell phones. Then browsers will choose the image that best suits users.

Pay attention, I use the mobile-first approach so if the picture isn't supported by browsers or the user came using a cell phone the small image will be shown.

don't do this

<img 
  src="ferrari-1920x1080.jpg"
  alt="yellow ferrari F8 spider on the background of the ocean">

You can use this instead

<picture>
  <source 
    srcset="ferrari-1200x960.jpg"
    media="(min-width: 641px) and (max-width: 1200px)">
  <source 
    srcset="ferrari-1920x1080.jpg"
    media="(min-width: 1201px)"> 
  <img 
    src="ferrari-640x480.jpg"
    alt="yellow ferrari F8 spider on the background of the ocean">
</picture>

Also, you can use the display density descriptor and the scrset attribute to suggest which image is better for a specific device taking into account pixel density.

For example, if a cell phone has 2x pixel density or more a browser loads the ferrari-640x480-2x.jpg image using the 2x descriptor. But if it has 1x pixel density the ferrari-640x480-1x image will be loaded. Also this rule will work for pads and desktop devices.

don't do this

<img 
  src="ferrari-1920x1080.jpg"
  alt="yellow ferrari F8 spider on the background of the ocean">

You can use this instead

<img 
  src="ferrari-1x.jpg"
  srcset="ferrari-2x.jpg 2x"
  alt="yellow ferrari F8 spider on the background of the ocean">

<!-- or -->

<picture>
  <source 
    srcset="ferrari-1200x960-1x.jpg,
            ferrari-1200x960-2x.jpg 2x"
    media="(min-width: 641px) and (max-width: 1200px)">
  <source 
    srcset="ferrari-1920x1080-1x.jpg,
            ferrari-1920x1080-2x.jpg 2x"
    media="(min-width: 1201px)"> 
  <img 
    src="ferrari-640x480-1x.jpg,
         ferrari-640x480-2x.jpg 2x"
    alt="yellow ferrari F8 spider on the background of the ocean">
</picture>

The main element is missing

Every web page has main content but developers forget about it somehow. They don't use the main element. So assistive technologies think web pages don't have main content.

Don't do it

<div class="main-content">
  <!-- main content is here -->
</div>

You can use it instead

<main class="main-content">
  <!-- main content is here -->
</main>

Using headings too much

There is a bad practice of using the h1-h6 elements for the subheading. When you do that you forget that headings help users of screen readers to navigate on the web page faster. If you have headings too much it prevents people. So use heading where they're needed.

Don't do it

<h2>iPhone 11</h2>
<h3>Just the right amount of everything.</h3>

You can use it instead

<h2>
  <span>iPhone 11</span>
  <span>Just the right amount of everything.</span>
</h2>

The alt attribute has incorrect values

The alt attribute can be very useful if developers use it correctly. Unfortunately, a lot of them don't try to describe images so that people with visual disabilities could understand what's on the picture.

Don't do it

<img src="picture.jpg" alt="adidas Originals Superstar">

You can use it instead

<img src="picture.jpg" alt="adidas Originals Superstar Bold platform trainers in black and white">

Using the div element instead of the span element

That is the top mistake that I see on a large number of websites. In the spec there is the following description of the div element:

The div element has no special meaning at all. It represents its children. It can be used with the class, lang, and title attributes to mark up semantics common to a group of consecutive elements.

Contexts in which this element can be used: where flow content is expected and as a child of a dl element.

The flow content is most elements that are used in the body of documents and applications. That isn't text.

The span element is the best element to markup text without special meaning. It has the following description in the spec:

The span element doesn't mean anything on its own but can be useful when used together with the global attributes, e.g. class, lang, or dir. It represents its children.

Contexts in which this element can be used: where phrasing content is expected.

Phrasing content is the text of the document, as well as elements that mark up that text at the intra-paragraph level.

So just use the span for text and you'll have valid HTML.

Don't do it

<div>some text</div>

You can use it instead

<span>some text</span>

Missing the address element for the social media block

Often we need to markup a social media block or other contact info in our projects. Usually, developers use the div element.

But the WHATWG spec contains the special address element for this task. What's written in the spec.

The address element represents the contact information for its nearest article or body element ancestor. If that is the body element, then the contact information applies to the document as a whole.

So if you want to have the valid HTML you should use the address element.

don't do this

<div class="my-social">
  <ul>
    <li><a href="github.com">Fork me on Github</a></li>
    <li><a href="twitter.com">Follow me on Twitter</a></li>
    <li><a href="linkedin.com">My LinkedIn</a></li>
  </ul>
</div>

You can use this instead

<address class="my-social">
  <ul>
    <li><a href="github.com">Fork me on Github</a></li>
    <li><a href="twitter.com">Follow me on Twitter</a></li>
    <li><a href="linkedin.com">My LinkedIn</a></li>
  </ul>
</address>

Breadcrumbs without the ol element

There is a best practice to use lists to markup navigation elements such as breadcrumbs, pagination, etc. Usually, developers use the ul element. But the spec contains a more appropriate element and this element is the ol element.

This element has the following description in the WHATWG spec:

The ol element represents a list of items, where the items have been intentionally ordered, such that changing the order would change the meaning of the document.

So if we will change the order of elements in the breadcrumbs then we change the meaning of the website's navigation and confusing users. So this list is ordered, i.e the ol element.

don't do this

<nav class="breadcrumbs">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Design Patterns</a></li>
    <li><a href="#">Breadcrumb Pattern</a></li>
  </ul>
</nav>

You can use this instead

<nav class="breadcrumbs" aria-label="breadcrumbs">
  <ol>
    <li><a href="#">Home</a></li>
    <li><a href="#">Design Patterns</a></li>
    <li><a href="#">Breadcrumb Pattern</a></li>
  </ol>
</nav>

Dates without the time element

I think every developer used the span element for dates. I'm too. But that's a mistake because the WHATWG spec contains the time element that we can use for it. This is what the WHATWG spec tells:

The time element represents its contents, along with a machine-readable form of those contents in the datetime attribute. The kind of content is limited to various kinds of dates, times, time-zone offsets, and durations.

So we should use the time elements instead of the span element creating dates.

don't do this

<span>October 5</span>
<span>two days ago</span>
<span>a Saturday</span>

You can use this instead

<time datetime="2019-10-05">October 5</time>
<time datetime="2019-01-29">two days ago</time>
<time datetime="2019-09-23">a Saturday</time>

P.S. If you like these tips go to read others on my Linkedin.

P.S.S. This post was written with the support of my patrons: Ashlea Gable, Ben Rinehart, Sergio Kagiema, Vlad Bazhanov, Spiridon Konofaos, Jesse Willard, Tanya Ten.

Источник: dev.to

Наш сайт является информационным посредником. Сообщить о нарушении авторских прав.

css html beginners tutorial