HTML + CSS에서 가로 메뉴를 * 정말로 * 정렬하려면 어떻게합니까?


87

HTML의 메뉴 모음에 대한 많은 자습서를 찾을 수 있지만이 특정 (IMHO 일반) 경우에는 괜찮은 해결책을 찾지 못했습니다.

#  THE MENU ITEMS    SHOULD BE    JUSTIFIED     JUST AS    PLAIN TEXT     WOULD BE  #
#  ^                                                                             ^  #
  • 다양한 텍스트 전용 메뉴 항목이 있으며 페이지 레이아웃은 유동적입니다.
  • 첫 번째 메뉴 항목은 왼쪽 정렬되어야하고 마지막 메뉴 항목은 오른쪽 정렬되어야합니다.
  • 나머지 항목은 메뉴 표시 줄에 최적으로 분산되어야합니다.
  • 숫자는 다양하므로 최적의 너비를 미리 계산할 기회가 없습니다.

TABLE은 여기서도 작동하지 않습니다.

  • 모든 구축 전차를 중앙에 배치하면 첫 번째 항목과 마지막 항목이 올바르게 정렬되지 않습니다.
  • 왼쪽 정렬 및 오른쪽 정렬하면 첫 번째 resp. 마지막 항목의 경우 간격은 차선이됩니다.

HTML과 CSS를 사용하여 깔끔하게 구현할 수있는 확실한 방법이 없다는 것이 이상하지 않습니까?

답변:


43

현대적인 접근 방식 -Flexboxes !

이제 CSS3 플렉스 박스더 나은 브라우저 지원을 제공 하므로 우리 중 일부는 마침내 사용할 수 있습니다. 더 많은 브라우저 적용 범위를 위해 추가 공급 업체 접두사를 추가하기 만하면됩니다 .

이 경우, 당신은 단지 부모 요소의 설정 것 display까지를 flex한 다음 변경 justify-content속성을 하나에 space-between또는 space-around간 또는 아이들의 주위에 공간을 추가하기 위해이 항목 인 flexbox.

사용justify-content: space-between - ( 여기 예) :

ul {
    list-style: none;
    padding: 0;
    margin: 0;
}
.menu {
    display: flex;
    justify-content: space-between;
}
<ul class="menu">
    <li>Item One</li>
    <li>Item Two</li>
    <li>Item Three Longer</li>
    <li>Item Four</li>
</ul>


사용justify-content: space-around - (여기에 예) :

ul {
    list-style: none;
    padding: 0;
    margin: 0;
}
.menu {
    display: flex;
    justify-content: space-around;
}
<ul class="menu">
    <li>Item One</li>
    <li>Item Two</li>
    <li>Item Three Longer</li>
    <li>Item Four</li>
</ul>


83

가장 간단한 방법은 사용 가능한 남은 공간보다 많은 공간을 차지할 줄 끝에 요소를 삽입 한 다음 숨겨 줄을 강제로 끊는 것입니다. 다음과 같은 간단한 span요소 로이 작업을 아주 쉽게 수행했습니다 .

#menu {
  text-align: justify;
}

#menu * {
  display: inline;
}

#menu li {
  display: inline-block;
}

#menu span {
  display: inline-block;
  position: relative;
  width: 100%;
  height: 0;
}
<div id="menu">
  <ul>
    <li><a href="#">Menu item 1</a></li>
    <li><a href="#">Menu item 3</a></li>
    <li><a href="#">Menu item 2</a></li>
  </ul>
  <span></span>
</div>

#menu span선택기 내부의 모든 정크 는 대부분의 브라우저를 만족시키는 데 필요합니다. span요소 의 너비 를 100 %로 강제 설정 해야합니다 display: inline-block. 규칙 에 따라 인라인 요소로 간주되므로 줄 바꿈이 발생합니다 . inline-block또한 요소가 메뉴에 맞지 않아 메뉴가 줄 바꿈되는 span것과 같은 블록 수준 스타일 규칙을 사용할 width수 있습니다.

물론 span사용 사례와 디자인 에 맞게의 너비를 조정해야 하지만 일반적인 아이디어를 얻고 적응할 수 있기를 바랍니다.


