표를 사용하지 않고이 HTML 레이아웃을 할 수 있습니까?


102

좋아요, 1 ~ 2 주 전에 간단한 레이아웃 문제가있었습니다. 즉, 페이지의 섹션에는 헤더가 필요합니다.

+---------------------------------------------------------+
| Title                                            Button |
+---------------------------------------------------------+

아주 간단한 것. 웹 세계에서 테이블 혐오가 점령 된 것 같습니다. 테이블 대신 HTML 양식에 정의 목록 (DL, DD, DT) 태그를 사용하는 이유를 물었을 때 생각 나게되었습니다 . 이제 테이블 대 div / CSS의 일반적인 주제는 이전에 논의되었습니다. 예 :

따라서 이것은 CSS와 레이아웃 테이블에 대한 일반적인 논의가 아닙니다. 이것은 단순히 한 가지 문제에 대한 해결책입니다. CSS를 사용하여 위의 다양한 솔루션을 시도했습니다.

  • 버튼 또는 버튼이 포함 된 div에 대해 오른쪽으로 플로팅합니다.
  • 버튼의 상대적 위치. 과
  • 상대 + 절대 위치.

이러한 솔루션 중 어느 것도 다른 이유로 만족스럽지 않았습니다. 예를 들어 상대적 위치로 인해 내 드롭 다운 메뉴가 콘텐츠 아래에 나타나는 Z- 색인 문제가 발생했습니다.

그래서 결국 다음으로 돌아 가게되었습니다.

<style type="text/css">
.group-header { background-color: yellow; width: 100%; }
.group-header td { padding: 8px; }
.group-title { text-align: left; font-weight: bold; }
.group-buttons { text-align: right; }
</style>
<table class="group-header">
<tr>
  <td class="group-title">Title</td>
  <td class="group-buttons"><input type="button" name="Button"></td>
</tr>
</table>

그리고 완벽하게 작동합니다. 그것은 간단하고 역 호환이 가능하며 (IE5에서도 작동 할 것입니다) 그냥 작동합니다. 포지셔닝이나 플로트를 망칠 필요가 없습니다.

그래서 누구든지 테이블없이 동등한 것을 할 수 있습니까?

요구 사항은 다음과 같습니다.

  • 역 호환성 : FF2 및 IE6;
  • 합리적인 일관성 : 여러 브라우저에서;
  • 수직 중앙 : 버튼과 제목의 높이가 다릅니다. 과
  • 유연성 : 위치 (패딩 및 / 또는 여백) 및 스타일을 합리적으로 정밀하게 제어 할 수 있습니다.

참고로 오늘 몇 가지 흥미로운 기사를 보았습니다.

편집 : 플로트 문제에 대해 자세히 설명하겠습니다. 이런 종류의 작품 :

