Icons have meaning - RTL in a web platform (4/6)
Tags: css, webdev, a11y, react
Published: 2021-08-16 08:42:14

_This post is the 4th part of a 6 part series, on how to build a RTL compatible web platform, take a look at the previous one [here](https://dev.to/pffigueiredo/bullet-proof-rtl-rtl-in-a-web-platform-3-6-4bne)._

## Icons Meaning 

Since many years ago, the web has adopted icons to either, give the user a **hint on certain actions** or to **replace text because it was too large**. Sometimes, we even have text with the icons right next to it, because reading an icon's logical meaning is so much faster than reading a word/phrase.

Here are a few examples of icons and their logical meanings, that you should be able to recognize:

:wastebasket: - The trash means a **removal/destructive action**;
:floppy_disk: - The floppy disk means a **save action**;
:heavy_plus_sign: - The plus means a **adding action**;
...

## Icons in RTL context

But why should icons be any different in RTL or LTR? Well, for the examples I purposefully showed above, there is absolute no difference, but let's look at these:

:arrow_right: - The right arrow means going  ______
:arrow_left: - The left arrow means going  ______

Now, you can try to fill in the blank space, but unless your guess contains a `if` in the middle, your are only thinking on one perspective. 

What I mean, is that :arrow_right: does **mean going forward** if you are looking at it from a LTR perspective, else, it does exactly the opposite, and it means, **going back**. The same thing is applied to :arrow_left:, having different meanings depending on the directional mindset you look at it.

## Tackling icons in a web platform

In most of RTL compatible platforms, there are 3 types of icons. So the first step on tackling icons correctness, should be classifying them into one of those 3 types.

The question you should be asking to classify them is: 

>_**Should this icon flip in RTL?**_ 

With that in mind, you can create these 3 sets of icons:

1- **Bidirectional icons**, are the ones that look the same in RTL and LTR.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwsmychpibhkzyobk500.png)

2- **Unidirectional icons**, are the ones that should rotate depending on the document's direction, because they usually have different meanings depending on their direction.
 
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ioibels1ppuj9egtxoa7.png)

3- **Brand Icons**, these icons represent brands or entities whose logo should remain the same, regardless of direction or language. 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4fffznsebmb940t08n7l.png)

## Code Implementation

After making this icon classification, you are already pretty far on the process. The next step, is creating this logic in code, and my advice here, is to create a single `Icon` component that acts as the source of truth of all your platform's  icons.

That way, you have wrapper that will control all your components and you don't have worry about flipping/not flipping every single icon.

```typescript
import React from 'react';
import styled from 'styled-components';

const IconWrapper = styled('div')`
  html[dir='rtl'] &.flip-icon {
    transform: scaleX(-1);
  }
`;

const Icon = ({ name, onClick, noFlip }) => {
  return (
    <IconWrapper onClick={onClick} className={noFlip ? '' : 'flip-icon'}>
      <i className={`icon icon-${name}`} title={name} />
    </IconWrapper>
  );
};

export default Icon;
```

Not looking too much at the implementation details, by using a wrapper as the one above, you can easily pass in a `noFlip` prop to the icons that you really don't want to flip (brand ones), and for all the other icons, it is already covered!

## Conclusion

1- Take a closer look into your icons and classify them beforehand, so that you can easily reverse the ones you need when implementing the code.

2- Create a `Icon` component that serves as a wrapper and the source of truth of all your icons. This is where the RTL vs LTR logic should live.

## Next Chapter

On the next chapter we will take a closer look on **external components**, and how we can also make them RTL compatible.

_Make sure to follow me on [twitter](https://twitter.com/P_FFigueiredo), to stay tuned with the latest updates on these series!_