icons and emoji accessibility

December 10, 2022 Reading time: 4 minutes

I recently discovered about Font Awesome and Unicode emojis. I thought: this a great way to have images without actually hosting them! As I'd like my projects to require a minimum of ressources that may suit my needs. But wait. I'd like these projects to also be as accessible as possible. How can you achieve that when this HTML element (for font awesome) and character (for Unicode emoji) are not HTML images (<img>) and therefore cannot have an alt attribute containing the relevant alternative text?

Let's dig this out!

Font Awesome

Well, for Font Awesome, the answer is on their website, they have a dedicated section! It is beautifully sumed up on Upyouray11.com so I'll just try to sum up the sum up, so to have a reference somewhere on my own blog.

Decorative image

Hide it from assistive technologies with aria-hidden attribute, value true.

<i aria-hidden="true" class="fas fa-car"></i>

Action image

Hide the icon itself but indicate the link purpose (menu, home, cart...) with aria-label attribute on the action HTML element

<a href="/" aria-label="Home">
  <i aria-hidden="true" class="fas fa-home"></i>
</a>

Meaningful images

Hide the alternative text in a span element via CSS so it's dedicated to assistive technologies

HTML would be

<i aria-hidden="true" class="fas fa-plant" title="Vegetarian"></i>
<span class="screen-reader-only">Vegetarian</span>

Note that we are adding a title attribute to help sighted mouse users

CSS would be