<html>
  <head>
    <title>Layout</title>
    <style type="text/css">
      .group-header, .group-content { width: 500px; margin: 0 auto; }
      .group-header { border: 1px solid red; background: yellow; overflow: hidden; }
      .group-content { border: 1px solid black; background: #DDD; }
      .group-title { float: left; padding: 8px; }
      .group-buttons { float: right; padding: 8px; }
    </style>
  </head>
  <body>
    <div class="group-header">
      <div class="group-title">This is my title</div>
      <div class="group-buttons"><input type="button" value="Collapse"></div>
    </div>
    <div class="group-content">
      <p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
      <p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
      <p>On a side note, I came across a couple of interesting articles today:</p>
    </div>
  </body>
</html>

파트에 대한 Ant P 덕분에 overflow: hidden(그래도 이유는 모르겠습니다). 여기에서 문제가 발생합니다. 제목과 버튼을 세로 중앙에 배치하고 싶다고 가정 해 보겠습니다. 요소의 높이가 다르기 때문에 문제가됩니다. 이것을 다음과 비교하십시오.

<html>
  <head>
    <title>Layout</title>
    <style type="text/css">
      .group-header, .group-content { width: 500px; margin: 0 auto; }
      .group-header { border: 1px solid red; background: yellow; overflow: hidden; }
      .group-content { border: 1px solid black; background: #DDD; }
      .group-header td { vertical-align: middle; }
      .group-title { padding: 8px; }
      .group-buttons { text-align: right; }
    </style>
  </head>
  <body>
    <table class="group-header">
    <tr>
      <td class="group-title">This is my title</td>
      <td class="group-buttons"><input type="button" value="Collapse"></td>
    </tr>
    </table>
    <div class="group-content">
      <p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
      <p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
      <p>On a side note, I came across a couple of interesting articles today:</p>
    </div>
  </body>
</html>

완벽하게 작동합니다.


11
알겠습니다. "vim에 어떤 색상을 사용해야하나요?" 내 특정 CSS 레이아웃 문제가 찬성됩니다.
cletus


어떤 경우에도 테이블없이 원하는 것을 할 수 있습니다. 도대체 왜 @SamB가이 2 년 된 질문에 부딪 혔습니까? DOH +
dynamic

3
@ yes123 : 음, 구문 강조 표시가 잘못되었습니다 ...
SamB

답변:


50

작업을 빠르고 정확하게 수행하기 위해 사용할 수있는 도구를 사용하는 데 아무런 문제가 없습니다.

이 경우 테이블이 완벽하게 작동했습니다.

나는 개인적으로 이것을 위해 테이블을 사용했을 것입니다.

중첩 된 테이블은 피해야한다고 생각합니다.


21
표 형식 데이터가 아닌 프리젠 테이션 레이아웃을 위해 표를 사용하는 경우를 제외하고는 처음에는 더 쉽기 때문에 어둡고 위험한 경로로 향하게됩니다.
One Crayon

9
Amazon조차도 특정 경우에 테이블을 사용합니다. 그리고 stackoverflow.com도 그렇습니다. 실제로 잘 작동하는 CSS 솔루션을 모두 좋아합니다.
Nosredna

11
아마존도 아니고 이제 stackoverflow는 웹 디자인의 정점입니다.
Bobby Jack

31
그렇지 않을 수도 있지만 수만 명의 사용자에게 서비스를 제공하는 작업 솔루션입니다.
17 of 26

22
이 반 테이블 밈은 평범한 어리석은 멍청한 것입니다. 유연한 제약 기반 레이아웃을위한 유일한 2 차원 레이아웃 관리자는 테이블입니다. 그리고 그것이 하나의 복잡한 것 (수많은 col / rowspans 포함)이든 중첩 된 것들이든 별 차이가 없습니다. 그러나 현실과 사실이 항상 열광에 대한 충분한 무기는 아닌 것 같습니다.
StaxMan

28

왼쪽과 오른쪽으로 떠서 둘 다 지우도록 설정하면 완료됩니다. 테이블이 필요 없습니다.

편집 : 나는 이것에 대해 많은 찬성표를 받았음을 알고 있으며 내가 옳다고 믿었습니다. 그러나 단순히 테이블이 필요한 경우가 있습니다. , 여기에 자신을 당신은 CSS로 모든 일을 시도 할 수 있으며 최신 브라우저에서 작동하지만 나이가 사람을 지원하는 경우는 ... 아니 반복 관련 스택 오버플로 스레드내 블로그에 호언 장담을 .

Edit2 : 이전 브라우저는 더 이상 흥미롭지 않기 때문에 새 프로젝트에 Twitter 부트 스트랩을 사용하고 있습니다. 대부분의 레이아웃 요구 사항에 적합하며 CSS를 사용합니다.


2
수직 센터링을 처리하지 않으므로 -1.
SamB 2011-06-13

1
왼쪽에 로고가 있고 오른쪽에 일부 텍스트 메뉴가있는 비슷한 문제가 발생했습니다. 메뉴는 로고의 기준선에 정렬되어야했습니다. 메뉴에 대한 float : right 사용이 작동하지 않았습니다. 오른쪽 상단으로 보냈고 더 이상 로고의 기준선과 수직으로 정렬되지 않았습니다.
Jean-François Beauchamp 2011

1
Title의 line-height를 Button의 높이와 동일하게 설정하면 vertical centering을 해결할 수 있다고 생각합니다.
igors

1
@igors, +1, 맞아요. 이 질문은 2009 년에서 있음을 유의)
밀라노 Babuškov에게

17

이것은 일종의 속임수 질문입니다.

제목과 버튼을 세로 중앙에 배치하고 싶다고 가정 해 보겠습니다.

예, CSS에서는 세로 중심화가 어렵다는 기록을 남기고 싶습니다. 사람들이 게시물을 올릴 때 "CSS에서 X를 할 수 있습니까?"라는 끝없는 것처럼 보일 때 대답은 거의 항상 "예"이며 그들의 징징 거리는 것은 정당하지 않은 것처럼 보입니다. 이 경우, 예, 그 한 가지는 어렵습니다.

누군가는 전체 질문을 "CSS에서 수직 중심에 문제가 있습니까?"로 편집해야합니다.


11
그것은 "table haters"주장에 대한 일종의 내 문제입니다. CSS는 테이블이 할 수있는 모든 것을 할 수 있습니다 ... 꽤 간단하고 일반적이며 합리적인 경우를 제외하고 (수직 센터링과 같은). CSS는 선거 약속이 잘못된 것 같습니다.
cletus

4
내 요점은 수직 센터링이 정말 어려운 유일한 일이라는 것입니다.
AmbroseChapel

3
CSS는 테이블을 대체하기위한 것이 아닙니다. 표 없이도 대부분의 일반적인 레이아웃 문제를 해결할 수 있도록하기위한 것입니다. 테이블이 작동하면 썰매 망치 대신 펜을 사용하여 그리는 것처럼 테이블을 사용하십시오.
Aaron Digulla

16

왼쪽에 떠있는 제목, 오른쪽에 떠있는 버튼, (여기에 내가 최근까지 알지 못했던 부분이 있습니다)-둘 다의 컨테이너를 만드십시오 {overflow:hidden}.

어쨌든 Z- 색인 문제를 피해야합니다. 작동하지 않고 IE5 지원 이 정말로 필요한 경우 계속해서 표를 사용하십시오.


+1 워, 오버플로가 숨겨져있는 것은 무엇입니까? 그것은 차이를 만듭니다. 왜 그런지 모르겠다.
cletus

솔직히 말해서 나도 이해하지 못하고 사양에서 언급을 찾을 수 없습니다. 누군가는 그것이 "올바른"방법이라고 말했고, 내가 그것을하기 위해 클리어 된 요소를 사용한다는 다른 질문에 대답 한 후에. 나에게는 좋은 생각 인 것 같습니다.

플로팅 된 요소는 다음 콘텐츠가 제대로 흐르기 위해 여전히 지워야합니다. 오버플로 : 숨김; 컨테이너의 높이 만 다룹니다.
Zack The Human

2
"overflow : hidden"은 높이 '확장'과 클리어링을 모두 달성하기위한 해킹입니다. 다음 요소는 해당 상자를 지울 것입니다 (적어도 사양의 해당 부분을 올바르게 구현하는 브라우저에서).
Bobby Jack

1
-1 수직 중심 취급하지만 용 +2하지 않는 overflow:hidden.
SamB 2011-06-13

7

순수한 CSS에서는 언젠가는 "display:table-cell". 불행히도 현재 A 등급 브라우저에서는 작동하지 않으므로 어쨌든 동일한 결과를 얻으려면 테이블을 사용하는 것이 좋습니다. 적어도 과거까지 충분히 작동한다는 것을 확신 할 수 있습니다.

솔직히 더 쉬운 경우 테이블을 사용하십시오. 아프지 않을 것입니다.

테이블 요소의 의미와 접근성이 정말로 중요하다면 테이블을 의미없는 것으로 만들기위한 작업 초안이 있습니다.

http://www.w3.org/TR/wai-aria/#presentation

나는 이것이 XHTML 1.1을 넘어서는 특별한 DTD가 필요하다고 생각하는데, 이것은 전체 text/htmlapplication/xml논쟁을 불러 일으킬 것이므로 거기에 가지 말자.

따라서 해결되지 않은 CSS 문제에 대해 ...

중앙에 두 요소를 수직으로 정렬하려면 약간 둔한 CSS 해커를 사용하여 몇 가지 다른 방법으로 수행 할 수 있습니다.

다음 제약 조건에 맞출 수 있다면 비교적 간단한 방법이 있습니다.

  • 두 요소의 높이는 고정되어 있습니다.
  • 컨테이너의 높이는 고정되어 있습니다.
  • 요소는 겹치지 않을만큼 좁습니다 (또는 고정 너비로 ​​설정 될 수 있음).

그런 다음 음수 여백으로 절대 위치 지정을 사용할 수 있습니다.

.group-header { height: 50px; position: relative; }
.group-title, .group-buttons { position: absolute; top: 50%; }
# Assuming the height of .group-title is a known 34px
.group-title { left: 0; margin-top: -17px; }
# Assuming the height of .group-buttons is a known 38px
.group-buttons { right: 0; margin-top: -19px; }

그러나 이것은 대부분의 상황에서 무의미합니다. 이미 요소의 높이를 알고 있다면 플로트를 사용하고 필요에 따라 충분한 여백을 추가하여 배치 할 수 있습니다.

다음은 텍스트 기준선을 사용하여 두 열을 인라인 블록으로 세로로 정렬하는 또 다른 방법입니다. 여기서 단점은 열이 왼쪽 가장자리에서 너비를 채우려면 고정 너비를 설정해야한다는 것입니다. 요소를 텍스트 기준선에 고정해야하므로 두 번째 열에 float : right를 사용할 수 없습니다. (대신에, 우리는 그것을 밀어 낼만큼 충분히 넓게 첫 번째 열을 만들어야합니다.)

<html>
  <head>
    <title>Layout</title>
    <style type="text/css">
      .group-header, .group-content { width: 500px; margin: 0 auto; }
      .group-header { border: 1px solid red; background: yellow; }
      .valign { display: inline-block; vertical-align: middle; }
      .group-content { border: 1px solid black; background: #DDD; }
      .group-title { padding: 8px; width: 384px; }
      .group-buttons { padding: 8px; width: 84px; text-align: right; }
    </style>
    <!--[if lt IE 8]>
    <style type="text/css">
      .valign { display: inline; margin-top: -2px; padding-top: 1px; }
    </style>
    <![endif]-->
  </head>
  <body>
    <div class="group-header">
      <div class="valign">
        <div class="group-title">This is my title.</div>
      </div><!-- avoid whitespace between these! --><div class="valign">
        <div class="group-buttons"><input type="button" value="Collapse"></div>
      </div>
    </div>
    <div class="group-content">
      <p>And it works perfectly, but mind the hacks.</p>
    </div>
  </body>
</html>

HTML : 각 열 주위에 .valign 래퍼를 추가합니다. (당신이 더 행복 해지면 그들에게 더 "의미있는"이름을 부여하십시오.) 이것들은 사이에 공백없이 유지되어야합니다. 그렇지 않으면 텍스트 공간이 그것들을 밀어 내게됩니다. (나는 그것이 끔찍하다는 것을 알고 있지만 마크 업을 "순수"하고 프리젠 테이션 레이어에서 분리하면 얻는 것입니다 ... 하!)

CSS :vertical-align:middle 그룹 헤더 요소의 텍스트 기준선에 블록을 정렬하는 데 사용 합니다. 각 블록의 다른 높이는 수직으로 중앙에 유지되고 컨테이너의 높이를 밀어냅니다. 요소의 너비는 너비에 맞게 계산되어야합니다. 여기에서는 가로 패딩을 뺀 400과 100입니다.

IE 수정 사항 : Internet Explorer는 기본 인라인 요소 (예 : div가 아닌 span)에 대해서만 인라인 블록을 표시합니다. 그러나 div에 hasLayout을 제공하고 인라인으로 표시하면 인라인 블록처럼 작동합니다. 여백 조정은 상단의 1px 간격을 수정하는 것입니다 (보려면 .group-title에 배경색을 추가해보세요).


1
흠 디스플레이 : table-X 태그는 테이블 태그를 사용하지 않고 테이블을 사용하여 레이아웃을 수행하는 목적을 가지고있는 것 같습니다.
Danubian Sailor 2013 년

3

이 경우에는 테이블 형식 데이터가 아니므로 테이블을 사용하지 않는 것이 좋습니다. 버튼이 맨 오른쪽에있는 것은 순전히 표현적인 것입니다. 다음은 테이블 구조를 복제하기 위해 수행하는 작업입니다 (사이트 계층 구조에 맞게 다른 H #으로 변경).

<style>
  .group-header { background: yellow; zoom: 1; padding: 8px; }
  .group-header:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
  /* set width appropriately to allow room for button */
  .group-header h3 { float: left; width: 300px; }
  /* set line-height or margins to align with h3 baseline or middle */
  .group-header input { float: right; }
</style>

<div class="group-header">
  <h3>This is my title</h3>
  <input type="button" value="Collapse"/>
</div>

중간에 진정한 수직 정렬을 원하면 (즉, 텍스트가 단추를 감싸는 경우 두 텍스트 줄에 대해 여전히 가운데 정렬되어 있음) 표를 작성하거나 position: absolute여백을 사용 하여 작업해야합니다 . 당신은 추가 할 수 있습니다position: relative 그것은 그에게 오는 경우, Z- 인덱스로 위를 범프 수 있도록 버튼과 같은 순서 수준으로 끌어하기 위해 귀하의 드롭 다운 메뉴 (또는 가능성이 부모)에.

width: 100%블록 수준 요소이기 때문에 div에 필요하지 않으며 zoom: 1IE에서 clearfix가있는 것처럼 div가 동작하도록합니다 (다른 브라우저가 실제 clearfix를 선택 함). 좀 더 구체적으로 대상을 지정하는 경우 이러한 모든 외부 클래스가 필요하지는 않지만 위치 지정을 더 쉽게하기 위해 단추에 래퍼 div 또는 범위가 필요할 수 있습니다.


귀하의 솔루션은 : after 의사 클래스 때문에 IE6에서 작동하지 않습니다.
Sebastian Hoitz

1
in 덕분에 IE 6에서 작동합니다. zoom: 1in .group-header으로 인해 hasLayout이 트리거되고 IE 6이 : after 요소가 활성화 된 것처럼 동일하게 작동합니다.
One Crayon

2

div에서 이중 부동을 수행하고 clearfix를 사용하십시오. http://www.webtoolkit.info/css-clearfix.html 패딩 / 여백 제한이 있습니까?

<div class="clearfix">
   <div style="float:left">Title</div>
   <input type="button" value="Button" style="float:right" />
</div>

수직 센터링 요구 사항 (그리고 약간의 추가 패딩)이 있습니다. 나는 당신이 게시 한 후에 그것을 명확히했다고 생각합니다.
cletus

2
<div class="group-header">
    <input type="button" name="Button" value="Button" style="float:right" />
    <span>Title</span>
</div>

1

Flexbox를 사용하기로 결정했습니다. 작업이 훨씬 쉬워 졌기 때문입니다.

기본적으로 정렬하고 추가하려는 자식의 부모로 이동해야합니다 display:box(물론 접두사가 붙음). 양쪽에 앉게하려면 justify-content를 사용하세요. 하세요. 이 경우 (링크 참조)와 같이 끝에 정렬해야하는 요소가있을 때 사이의 간격은 올바른 것입니다.

그런 다음 수직 정렬 문제입니다. 두 요소의 부모를 만들었으므로 Flexbox를 정렬하려고합니다. 이제 사용하기 쉽습니다.align-items: center .

그런 다음 이전에 원하는 스타일을 추가하고 제목에서 플로트를 제거하고 헤더의 버튼을 추가하고 패딩을 추가했습니다.

.group-header, .group-content {
    width: 500px;
    margin: 0 auto;
}
.group-header{
    border: 1px solid red;
    background: yellow;
    overflow: hidden;
    display: -webkit-box;
    display: -moz-box;
    display: box;
    display: -webkit-flex;
    display: -moz-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-justify-content: space-between;
    -moz-justify-content: space-between;
    -ms-justify-content: space-between;
    -o-justify-content: space-between;
    justify-content: space-between;
    webkit-align-items: center;
    -moz-align-items: center;
    -ms-align-items: center;
    -o-align-items: center;
    align-items: center;
    padding: 8px 0;
}
.group-content{
    border: 1px solid black;
    background: #DDD;
}
.group-title {
    padding-left: 8px;
}
.group-buttons {
    padding-right: 8px
}

데모보기


1

나는 테이블이 로딩이 끝날 때까지 표시되지 않는 간단한 이유 때문에 테이블 형식 데이터에만 테이블을 사용해야한다는 데 동의합니다 (아무리 빠르더라도 CSS 방법보다 느립니다). 그러나 이것이 가장 간단하고 우아한 해결책이라고 생각합니다.

<html>
    <head>
        <title>stack header</title>
        <style type="text/css">
            #stackheader {
                background-color: #666;
                color: #FFF;
                width: 410px;
                height: 50px;
            }
            #title {
                color: #FFF;
                float: left;
                padding: 15px 0 0 15px;
            }
            #button {
                color: #FFF;
                float: right;
                padding: 15px 15px 0 0;
            }
        </style>
    </head>

    <body>
        <div id="stackheader">
        <div id="title">Title</div>
        <div id="button">Button</div>
        </div>
    </body>
</html>

버튼 기능과 추가 세부 사항은이 기본 양식에서 스타일을 지정할 수 있습니다. 잘못된 태그에 대해 사과드립니다.

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