[Мета-примечание:] Я просматривал страницу с вопросами и очень устал от "DIVS vs Tables" "Когда использовать таблицы vs DIVS" "Divs лучше, чем Tables", "Tables vs CSS" и все вопросы, которые задают ТО ЖЕ ВЕЩЬ OMG ЛЮДИ, но Я хотел бы увидеть, как люди справляются с переводом канонического примера «почему вам следует отказаться и использовать таблицы»:
<table>
<tr>
<td> Name </td>
<td> <input> </td>
</tr>
<tr>
<td> Social Security Number </td>
<td> <input> </td>
</tr>
</table>
Вопрос: Как лучше всего (семантически, просто, надежно, плавно, переносимо) реализовать описанное выше без таблиц. Во-первых, я предполагаю, что в наивной реализации для первого столбца используется фиксированная ширина столбца, но это может иметь сомнительные результаты для динамически сгенерированного контента. Было бы неплохо включить в ответ сильные и слабые стороны вашего подхода.
P.S. Еще одна вещь, о которой я много думаю, - это вертикальное центрирование, но хак для этого довольно хорошо описан в jakpsatweb.cz
Обновлено: scunlife показывает хороший пример того, почему я не продумал проблему так тщательно. Таблицы могут выровнять несколько столбцов одновременно. Вопрос все еще остается в силе (я бы хотел увидеть разные методы CSS, используемые для выравнивания / макета) - хотя решения, которые могут справиться с его? более сложный пример определенно предпочтительнее.