.screen-reader-only {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

Unicode emojis

Decorative image

Hide it from assistive technologies with aria-hidden attribute, value true in an additionnal span element:

<span aria-hidden="true">&#x1F4D6;</span>

Other images

Nest the emoji into a span element and give it a role attribute, value img and the alternative text in aria-label attribute's value:

<span role="img" aria-label="open book">&#x1F4D6;</span>

Now, let's apply this in this blog's contents!


flexbox cheat-set

December 3, 2022 Reading time: 4 minutes

I still can't remember wich property apply to which axis so let's build a cheat-set! Again, many thanks to FreeCodeCamp courses for the detailed explanations.

For starters, in our HTML document we'll need a container as well as children boxes. For instance:

<body>
<main>
<section>
<h2>section 1</h2>
<p>Lorem ipsum dolor sit amet.</p>
</section>
<section>
<h2>section 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</section>
<section>
<h2>section 3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</section>
</main>
</body>

Here the container is main and it's children boxes are section. Let's tell the browser how to position elements on the page:

main {
display: flex;
justify-content: space-evenly;
}

Explanations & other possibilites

First thing first, we have to declare we're using the flex model. Use display property value flex for that.

Main axis

The main axis is declared with flex-direction property:

  • row (default): horizontal axis with flex items from left to right
  • row-reverse: horizontal axis with flex items from right to left
  • column: vertical axis with flex items from top to bottom
  • column-reverse: column-reverse: vertical axis with flex items from bottom to top

The justify-content property determines how the items inside a flex container are positioned along the main axis. It can take this values (find all on mdn web docs):

  • Positional alignment: center | start | end | flex-start | flex-end | left | right
  • Distributed alignment: space-between | space-around | space-evenly | stretch

The flex-wrap property determines how the flex items behave when the flex container is too small. Otherwise, items will shrink if needed. It can take this values:

  • nowrap (default)
  • wrap
  • wrap-reverse

The gap CSS property sets the gaps (gutters) between rows and columns. It is a shorthand for row-gap and column-gap. It can take one or two lenght value(s) (such as 1em for instance) or percentage value(s).

Cross axis

The align-items property controls alignment of all items on the cross axis. It can take this values:

  • Positional alignment: center | start | end | flex-start | flex-end
  • Baseline alignment: baseline | first baseline | last baseline

device screen sizes

December 2, 2022 Reading time: ~1 minute

Here's a list of screen sizes by device:

  • 320px — 480px: Mobile devices.
  • 481px — 768px: iPads, Tablets.
  • 769px — 1024px: Small screens, laptops.
  • 1025px — 1200px: Desktops, large screens.
  • 1201px and more — Extra large screens, TV.

(Thanks FreeCodeCamp!)

In the CSS document, place the @media rule after the first no-rule is applied. For instance:

main {
width: 55%;
max-width: 400px;
}

@media screen and (max-width: 500px) {
main {
width: 85%;
}
}

sticky nav bar (and other position considerations)

November 26, 2022 Reading time: 4 minutes

Une autre chose avec laquelle j'ai un peu lutté, c'est de mettre deux éléments l'un en-dessous de l'autre (<nav> et <main>) sans que le texte présent dans <main> passe sous la barre de <nav> qui a un positionnement forcé.

Fragment de la page html sur laquelle je travaille :

<body>
<nav>
nav bar
</nav>
<main>
<section>
<h2>section 1</h2>
<p>Ut consectetur eros efficitur, convallis tortor ut, placerat sapien.</p>
</section>
<section>
<h2>section 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</section>
</main>
</body>

Proposition de solution pour garder la partie de navigation en haut de page :

body {
margin: 0;
}

nav {
position: -webkit-sticky; /* Safari */
position: sticky;
height: auto;
top: 0;
background-color: #251D3A;
color: #E04D01;
}

main {
overflow: hidden;
background-color: #FF7700;
color: #2A2550;
}

Explications :

Il y a plusieurs valeurs possibles pour la propriété position qui indique la façon dont un élément doit être positionné dans le document. Par défaut, le flux du document se déroule de haut en bas. On peut sortir un élément du flux avec la position absolute par exemple, pour rendre le positionnement de l'élément relatif à son élément parent ou encore la position fixed si on veut le positionner relativement à la fenêtre du navigateur. La valeur sticky quant à elle permet d'aller de la valeur relative (ici, relatif à <body> qui remplit 100% de l'espace) à un positionnement fixe (par exemple : top: 0, soit haut de page) en fonction du défilement du document.

Attention : Internet Explorer ne gère pas le positionnement sticky et Safari a besoin d'un préfixe -webkit.

Elle est complétée par la propriété overflow de l'élément suivant avec une valeur hidden pour que le contenu remplisse tout l'espace disponible avec possibilité de défilement sans barre de défilement.

Il y a peut-être des façons de faire plus propres mais pour l'exemple en question ça fonctionne, en plus d'être très court ce qui est appréciable. On pourra ajouter des marges intérieures (padding) pour que ce soit un peu moins moche, par exemple :

padding: 0 1em;

pour <body> et <main> et

padding: 1em;

pour <nav>.

(si deux valeurs : la première est valable pour haut/bas du bloc, la deuxième pour droite/gauche. Si une seule valeur : valable pour les quatre côtés)


<body> default margin

November 24, 2022 Reading time: 2 minutes

J'ai enfin compris que certains éléments HTML avaient une marge et/ou padding par défaut appliquée par les navigateurs, par exemple <body> a une marge par défaut de 8px sur Firefox. Résultat : si vous coloriez votre page en jaune :

body {
background-color: gold;
}

et votre tête de page en bleu (en fournissant une hauteur pour que le bloc soit visible) :

header {
background-color: aqua;
height: 200px;
}

pour la page suivante :

<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<header>
</header>
<main>
</main>
</body>
</html>

eh bien vous verrez apparaitre ce qui semble être une bordure non sollicitée de votre <header> ! D'après ce que j'ai compris, il s'agit plutôt de l'espace que se ménage le <body> par rapport à ses éléments enfants donc c'est plutôt sur <body> qu'il faut agir. Pour le débarrasser de ses marges cachées, proposition de solution :

body {
background-color: gold;
margin: 0;
}

(Voir sinon une autre proposition dans un article plus récent.) C'est le même principe pour tous les éléments qui ont une marge par défaut paramétrée par le navigateur, <h1> par exemple ou encore, <ul>.


<head> boilerplate

November 23, 2022 Reading time: 5 minutes
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Une nouvelle page HTML" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Page test</title>
<link rel="stylesheet" href="style.css"/>
<script src="script.js" defer></script>
<base href="https://www.mywebsiteURL.com/" target="_blank">
</head>
<body>
</body>
</html>

Explanations:

<!DOCTYPE html>

so the browser follows the HTML specification

<html lang="fr">

html tag -> to inform the browser it's an HTML document
lang attribute -> to allow screen readers to invoke the correct pronunciation

<head>

head tag -> machine-readable information about the document

<meta>

meta tag -> to add metadata with no specifc tag

charset attribute -> (charset stands for  "character set")  to specify the document's character encoding (UTF-8 being the universal character set, encodes multiple languages). This tag/attribute must be located within the first 1024 bytes of the document.

name and content attributes (they come together: metadata's name, metadata's value)
-> name value description -> to put in content's value a very short description of the page's content. This will be used by search engines to provide a description of the page.
-> name value viewport (for a browser, 'viewport' means what's visible, a viewport definition tells the browser how to render the page) -> to put in content's value some elements like width that could be device-width and the ratio between the device width and the display zone size (positive number between 0.0 and 10.0), separated by comas. It helps the styling of the page looking similar on mobile as it does on a desktop or laptop and sets the initial zoom level when the page is first loaded by the browser.

<title>

title tag -> to specify the website's title where the HTML document belongs; the title page could also be added (that's what is appearing in the brower's tabs). It's also this title that is indexed by search engines. Note that this is also useful for people using assitive technologies to rapidly aprenhend the website's content.

<link>

link tag -> to link the HTML document to an external resource, for instance a stylesheet or JavaScript
rel attribute -> to specify the relation. Use stylesheet for CSS
href attribute -> stylesheet's URL (can be relative)

<base>

base tag -> specifies a default URL and a default target for all links on a page