1
span대신 a를 사용하면 작동하는 것 같습니다 hr! 실제로 작동하지 않습니다. HR이 가시적 인 공간을 차지하고 있습니다 #menu { border: solid 1px green; }. 확인을 위해 사용하십시오 . 또한 display: inline-block;자연스럽게 인라인 요소가 아닌 요소에 대해서는 IE (... 7? CompatibilityView?)에서 작동하지 않습니다. HR은 블록 요소이므로 IE의 HR에서는 인라인 블록이 작동하지 않는다고 생각합니다. 어쨌든, 스팬.
ANeves은 SE입니다 생각하는 악

9
잘 작동하지만 각 공간을 & ensp;로 바꾸면 결과가 더 예뻐집니다. (n 공백), 메뉴 및 항목 및 1이 서로 가깝게 유지되도록합니다. & nbsp; 사파리에서는 작동하지 않습니다.
yitwail 2011-08-09

15
나는 벽에 머리를 대고 한 시간 이상을 보냈고 이것이 왜 나를 위해 작동하지 않는지 알아 내려고 노력했습니다. 대답은 태그 사이에 공백이 필요하다는 것입니다. WordPress에서 작업 중이며 wp_page_menu는 각 <li> </ li> 뒤에 줄 바꿈을 포함하지 않습니다. preg_replace를 사용하여 추가했으며 이제 작동합니다. Fwewww
Greg Perham

1
요즘이 기능을 사용하려면이를 지원하는 브라우저의 LI에서 display : inline-block을 사용해야하고 display : inline을 공백으로 & nbsp; 지원하지 않는 브라우저에서. 또한 ie7은 인라인 블록을 지원하지 않기 때문에 강제 랩 태그에 인라인을 사용하고 랩을 강제 할 수있을만큼 충분한 & nbsp;을 밀어 넣어야합니다.
Joren

1
Joren의 의견을 명확히하기 위해 UL은 여전히 ​​인라인이어야하며 LI의 인라인 블록이어야합니다.
Moss

12

좋아,이 솔루션은 때문에 지원의 부족, 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이유는 안에있는 단어도 정당화되기를 원하지 않기 때문이며 나도 나누지 않는 공백을 사용하고 싶지 않기 때문입니다.


감사! 당신의 영혼은 요점에 있습니다. 질문을 시작하면 답으로 표시합니다.
Andrevinsky 2014

IE에서 작동하는 데 문제가 있습니다. Google 땅에서 몇 시간을 보낸 후 마침내 다음 블로그 게시물을 찾았습니다. kristinlbradley.wordpress.com/2011/09/15/… 마침내 트릭은 선택기 에 추가 text-justify: distribute-all-lines;하는 것이 었습니다 ul. 독점적 인 IE 물건 인 것 같습니다.
maryisdead

확실하지이 문제가 있지만, 내가 사용하는 경우 width: 100%대신 margin-left: 100%: ul:after{content:""; margin-left:100%;}
유진 노래

8

해결책이 있습니다. 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>


저에게이 솔루션은 Gecko에서는 잘 작동하지만 WebKit 브라우저에서는 작동하지 않습니다 (Chromium, Midori, Epiphany로 테스트 됨). WebKit에서는 마지막 항목 뒤에 공백이 있습니다.
비행기

각 범위 사이에 공백 문자가 하나만 있고 마지막 내부와 마감 사이에 두 문자가 있는지 확인하십시오. 그래도 작동하지 않으면 공백으로 돌아 다니십시오. 웹킷에 버그가 있습니다.
mikelikespie

1
.outer {text-align : justify} .outer span.finish {display : inline-block; 너비 : 100 %} .outer span.inner {display : inline-block; white-space : nowrap} IE6 및 IE7에서는 작동하지 않습니다.
Binyamin

주는 일 .outer line-height: 0이 하나 개의 라인으로 구성된 것처럼 힘을 목록의 높이를하는 렌더링합니다.
kontur 2014 년

4

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;
}

1
불행하게도이 때문에 누락의 IE 7에서 작동하지 않습니다 테이블 셀 지원
필립 마이클

3

또 다른 해결책. 고유 클래스 등을 추가하는 것과 같이 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>


2

<p>함께 만드 text-align: justify시겠습니까?

업데이트 : 신경 쓰지 마세요. 내가 생각했던 것처럼 전혀 작동하지 않습니다.