Что я обычно делаю:
<form>
<label for = "param_1">Param 1</label>
<input id = "param_1" name = "param_1"><br />
<label for = "param_2">Param 2</label>
<input id = "param_2" name = "param_2"><br />
</form>
и в CSS:
label,input { display: block; float: left; margin-bottom: 1ex; }
input { width: 20em; }
label { text-align: right; width: 15em; padding-right: 2em; }
br { clear: left; }
Конечно, вам придется определять ширину в соответствии с вашими фактическими данными :-)
display: block, чтобы ему можно было назначить размер и выровнять его.float: left, потому что Explorer работает немного по-другому.br так, чтобы где-то был clear: left, и я помню, что размещение его на этикетке не сработало в некоторых браузерах.Кроме того, с br вы получите хорошее форматирование, даже если браузер не поддерживает CSS :-)
Что ж, если вам нужна динамическая ширина столбца, вы должны сделать свои поля наоборот, то есть все метки и все входы, и там вы наверняка потеряете горизонтальное выравнивание :-)
предположим, вы используете 'white-space: nowrap' и заданную высоту строки? могло бы тебе сойти с рук?
Ой, подождите, да, тогда вы потеряете вертикальную плавность. Хм.
ну, вам может сойти с рук почти все :-) Проблема здесь будет в том, что, гм, у вас нет возможности узнать 1) правильную высоту строки, 2) если какой-то браузер не подумает о том, чтобы отображать это по-другому, и 3) что он будет делать без CSS, поскольку это нарушит «нормальный» поток документа.
запретить тегу br. с этим макетом вы могли бы просто сказать ярлык {clear: left}
Поддерживаю Стива. Также не забывайте fieldsets, поскольку они чрезвычайно полезны для сложных, но содержательных макетов.
@StevePerks, как я уже сказал, br есть в случае, если браузер не поддерживает css, например текстовый браузер.
@mat - я согласен с обоснованием использования <code> <br> </code>, но его использование в этом месте по-прежнему носит презентационный, а не структурный характер. Если каждая пара / группировка находится в контейнере уровня блока, включение <code> <br> </code> не требуется.
Я думал о чем-то вроде:
<div style = "text-align:right; float:left;">
Name: <input /> <br />
Social Security Number: <input /> <br />
</div>
который, если правый столбец имеет фиксированную длину, выравнивает ОК с переменной длиной текста, но мне интересно, каковы недостатки этого метода?
Уловка заключается в том, что когда форма становится более сложной, чем в вашем примере, вы понимаете, что таблицы обеспечивают «гибкую сетку», чего не делают никакие другие элементы.
например что, если «ввод» сложнее текстового поля? например куча переключателей, каждая со своим ярлыком:
Color: [____Red___][v]
Hood: [*]
Size: (_) Small
(_) Medium
(_) Large
(*) X-Large
Если все, что вам нужно, это простые формы, CSS - это здорово, но как только вам понадобится сетка, все станет интересно ...
Если вы действительно хотите это сделать, я бы посмотрел Решение Человека в синем, он работает очень хорошо и очень чистый.
Для этого вы можете использовать набор полей или комбинацию dd / dt / dd.
Люди говорят о таблицах, которые заставляют свои формы отображаться так, как они хотят, это правда, ТОЛЬКО если вы хотите отображать свои формы в столбцах и готовы потерять семантическое значение. Имея следующий HTML-код, можно отображать эту форму в любом количестве макетов.
Кстати - нет <br />
<form>
<fieldset>
<legend>Personal Info</fieldset>
<div>
<label for = "name">Name</label>
<input id = "name" name = "name" />
</div>
<div>
<label for = "ssn">Social Security Number</label>
<input id = "ssn" name = "ssn" />
</div>
</fieldset>
</form>
Вы можете очистить <divs> или установить их на overflow: hidden, чтобы убедиться, что поплавки очищены.
Варианты из приведенного выше html:
Name |==============| SSN |==============|
Name |==============|
SSN |==============|
Name |==============|
SSN |==============|
Name |==============|
SSN |==============|
Name: |==============|
SSN: |==============|
Name:
|==============|
SSN:
|==============|
Все вышеперечисленное можно выполнить с помощью всего нескольких строк CSS.
Когда дело доходит до радио, флажков и кнопок отправки, все становится немного сложнее, но чистый семантический HTML МОЖЕТ отображаться так, как вы хотите, с помощью css.
Как бы вы добавили ':' через CSS?
Не везде поддерживается, но псевдоэлемент: after сделает это. Это действительно хорошо сочетается с семантическим HTML, поскольку программа чтения с экрана не должна его читать.
извините, если быть более точным: label: after {content: ":"}
Попался; Я не знал, что вы можете изменить контент с помощью стиля
Хотя другие предложения, вероятно, лучше подходят для получения гибкого макета, буквальный ответ на вопрос будет примерно таким:
<form action = "www.example.com"> <div class = "table"> <div class = "tbody"> <div class = "tr"> <div class = "td"> <label for = "name">Name</label> </div> <div class = "td"> <input id = "name"> </div> </div> <div class = "tr"> <div class = "td"> <label for = "ssn">Social Security Number</label> </div> <div class = "td"> <input id = "ssn"> </div> </div> </div> </div> </form>
с
<style type = "text/css"> div.table { display:table; border-spacing:2px; } div.tbody { display:table-row-group; } div.tr { display:table-row; } div.td { display:table-cell; vertical-align: middle; padding:1px; } </style>
Это работает с последними версиями Firefox, Chrome, Opera и Safari. Он также работает с IE8 Beta 2 (стандартный режим). Он не работает с IE7 или более ранними версиями, кроме «прогрессивного улучшения» и всего такого.
Жаль, что rowspan и colspan не работают (я только что пробовал в Firefox 3.0.6)
Я согласен, что это решение, я просто не понимаю, зачем кому-то это делать. Единственное отличие состоит в том, что вы по существу используете классы для связывания ваших css и html вместо типа html (т.е. вы используете class = "table" вместо form.table {} в css). В настоящее время я начинаю рефакторинг кода из 50 тыс. Строк, и большинство моих диалоговых форм (40+) используют таблицу для выравнивания входных данных, меток и специальных элементов управления; эта таблица обычно находится внутри div. Я отчаянно пытаюсь определить, почему мне следует перейти на этот метод ... но, увы, я не успеваю.
@gunslingor - Ты бы не стал, по крайней мере, не совсем так. Имена классов, в частности, выбраны для демонстрации принципа макета, тогда как в производственном коде вы должны использовать имена классов, которые описывают контент, а не макет. Дело в том, что иногда вам нужен макет столбцов и строк, но у вас семантически нет табличных данных. Таблицы CSS предоставляют средства для этого. Более того, понимание таблиц CSS и, в частности, того, как создаются объекты анонимных таблиц, приводит к некоторым очень удобным эффектам компоновки с очень небольшой разметкой.
Это действительно то, о чем я подумал в первую очередь, это довольно чисто и понятно. Я надеялся, что появятся другие решения, которые позволят использовать динамическую ширину столбца для левого столбца.