22 декабря 2015
13 ноября 2009
26
Дивные дивы
Сперва, всем привет!
Это моя первая статья, так что посмотрим каким вкусным этот блин будет.
Так как я больше серверный программист, чем клиентщик, очень часто бывает ситуация, когда надо быстро сверстать страницу, и вот тут начинаются проблемы. Вроде все помнишь, но мысли разбредаются и в итоге тратишь много времени на воспоминания и вычитывание статей.
Как правило, все всегда есть и поиски завершаются успехом, но есть одно но. В основном вся информация на английском. И даже если знаешь язык нормально, все равно приходится напрягаться. Даже
Сегодня мы рассмотрим две темы:
- Как расположить несколько div’ов горизонтально так, чтобы они никуда не уплывали.
- Как сделать два горизонтально расположенных div’а одинаковой высоты.
Ничего нового я не скажу, это всего лишь перевод этой и вот этой статей с woorkup.com. Приступим.
Сразу скажу, что Антонио Лупетти делает в общем правильное дело — борется с IE6. Так что оба совета не для старого ослика. С другой стороны, даже столь неповоротливая организация-заказчик, на которую я работаю, и то инициализировала переход. Правда, пока только инициализировала...
Так же добавлю от себя, что обе эти проблемы можно решить с использованием списков <UL>, но это не совсем элегантно. Каждый инструмент лучше использовать по его непосредственному назначению.
Как расположить несколько div'ов в горизонтальной плоскости
Основная идея этого совета — использовать div-обертку (wrapper) и селектор CSS :first-child.
Итак, дано: сделать на странице несколько блоков, равномерно распределенных по горизонтали:
Исходный код такой разметки предельно прост:
<div id="wrapper">
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
</div>
Для того, чтобы горизонтально расположить блоки в оболочке, нам потребуется всего несколько строк CSS кода. Первое, что приходит в голову: объявить класс .section со свойствами width и margin-right, с нужными нам значениями. Но при этом правый отступ крайнего правого элемента будет выступать за границы оболочки:
Так как правый отступ крайнего правого элемента превышает ширину оболочки, по правилам разметки крайний правый блок «уйдет» вниз:
Возникает вопрос: как убрать «лишний» отступ у крайнего правого блока без специального CSS класса, у которого свойство margin-right будет задано 0?
Именно здесь и стоит вспомнить о селекторе :first-child, и инвертировать правые отступы на левые. Таким образом, чтобы у первого блока отступ слева был нулевым. Напрашивается вопрос: зачем инвертировать? Все дело в том, что в IE7|8 поддержка :first-child добавлена, а :last-child нет. Экономят?
Итак, давайте посмотрим на CSS код решения. Сперва определим оболочку:
#wrapper {
width:320px;
height:60px;
background:#EFEFEF;
}
Теперь объявим класс содержимого оболочки .section:
.section {
border:solid 1px #999;
float:left;
height:58px;
margin-left:10px;
width:98px;
}
В примере используются фиксированные значения свойств width и margin-left. Вы на свое усмотрение можете использовать и процентные отношения.
Теперь нам надо убрать отступ слева у первого блока, делается это так:
#wrapper div:first-child {
margin-left:0px;
}
Как уже было сказано выше, единственный недостаток этого подхода то, что IE6 не поддерживает селектор :first-child. В этом случае придется использовать условные комментарии для того, чтобы объявить-таки отдельный класс (например, .section-first). Свойства этого класса будут с теми же значениями, что в классе .section, только свойство margin-left = 0.
Как сделать несколько div'ов одинаковой высоты
В этом туториале Антонио предлагает реализацию фиктивных колонок, равных по высоте, с использованием CSS свойств position: absolute и border.
Представим, что у нас задача: надо реализовать разметку на две колонки так, чтобы высота боковой колонки была равна высоте основной. Иллюстрация такой задачи ниже:
Сначала опишем такую разметку:
<div id="wrapper">
<div id="maincontent">...</div>
<div id="sidebar">...</div>
</div>
Как и в предыдущем примере, у нас есть div-оболочка, в которой содержатся «подопытные» блоки.
CSS-код оболочки выглядит вот так:
#wrapper {
margin:0 auto;
width:600px; }
Рассмотрим теперь по-отдельности каждую из колонок.
Главная колонка
Главная колонка представлена id #maincontent. Она будет содержать основное содержимое страницы (например, посты). Иллюстрация показывает основную фишку этого туториала:
У колонки правая граница задана очень большой (border 200px). Эта граница и будет представлять собой место для вспомогательной колонки (#sidebar). Для этого задана фиктивная заливка фона #sidebar, которая будет иметь ту же высоту, что и основная. Описание стиля главной колонки ниже:
#maincontent {
border-right:solid 200px #DFDFDF;
position:absolute;
width:400px;
}
Вспомогательная колонка
Все, что нам осталось, описать #sidebar:
#sidebar {
background:#DFDFDF;
margin-left:400px;
position:absolute;
width:200px;
}
Ширина вспомогательной колонки должна быть такой же, как ширина границы основной колонки (200px), а левый отступ margin-left должен быть равен ширине содержимого #maincontent.
Вот что получается в результате:
Недостатки этого способа
Везде и во всем есть недостатки, этот способ верстки не исключение. Во-первых, ширина колонок должна быть фиксированной. Во-вторых, фон у них должен быть одинаковый. И в-третьих, вспомогательная колонка всегда должна быть по высоте меньше, чем основная.
В комментариях к статье было предложено решение. Оно не очень элегантное, но решает свои задачи:
#wrapper{
overflow: hidden;
margin:0 auto;
width:600px;
}
#maincontent, #sidebar{
float: left;
padding-bottom: 9999px;
margin-bottom: -9999px;
}
#maincontent{
background:#ccc;
width:400px;
}
#sidebar{
background:#DFDFDF;
width:200px;
}
Ну и, в качестве последней приманки (или десерта): приз!
Статья переводная, так что все труды ушли на приз. =)
если не сложно, дай мне ссылку на это решение. Или (что будет еще лучше), напиши его в комментарии. Хотя бы просто скинь css.
Насчет второго так и есть -- симуляция. Есть много других способов, так что это один из. В оригинальной статье множество комментариев по этому поводу, но все способы так или иначе вырывают блоки из контекста и/или используют горы костылей.
Плюс, конечно, для этих целей можно использовать js. И в jquery, и в mootools есть решения.
Например, для фотогалерей я обычно использую следующую разметку:
С такими вот, например, стилями
спасибо! Я это и имел в виду, когда писал, что расположить горизонтально можно с помощью списка. Это подходит для атомарных элементов (картинок, пунктов меню). Но верстать, например, меню (целиком) и блок с постами в блоге с помощью списков... не то.
ujifgc,
спасибо! Больше мнений, хороших и разных! =)
1) sidebar должен быть строго меньше по высоте, чем maincontent
2) невозможность задать для sidebar фон, отличный от сплошной заливки (например, фоновая картинка). Сюда же относим все остальные проблемы, связанные с тем, что sidebar реально имеет не ту же саму высоту, как maincontent: потребность в своем бордере, наличие блоков, которые могут позиционироваться относительно sidebar и т.п.
Самое лучшее решение, которое существует, предложил Чикуенок:
http://chikuyonok.ru/2009/06/float-columns/
Хотя и у него есть ограничения, например, фиксированная ширина колонок.
Но было бы еще лучше ссылки на реальные примеры того, что вы проделали.
... "вот что у нас получилось _ссылка_".
спасибо, я это учту в будущем. Здесь сделал, как было в оригинале.
1. задаю отступ блокам не справа а слева
2. для того чтобы погасить отступ первых блоков в строках, блоку-обертке задаю отрицательный левый отступ равный величине отступа у блоков
Есть что почерпнуть новенького. За информацию спасибо. Статья получилась.
Насчет выравнивания колонок - я обычно пускаю фон - в принципе самый кроссбраузерно оптимальный вариант.
Получилось все отлично - http://manualov.net/Acura-manuals.php