Вы найдете множество руководств по строкам меню в HTML, но для этого конкретного (хотя IMHO общего) случая я не нашел достойного решения:
# THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE #
# ^ ^ #
- Существует разное количество пунктов меню, состоящих только из текста, и макет страницы плавный.
- Первый пункт меню должен быть выровнен по левому краю, последний пункт меню должен быть выровнен по правому краю.
- Остальные пункты должны быть оптимально распределены по строке меню.
- Количество разное, поэтому нет возможности заранее рассчитать оптимальную ширину.
Обратите внимание, что ТАБЛИЦА здесь также не будет работать:
- Если вы центрируете все TD, первый и последний элемент не выровнены правильно.
- Если вы выровняете по левому краю и по правому краю первый соотв. последние пункты, интервал будет неоптимальным.
Разве не странно, что нет очевидного способа реализовать это чистым способом с помощью HTML и CSS?
span
вместоhr
! На самом деле это не работает, HR занимает видимое пространство - используйте#menu { border: solid 1px green; }
для подтверждения. Кроме того,display: inline-block;
не работает в IE (... 7? CompatibilityView?) Для элементов, которые не являются встроенными элементами. HR - это блочный элемент, поэтому я предполагаю, что встроенный блок не работает для HR в IE. Во всяком случае, размах.Хорошо, это решение не работает в IE6 / 7 из-за отсутствия поддержки
:before
/:after
, но: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>
Причина, по которой у меня есть тег a,
inline-block
заключается в том, что я не хочу, чтобы слова внутри также были оправданы, и я также не хочу использовать неразрывные пробелы.источник
text-justify: distribute-all-lines;
вul
селектор. Кажется, это проприетарный IE.width: 100%
вместоmargin-left: 100%
:ul:after{content:""; margin-left:100%;}
Есть решение. Работает в FF, IE6, IE7, Webkit и др.
Убедитесь, что вы не добавили пробелов перед закрытием
span.inner
. IE6 сломается.При желании можно указать
.outer
ширину.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>
источник
.outer
line-height: 0
заставляет отображать высоту списка, как если бы он состоял из одной строки.Работает с Opera, Firefox, Chrome и 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; }
источник
еще одно решение. У меня не было возможности заняться html, например добавить выделенный класс и т. Д., Поэтому я нашел чистый способ css.
Работает в Chrome, Firefox, Safari .. не знаю об IE.
Тест: 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>
источник
Сделать это
<p>
сtext-align: justify
?Обновление : Nevermind. Это совсем не работает, как я думал.
Обновление 2 : сейчас не работает ни в каких браузерах, кроме IE, но CSS3 поддерживает это в виде
text-align-last
источник
text-align-last
работает в любых браузерах, кроме Safari . Это должен быть возможный противник подхода flexbox или взлома span .Для браузеров на базе Gecko я придумал это решение. Это решение не работает с браузерами WebKit (например, Chromium, Midori, Epiphany), они по-прежнему показывают конечный пробел после последнего элемента.
Я помещаю строку меню в абзац по ширине . Проблема в том, что последняя строка выровненного абзаца не будет выровнена по очевидным причинам. Поэтому я добавляю широкий невидимый элемент (например, img), который гарантирует, что абзац состоит как минимум из двух строк.
Теперь строка меню выравнивается по тому же алгоритму, который браузер использует для выравнивания обычного текста.
Код:
<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>
Реплика: Вы заметили, что я обманул? Чтобы добавить элемент-заполнитель пространства, я должен предположить ширину строки меню. Так что это решение не полностью соответствует правилам.
источник
Текст оправдан только в том случае, если предложение естественным образом вызывает разрыв строки. Итак, все, что вам нужно сделать, это естественным образом принудительно разорвать строку и скрыть то, что находится во второй строке:
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>
Элемент li.break должен находиться в той же строке, что и последний пункт меню, и должен содержать некоторый контент (в данном случае неразрывный пробел), в противном случае в некоторых браузерах, если он не находится в той же строке, вы увидите небольшой лишний пробел в конце вашей строки, и если он не содержит содержимого, он игнорируется и строка не обосновывается.
Протестировано в IE7, IE8, IE9, Chrome, Firefox 4.
источник
если использовать javascript, то это возможно (этот сценарий основан на 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>
и 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>
и последний 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>
источник
Более простая разметка, протестированная в 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>
и 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; }
Живой пример .
источник
Этого можно добиться с помощью некоторых тщательных измерений и селектора последнего дочернего элемента.
ul li { margin-right:20px; } ul li:last-child { margin-right:0; }
источник
Я знаю, что в исходном вопросе указан HTML + CSS, но он конкретно не говорит об отсутствии javascript ;)
Пытаясь сохранить CSS и разметку как можно более чистыми и как можно более семантически значимыми для (используя UL для меню), я пришел к этому предложению. Возможно, не идеально, но это может быть хорошей отправной точкой:
<!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>
источник