Vous trouverez de nombreux didacticiels 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 existe 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'un TABLE ne fonctionnera pas non plus ici:
- Si vous centrez tous les TD, le premier et le dernier élément ne sont pas alignés correctement.
- Si vous alignez à gauche et à 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 de mettre en œuvre cela de manière propre en utilisant HTML et CSS?
span
au lieu d'unhr
! Cela ne fonctionne pas vraiment, le HR occupe un espace visible - utilisez#menu { border: solid 1px green; }
pour confirmer. De plus,display: inline-block;
ne fonctionne pas sur IE (... 7? CompatibilityView?) Pour les éléments qui ne sont pas naturellement des éléments en ligne. HR est un élément de bloc, donc je suppose que le bloc en ligne ne fonctionne pas pour HR sur IE. Quoi qu'il en soit, span.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; }
<div id="menu"> <ul> <li><a href="#">Menu item 1</a></li> <li><a href="#">Menu item 2</a></li> <li><a href="#">Menu item 3</a></li> <li><a href="#">Menu item 4</a></li> <li><a href="#">Menu item 5</a></li> </ul> </div>
La raison pour laquelle j'ai la balise a comme an
inline-block
est que je ne veux pas que les mots à l'intérieur soient également justifiés, et je ne veux pas non plus utiliser d'espaces insécables.la source
text-justify: distribute-all-lines;
auul
sélecteur. Semble être des trucs IE propriétaires.width: 100%
place demargin-left: 100%
:ul:after{content:""; margin-left:100%;}
J'ai une solution. Fonctionne dans FF, IE6, IE7, Webkit, etc.
Assurez-vous de ne pas mettre d'espaces avant de fermer le fichier
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; }
<div class="outer"> <span class="inner">THE MENU ITEMS</span> <span class="inner">SHOULD BE</span> <span class="inner">JUSTIFIED</span> <span class="inner">JUST AS</span> <span class="inner">PLAIN TEXT</span> <span class="inner">WOULD BE</span> <span class="finish"></span> </div>
la source
.outer
line-height: 0
forces la hauteur de la liste à rendre comme si elle était constituée d'une seule ligne.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; }
la source
encore une autre solution. Je n'avais aucune option pour aborder le html comme ajouter une classe distinguée, etc., donc j'ai trouvé un moyen purement css.
Fonctionne sous 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: ' '; }
<ul> <li><a href="#">home</a></li> <li><a href="#">exposities</a></li> <li><a href="#">werk</a></li> <li><a href="#">statement</a></li> <li><a href="#">contact</a></li> </ul>
la source
Faites-en un
<p>
avectext-align: justify
?Mise à jour : Nevermind. Cela ne fonctionne pas du tout comme je le pensais.
Mise à jour 2 : ne fonctionne dans aucun navigateur autre que IE pour le moment, mais CSS3 prend en charge cela sous la forme de
text-align-last
la source
text-align-last
fonctionne dans tous les navigateurs autres que Safari . Cela devrait être l'adversaire possible de l'approche flexbox ou du hack span .Pour les navigateurs basés sur Gecko, j'ai proposé cette solution. Cette solution ne fonctionne pas avec les navigateurs WebKit (par exemple, Chromium, 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 une img) qui garantit que le paragraphe fait 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:
<div style="width:500px; background:#eee;"> <p style="text-align:justify"> <a href="#">THE MENU ITEMS</a> <a href="#">SHOULD BE</a> <a href="#">JUSTIFIED</a> <a href="#">JUST AS</a> <a href="#">PLAIN TEXT</a> <a href="#">WOULD BE</a> <img src="/Content/Img/stackoverflow-logo-250.png" width="400" height="0"/> </p> <p>There's an varying number of text-only menu items and the page layout is fluid.</p> <p>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.</p> <p>The number is varying,so there's no chance to pre-calculate the optimal widths.</p> <p>Note that a TABLE won't work here as well:</p> <ul> <li>If you center all TDs, the first and the last item aren't aligned correctly.</li> <li>If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.</li> </ul> </div>
Remarque: remarquez-vous que j'ai triché? Pour ajouter l'élément de remplissage d'espace, je dois deviner la largeur de la barre de menus. Cette solution n’est donc pas complètement aux règles.
la source
Le texte n'est justifié que si la phrase provoque naturellement un saut de ligne. Donc, tout ce que vous avez à faire est naturellement de forcer un saut de ligne et de cacher ce qui se trouve 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 e.g. 1000px if your ul has no width */ }
HTML:
<ul> <li><a href="/">The</a></li> <li><a href="/">quick</a></li> <li><a href="/">brown</a></li> <li><a href="/">fox</a></li> <li class="break"> </li> </ul>
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 n'est pas sur la même ligne, vous verrez des petits un 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é dans IE7, IE8, IE9, Chrome, Firefox 4.
la source
si aller avec javascript c'est possible (ce script est basé sur mootools)
<script type="text/javascript">//<![CDATA[ window.addEvent('load', function(){ var mncontainer = $('main-menu'); var mncw = mncontainer.getSize().size.x; var mnul = mncontainer.getFirst();//UL var mnuw = mnul.getSize().size.x; var wdif = mncw - mnuw; var list = mnul.getChildren(); //get all list items //get the remained width (which can be positive or negative) //and devided by number of list item and also take out the precision var liwd = Math.floor(wdif/list.length); var selw, mwd=mncw, tliw=0; list.each(function(el){ var elw = el.getSize().size.x; if(elw < mwd){ mwd = elw; selw = el;} el.setStyle('width', elw+liwd); tliw += el.getSize().size.x; }); var rwidth = mncw-tliw;//get the remain width and set it to item which has smallest width if(rwidth>0){ elw = selw.getSize().size.x; selw.setStyle('width', elw+rwidth); } }); //]]> </script>
et le css
<style type="text/css"> #main-menu{ padding-top:41px; width:100%; overflow:hidden; position:relative; } ul.menu_tab{ padding-top:1px; height:38px; clear:left; float:left; list-style:none; margin:0; padding:0; position:relative; left:50%; text-align:center; } ul.menu_tab li{ display:block; float:left; list-style:none; margin:0; padding:0; position:relative; right:50%; } ul.menu_tab li.item7{ margin-right:0; } ul.menu_tab li a, ul.menu_tab li a:visited{ display:block; color:#006A71; font-weight:700; text-decoration:none; padding:0 0 0 10px; } ul.menu_tab li a span{ display:block; padding:12px 10px 8px 0; } ul.menu_tab li.active a, ul.menu_tab li a:hover{ background:url("../images/bg-menutab.gif") repeat-x left top; color:#999999; } ul.menu_tab li.active a span,ul.menu_tab li.active a.visited span, ul.menu_tab li a:hover span{ background:url("../images/bg-menutab.gif") repeat-x right top; color:#999999; } </style>
et le dernier html
<div id="main-menu"> <ul class="menu_tab"> <li class="item1"><a href="#"><span>Home</span></a></li> <li class="item2"><a href="#"><span>The Project</span></a></li> <li class="item3"><a href="#"><span>About Grants</span></a></li> <li class="item4"><a href="#"><span>Partners</span></a></li> <li class="item5"><a href="#"><span>Resources</span></a></li> <li class="item6"><a href="#"><span>News</span></a></li> <li class="item7"><a href="#"><span>Contact</span></a></li> </ul> </div>
la source
Balisage plus simple, testé dans Opera, FF, Chrome, IE7, IE8:
<div class="nav"> <a href="#" class="nav_item">nav item1</a> <a href="#" class="nav_item">nav item2</a> <a href="#" class="nav_item">nav item3</a> <a href="#" class="nav_item">nav item4</a> <a href="#" class="nav_item">nav item5</a> <a href="#" class="nav_item">nav item6</a> <span class="empty"></span> </div>
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 .
la source
Ceci peut être réalisé parfaitement par quelques mesures soigneuses et le sélecteur du dernier enfant.
ul li { margin-right:20px; } ul li:last-child { margin-right:0; }
la source
Je sais que la question d'origine spécifiait HTML + CSS, mais elle ne disait pas spécifiquement pas de javascript ;)
En essayant de garder le css et le balisage aussi propres que possible, et aussi sémantiquement significatifs que possible (en utilisant un UL pour le menu), j'ai proposé cette suggestion. Probablement pas idéal, mais cela peut être un bon point de départ:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>Kind-of-justified horizontal menu</title> <style type="text/css"> ul { list-style: none; margin: 0; padding: 0; width: 100%; } ul li { display: block; float: left; text-align: center; } </style> <script type="text/javascript"> setMenu = function() { var items = document.getElementById("nav").getElementsByTagName("li"); var newwidth = 100 / items.length; for(var i = 0; i < items.length; i++) { items[i].style.width = newwidth + "%"; } } </script> </head> <body> <ul id="nav"> <li><a href="#">first item</a></li> <li><a href="#">item</a></li> <li><a href="#">item</a></li> <li><a href="#">item</a></li> <li><a href="#">item</a></li> <li><a href="#">last item</a></li> </ul> <script type="text/javascript"> setMenu(); </script> </body> </html>
la source