업데이트 2 : 현재 IE 이외의 브라우저에서는 작동하지 않지만 CSS3는 다음과 같은 형식으로이를 지원합니다.text-align-last


빠르다! 나는 내 자신의 솔루션이 독특하다고 생각했지만 몇 분 만에 비슷한 것을 생각해 냈습니다.
비행

이제 2016 년 text-align-last 에는 Safari 이외의 모든 브라우저에서 작동합니다 . 이것은 플렉스 박스 접근 방식 이나 스팬 해킹 의 가능한 상대가되어야합니다 .
hakatashi

1

Gecko 기반 브라우저의 경우이 솔루션을 생각해 냈습니다. 이 솔루션은 WebKit 브라우저에서 작동하지 않지만 (예 : Chromium, Midori, Epiphany) 마지막 항목 뒤에 계속 공백이 표시됩니다.

메뉴 바를 양쪽 정렬 된 단락 에 넣었습니다 . 문제는 명백한 이유로 양쪽 맞춤 단락의 마지막 줄이 양쪽 맞춤으로 렌더링되지 않는다는 것입니다. 따라서 단락이 최소한 두 줄 길이임을 보증하는 넓은 보이지 않는 요소 (예 : img)를 추가합니다.

이제 메뉴 표시 줄은 브라우저가 일반 텍스트를 정렬하는 데 사용하는 것과 동일한 알고리즘으로 정렬됩니다.

암호:

<div style="width:500px; background:#eee;">
 <p style="text-align:justify">
  <a href="#">THE&nbsp;MENU&nbsp;ITEMS</a>
  <a href="#">SHOULD&nbsp;BE</a>
  <a href="#">JUSTIFIED</a>
  <a href="#">JUST&nbsp;AS</a>
  <a href="#">PLAIN&nbsp;TEXT</a>
  <a href="#">WOULD&nbsp;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>

비고 : 내가 속임수를 쓴 것을 눈치 채 셨나요? 공간 채우기 요소를 추가하려면 메뉴 모음의 너비를 추측해야합니다. 따라서이 솔루션은 완전히 규칙에 따르지 않습니다.


목록 항목에 display : inline을 설정하면 여기에서도 목록을 사용할 수 있습니다. 목록은 메뉴에 대해 더 일반적입니다.
Andrew Vit

@Andrew Vit : 당신이 맞아요. 그것은 대부분 asbjornu의 솔루션이 제안하는 것입니다.
비행기

@flight, 내 대답이 해결책이라고 생각하면 하나로 표시해 주시겠습니까? 지금은 문제가 해결되지 않은 것 같습니다. 그렇지 않은 경우 찾은 솔루션을 제공하거나 제공된 답변 중 하나를 문제에 대한 솔루션으로 표시하면 좋을 것입니다. :-)
Asbjørn Ulsberg 2011 년

1

문장이 자연스럽게 줄 바꿈을 일으키는 경우에만 텍스트가 정당화됩니다. 따라서 자연스럽게 줄 바꿈을하고 두 번째 줄의 내용을 숨기면됩니다.

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">&nbsp;</li>
</ul>

li.break 요소는 마지막 메뉴 항목과 같은 줄에 있어야하며 일부 콘텐츠 (이 경우에는 구분되지 않는 공백)를 포함해야합니다. 그렇지 않으면 일부 브라우저에서 같은 줄에 있지 않으면 작은 내용이 표시됩니다. 줄 끝에 여분의 공간이 있고 내용이 없으면 무시되고 줄이 정렬되지 않습니다.

IE7, IE8, IE9, Chrome, Firefox 4에서 테스트되었습니다.


0

가능한 자바 스크립트를 사용하는 경우 (이 스크립트는 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>

0

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;
}

라이브 예 .


-1

이것은 신중한 측정과 마지막 자식 선택기로 완벽하게 달성 할 수 있습니다.

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

4
텍스트는 모든 곳에서 동일하게 렌더링되지 않으며 픽셀이 꺼지면 메뉴가 깨집니다. 이것은 이미지와 같은 고정 너비 요소에서만 작동합니다.
fregante

-2

나는 HTML + CSS를 지정한 원래 질문을 알고 있지만 특별히 자바 스크립트 가 없다고 말하지 않았습니다 .)

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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.