loading...

The 6 most common mistakes developers when writing HTML and CSS

melnik909 profile image Stas Melnikov Updated on ・3 min read

Using the placeholder attribute instead the label element

Often developers use the placeholder attribute instead of the label element. But the user of screen readers can't fill in fields in this cases because screen readers can't read the text from the placeholder attribute.

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

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

<label>
  <span>Enter your email</span>
  <input type="email" placeholder="e.g. example@gmail.com">
</label>

To markup decorative graphics using the img element

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

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

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

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

Using the resize property

When you disable resizing a textarea using the resize property you worsen accessibility. So the user can't enter a data a comfortable way for himself.

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

You can use the min-width, max-width, min-height and max-height properties that to limit element's sizes and user can fill in fields a comfortable way for himself.

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

Using display: block and position: absolute (fixed) together

I often see developers use the display and position properties like this:

.button::before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}

But the browser sets the block value by default. Therefore you needn't to add this value for the absolute or fixed positioned elements. So the following code produce the same results as the previous.

.button::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
}

The none value for the outline property

I can't use a website using my keyboard. I can't going to a link. I can't register. That happens because developers disable focus on elements when they add the none value for the outline property.

.button:focus {
  outline: none;
}

/* or */

.button:focus {
  outline: 0;
}

If you need to disable default focus don't forget to make the alternate focus state.

.button:focus {
  outline: none;
  box-shadow: 0 0 3px 0 blue;
}

Empty elements

Often developers use empty HTML elements to style elements. For example, the hamburger markup using the empty div or span elements:

<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;
}

But you can use the ::before and ::after pseudo-elements and to achieve similar results.

<button class="hamburger">
  <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;
}

Posted on by:

melnik909 profile

Stas Melnikov

@melnik909

I help people to learn new things about HTML and CSS on Patreon platform 👉 https://www.patreon.com/posts/34774556

Discussion

markdown guide
 

Nice, some good points. This is really short-sighted though: "Using display: block and position: absolute (fixed) together". In all browsers? In one browser? What if a user agent is configured differently? Chrome makes changes to their user agent stylesheet all the time. I would never discourage someone to leave out something as important as a display property if they want to explicitly define it. Sure, there are some we've all gotten used to over the years, but by no means would I consider this a "mistake". What if said element is a table and said user wants to absolutely position it as a block element? Be careful with how you are categorizing these as "mistakes".

 

I have not thought about this before. So I checked it with a CodePen and found this sentence in the Specification:

An absolutely positioned box establishes a new containing block for normal flow children and absolutely (but not fixed) positioned descendants.

I assume that these words about "new containing block" force browser developers to display absolutely positioned pseudo-element as a block.

 

No they don't. display:inline-block, display:table-cell and display:list-item all establish containing blocks, so any of those would also be consistent with that sentence from the spec. What you are looking for is section 9.7 Relationships between 'display', 'position', and 'float', step 2

 

In Chrome. IE, Edge, Firefox, Safari, Android, Safari on iOS, UC Browser, Samsung

 

Any mistakes authors when writing headlines?

 

Only can judge him.

(It's all love;))

 

Although I agree with most of the points, I find the headline a bit misleading - are these the "most common mistakes"? I must confess, I've never seen the "resize:none" - setting somewhere in the wild for textareas but honestly, I've also not payed attention to that :).

I definitely agree with the misusage of the placeholder - that also goes for UI designers, who misuse the placeholder already.

Relating to the usage of label, I'd recommend to extend the example with an id for the input-field and a relating for-attribute for the label-tag.
<label for="email_field">
Email:<input type="email" id="email_field" />
</label>

That makes it more relateable where the label tag relates to :).

 

Wouldn't it be nicer to wrap icons in figure elements and with a figcaption to help users with screenreaders?

 
 
 

Did you count how many famous boilerplate templates have the "bad practice" hamburger menu? 🤣🤣

Awesome Article!

 
 

That moment when i realized i did all of that mistakes...

 

Don't worry. Now you know more and can fix it!