Comment puis-je vraiment justifier un menu horizontal en HTML + CSS?

Vous trouvez beaucoup de tutoriels sur les barres de menus en HTML, mais pour ce cas spécifique (bien que générique IMHO), je n’ai trouvé aucune solution décente:

# THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE # # ^ ^ # 
  • Il y a un nombre variable d’éléments de menu contenant uniquement du texte et la mise en page est fluide.
  • Le premier élément de menu doit être aligné à gauche, le dernier élément de menu doit être aligné à droite.
  • Les éléments restants doivent être répartis de manière optimale dans la barre de menus.
  • Le nombre varie, il n’y a donc aucune chance de pré-calculer les largeurs optimales.

Notez qu’une TABLE ne fonctionnera pas aussi ici:

  • Si vous centrez tous les TD, le premier et le dernier élément ne sont pas correctement alignés.
  • Si vous alignez à gauche et alignez à droite le premier resp. les derniers éléments, l’espacement sera sous-optimal.

N’est-il pas étrange qu’il n’y ait pas de moyen évident d’implémenter cela de manière propre en utilisant HTML et CSS?

Approche moderne – Flexboxes !

Maintenant que CSS3 Flexbox prend mieux en charge les navigateurs , certains d’entre nous peuvent enfin les utiliser. Ajoutez simplement des préfixes de fournisseurs supplémentaires pour une plus grande couverture du navigateur .

Dans ce cas, il vous suffit de définir l’ display l’élément parent sur flex , puis de modifier la propriété Justification justify-content soit space-between space-around ou space-around afin d’append de l’espace entre ou autour des éléments flexbox enfants.

En utilisant justify-content: space-between – ( exemple ici) :

 ul { list-style: none; padding: 0; margin: 0; } .menu { display: flex; justify-content: space-between; } 
  

La chose la plus simple à faire est de forcer la ligne à se briser en insérant un élément à la fin de la ligne qui occupera plus que l’espace disponible, puis le cachera. Je l’ai accompli assez facilement avec un simple élément span tel que:

 #menu { text-align: justify; } #menu * { display: inline; } #menu li { display: inline-block; } #menu span { display: inline-block; position: relative; width: 100%; height: 0; } 
  

Ok, cette solution ne fonctionne pas sur IE6 / 7, à cause du manque de support de :before / :after , mais:

 ul { text-align: justify; list-style: none; list-style-image: none; margin: 0; padding: 0; } ul:after { content: ""; margin-left: 100%; } li { display: inline; } a { display: inline-block; } 
  

J’ai une solution Fonctionne dans FF, IE6, IE7, Webkit, etc.

Assurez-vous de ne pas mettre d’espaces avant de fermer le span.inner . IE6 va casser.

Vous pouvez éventuellement donner à .outer une largeur

 .outer { text-align: justify; } .outer span.finish { display: inline-block; width: 100%; } .outer span.inner { display: inline-block; white-space: nowrap; } 
 
THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE

Fonctionne avec Opera, Firefox, Chrome et IE

 ul { display: table; margin: 1em auto 0; padding: 0; text-align: center; width: 90%; } li { display: table-cell; border: 1px solid black; padding: 0 5px; } 

encore une autre solution. Je n’avais aucune option pour aborder le HTML comme append une classe distinguée, etc., donc j’ai trouvé un moyen css pur.

Fonctionne dans Chrome, Firefox, Safari..ne sais pas sur IE.

Test: http://jsfiddle.net/c2crP/1

 ul { margin: 0; padding: 0; list-style: none; width: 200px; text-align: justify; list-style-type: none; } ul > li { display: inline; text-align: justify; } /* declaration below will add a whitespace after every li. This is for one line codes where no whitespace (of breaks) are present and the browser wouldn't know where to make a break. */ ul > li:after { content: ' '; display: inline; } /* notice the 'inline-block'! Otherwise won't work for webkit which puts after pseudo el inside of it's parent instead of after thus shifting also the parent on next line! */ ul > li:last-child:after { display: inline-block; margin-left: 100%; content: ' '; } 
  

Faites-en un

avec text-align: justify ?

Mise à jour : Nevermind. Cela ne fonctionne pas du tout comme je le pensais.

Mise à jour 2 : Ne fonctionne pas dans les navigateurs autres qu’IE, mais CSS3 a le support sous la forme de text-align-last

Pour les navigateurs basés sur Gecko, j’ai trouvé cette solution. Cette solution ne fonctionne pas avec les navigateurs WebKit (par exemple, Chrome, Midori, Epiphany), ils affichent toujours un espace après le dernier élément.

Je mets la barre de menu dans un paragraphe justifié . Le problème est que la dernière ligne d’un paragraphe justifié ne sera pas justifiée pour des raisons évidentes. Par conséquent, j’ajoute un élément invisible large (par exemple un img) qui garantit que le paragraphe a au moins deux lignes de long.

Maintenant, la barre de menus est justifiée par le même algorithme que le navigateur utilise pour justifier le texte brut.

Code:

 

THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE

There's an varying number of text-only menu items and the page layout is fluid.

The first menu item should be left-aligned, the last menu item should be right-aligned. The remaining items should be spread optimal on the menu bar.

The number is varying,so there's no chance to pre-calculate the optimal widths.

Note that a TABLE won't work here as well:

  • If you center all TDs, the first and the last item aren't aligned correctly.
  • If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.

Remarque: remarquez-vous que j’ai sortingché? Pour append l’élément de remplissage d’espace, je dois deviner la largeur de la barre de menus. Donc, cette solution n’est pas tout à fait conforme aux règles.

Le texte n’est justifié que si la phrase provoque naturellement un saut de ligne. Donc, tout ce que vous devez faire est de forcer naturellement un saut de ligne et de cacher ce qui se passe sur la deuxième ligne:

CSS:

 ul { text-align: justify; width: 400px; margin: 0; padding: 0; height: 1.2em; /* forces the height of the ul to one line */ overflow: hidden; /* enforces the single line height */ list-style-type: none; background-color: yellow; } ul li { display: inline; } ul li.break { margin-left: 100%; /* use eg 1000px if your ul has no width */ } 

HTML:

  

L’élément li.break doit être sur la même ligne que le dernier élément de menu et doit contenir du contenu (dans ce cas, un espace insécable), sinon dans certains navigateurs, s’il ne se trouve pas sur la même ligne espace supplémentaire à la fin de votre ligne, et s’il ne contient aucun contenu, il est ignoré et la ligne n’est pas justifiée.

Testé sous IE7, IE8, IE9, Chrome, Firefox 4.

si aller avec javascript c’est possible (ce script est basé sur mootools)

  

et le css

  

et le dernier HTML

  

Balisage simplifié, testé sous Opera, FF, Chrome, IE7, IE8:

  

et css:

 .nav { width: 500px; height: 1em; line-height: 1em; text-align: justify; overflow: hidden; border: 1px dotted gray; } .nav_item { display: inline-block; } .empty { display: inline-block; width: 100%; height: 0; } 

Exemple en direct .

Ceci peut être réalisé parfaitement par des mesures soigneuses et le sélecteur de dernier enfant.

 ul li { margin-right:20px; } ul li:last-child { margin-right:0; } 

Je connais la question d’origine spécifiée HTML + CSS, mais elle ne dit pas spécifiquement pas de javascript 😉

En essayant de garder le css et le balisage aussi propres que possible, et aussi sémantiquement que possible (en utilisant un UL pour le menu), j’ai trouvé cette suggestion. Probablement pas idéal, mais ça peut être un bon sharepoint départ:

    Kind-of-justified horizontal menu