Les tableaux en HTML c'est vraiment génial à un tel point que personne ne les utilise.
Et je sais pourquoi, fût un temps béni où ils servaient à la mise en page alors que, la finalité du tag <table> a toujours été de présenter des DONNéES TABULAIRES.
Avec les attributs qui-sentent-la-cave de table comme cellspacing ou cellpadding on pouvait même se passer de CSS pour créer une mise en page bien moche mais qui tient vaguement la route.
Soit. Revenons à nos Ovis et la second question existentielle: qui présente des données tabulaires sur son site?
Même les gens qui devraient le faire utilisent plutôt des listes à puces ou des images.
On vit d'ailleurs à une bonne vieille époque où tu peux demander à une IA de te générer un vieux visuel avec des erreurs dedans mais bon les gens vont pas les voir donc tu le poste quand même sur les réseaux sociaux en espérant attirer les commentaires "ah oui, très instructif!" et enfin devenir populaire avec les mamys sur Facebook.
Ceci dit, le(s) gros coupable(s) de pourquoi les tableaux ça craint encore plus que le manque cuisant de bidets dans les toilettes de mon pays, ce sont les téléphones mobiles.
Vous avez déjà essayé de présenter des DONNéES TABULAIRES sur une largeur de 4 centimètres?
On peut pas faire rentrer beaucoup de données tabulaires là dedans avant que ça déborde. Non sérieusement, même mon aspicot rentre pas là dedans.
Voilà un autre caillou à ajouter dans mon gros sac de de raisons de détester le web design à cause des téléphones mobiles.
Oui je sais, les gens normaux c'est à cause du CSS. Mais moi j'aime bien le CSS.
J'en suis arrivé à développer quelques solutions.
Déjà, il y a la solution en place sur le présent blog, que j'ai pas inventée et qui est juste mieux que celle que je vais expliquer dans cet article.
Elle consiste à RETOURNER LE TABLEAU sur mobile. C'est-à-dire que les intitulés de colonnes se retrouvent chacun sur une ligne différente tout à gauche, puis suivent les données.
Ici, je vous présente une alternative super originale qui consiste à détecter avec du JavaScript si du texte déborde, auquel cas on ajoute un petit bouton discret permettant de révéler l'entièreté du contenu dans un bidule flottant.
Chouette idée ou quoi?
Je vous montre déjà la démo, comme ça, si vous êtes déçus, vous pouvez retourner fissa sur TikTok et lamenter ces quelques minutes de carburant solaire perdues sur ce blog que vous aviez juré de ne plus ouvrir à nouveau, mais c'est plus fort que vous même si ça manque de tutos de dessin de sous-vêtements en SVG ces temps-ci.
Ah ouais quand même, c'est beau comme un cyber-truck dis-moi.
Les explications et le code
Le code vous pouvez déjà le voler en cliquant droit sur la démo plus haut puis afficher la source, enregistrer-sous ou que sais-je.
On a besoin:
- D'un tableau avec une largeur fixe; C'est moins simple à créer que ça en a l'air, l'attribut étrange table-layout: fixed; est parfois nécessaire et j'ai appris son existence ce matin;
- De certaines cellules marquées d'une classe CSS particulière (enfin c'est comme ça que je vais procéder mais le monde est votre huitre);
- Ces cellules doivent avoir certaines propriétés CSS comme par exemple text-overflow: ellipsis.
Voici un exemple de classe CSS sus-mentionnée que je n'applique donc qu'à certaines colonnes mais on pourrait les appliquer à toutes:
.expandable-cell {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Avec ça les cellules qui débordent de texte se retrouvent avec des "..." à la fin de la ligne avec le contenu débordant retiré.
Pour afficher le texte complet je décide d'utiliser l'élément natif dialog parce qu'il existe et que tout le monde s'en fout.
<dialog id="expanded">
</dialog>
<main>
<table>
<thead>
<tr>
<th>Colonne 1</th>
<th>Colonne 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Petit texte ici</td>
<td class="expandable-cell">Pourquoi y a pas d'animations ici c'est un peu bizarre non</td>
</tr>
<tr>
<td>Coucou</td>
<td class="expandable-cell">Text court</td>
</tr>
<tr>
<td>Encore un peu</td>
<td class="expandable-cell">Lorem Ipsum Dolor Sit Amet La Baraka de Buratta de Barzotti</td>
</tr>
</tbody>
</table>
</main>
Pour que le dialog apparaisse au bon endroit il faut virer (on dit reset dans le metier) le margin: auto; qu'il reçoit du navigateur:
#expanded {
/* Remove the margin auto thingy */
margin: 0;
}
Et voici tout le JS:
const expanded = document.querySelector("#expanded")
const hideExpandedCell = () => expanded.close()
// Just close on any keypress:
expanded.addEventListener("keydown", hideExpandedCell)
const setupExpandables = () => {
const expandables = document.querySelectorAll(".expandable-cell")
for (const cell of expandables) {
if (cell.offsetWidth < cell.scrollWidth) {
// Expandable cell.
// Set title attribute:
cell.title = cell.textContent
// Add the button:
const expLink = document.createElement('img')
expLink.title = "Show the full text"
expLink["aria-label"] = "Expand collapsed text"
expLink["aria-role"] = "button"
expLink.className = "table-icon"
expLink.src = "circle-plus.svg"
expLink.addEventListener('click', (e) => expandCell(e))
cell.prepend(expLink)
}
}
document.addEventListener("click", hideExpandedCell)
}
const expandCell = (e) => {
e.stopPropagation()
expanded.textContent = e.currentTarget.nextSibling.textContent
const scrollTop = document.documentElement.scrollTop
const textBoudingRect = e.currentTarget.getBoundingClientRect()
const newTop = textBoudingRect.bottom + 5 + scrollTop
const newLeft = textBoudingRect.left
expanded.style.top = `${newTop}px`
expanded.style.left = `${newLeft}px`
expanded.show()
}
// Initialize:
setupExpandables()
Remarquez que ce bon vieux dialog ne se ferme pas tout seul en cliquant à côté, ni en pressant la touche "Esc".
C'est pas un "modal" donc je crois que l'absence de réponse à "Esc" est normale, mais ils ont l'air de dire dans la doc que cliquer à côté devrait fonctionner.
J'ai dû rater un truc. Ce sera pour un prochain glorieux article.
Du coup j'ai l'événement keydown qui ferme le dialog pour n'importe quelle touche. Plus facile comme ça.
La function setupExpandables qui ajoute tous les petits boutons doit aussi créer un plan foireux pour que cliquer en dehors du dialog le ferme:
document.addEventListener("click", hideExpandedCell)
Dans setupExpandables, on parcourt aussi toutes les cellules concernées par ce fantastique plan pour tester SI LE TEXTE DEPASSE.
Comment qu'on fait ça demandez-vous?
J'ai découvert quelque part que si la propriété offsetWidth de la cellule est plus petite que scrollWidth, ben euh... Ça déborde. Apparemment. Cool.
Il s'agit ensuite de créer un élément img et utiliser ça comme bouton. Pourquoi pas créer un bouton avec une image dedans? Parce que ça prend 15 lignes en plus.
Le "bouton" affiche le dialog juste en dessous de la cellule en copiant son textContent.
Voilà c'est super hein.
On pourrait aussi utiliser innerHTML et copier tout le HTML. On pourrait aussi aller prendre l'air.
Et euh, pourquoi le bouton il est pas derrière le texte?
Oui. Pourquoi c'est pas comme ça:
Malheureusement, si on essaye de mettre le bouton à droite du texte il n'apparait plus, parce qu'il est dans la partie qui overflow derrière les trois petits points.
On est obligés de le mettre devant.
J'avais dit que ce plan était un peu pourri.
Une possible alternative serait de rendre le texte cliquable (clickable? Qu'on peut cliquer dessus) en le transformant en genre de lien plutôt que d'ajouter un bouton. Ou ajouter un bouton mais au dessus.
Je vous laisse rendre tout ça moins médiocre et vous montre l'horreur une dernière fois:
Utilisez "afficher la source" pour révéler le code 100% bio sans IA.



Commentaires
Il faut JavaScript activé pour écrire des commentaires ici