The 6 most common mistakes developers when writing HTML and CSS
Tags: html, webdev, learning, css
Published: 2019-11-10 19:21:54


## The `placeholder` attribute instead of the `label` element

Please, stop using the `placeholder` attribute instead of the `label` element. People that use screen readers can't fill in input fields because screen readers can't read the text from the placeholder attribute. 

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

I recommend using the `label` element for a field name and the `placeholder` attribute for an example of data that users should fill in. 

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

## The `img` element for decorative graphics

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

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

But social icons are decorative icons that help users faster to understand the meaning of elements without reading text. If we remove icons we won't lose the meaning of elements. So the `background-image` property is the best way.

```html
<a href="https://twitter.com" class="social">
  <span class="social__name">Twitter</span>
</a>
```
```css
.social::before {
  background-image: url("twitter.svg");
}
```
## `resize: none`
When you disable resizing textarea using `resize: none` you worsen accessibility. So the user can't comfortably enter data for himself.

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

You can use the `min-width`, `max-width`, `min-height` and `max-height` properties that to limit elements' sizes. Users can fill in input fields a comfortable way for himself.

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

### Using `display: block` with `position: absolute` or `position: fixed`

I often see the following code snippet:

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

Here `display: block` isn't necessary because if `position: absolute` or `position: fixed` is used browsers set `display: block` by default. So the following code is a full alternative to the previous one.

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

## `outline: none`

I can't use websites using my keyboard. I can't go to a link. I can't register. That happens because developers disable focus on elements when they add `outline: none`.

```css
.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.

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

### Empty elements 

There is the practice of using empty HTML elements to style elements. For example, the hamburger markup using the empty `div` or `span` elements:

```html
<button class="hamburger">
  <span></span>
  <span></span>
  <span></span>
</button>
```
```css
.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 achieve similar results.

```html
<button class="hamburger">
  <span class="hamburger__text">
    <span class="visually-hidden">Open menu</span>
  </span>
</button>
```
```css
.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;
}
```
**P.S**
✉️ I make unlimited Q&A sessions about HTML/CSS via email with expect responses in 2 days. 

😎 I make HTML/CSS reviews of your non-commercial projects and recommendations for improvement. 

🧑‍🏫I help in searching high-quality content about HTML/CSS

Please, use my email for communication 👉 melnik909@ya.ru

💪 Discover [more free things](https://linktr.ee/melnik909) from me