HTML / CSS: создание двух плавающих div одинаковой высоты


106

У меня есть небольшая специфическая проблема, которую я сейчас решаю с помощью a table, см. Ниже. По сути, я хочу, чтобы два блока занимали 100% доступной ширины, но занимали ровно столько места по вертикали, сколько необходимо (что на самом деле не так очевидно на картинке). Эти двое должны всегда иметь одинаковую высоту с небольшой линией между ними, как показано.

альтернативный текст
(источник: pici.se )

Все это очень легко сделать table, и я этим занимаюсь сейчас. Однако я не слишком заинтересован в решении, поскольку семантически это не таблица.


2
Э ... где картинка? Я знаю, что слишком поздно комментировать это
Аджай Кулкарни

Вот ссылка на изображение с WebArchive.org https://web.archive.org/web/20120617031534/http://pici.se/pictures/qJRMtoLPv.png
DidThis

Ответы:


160

Вы можете получить столбцы с одинаковой высотой в CSS, применив нижнее заполнение большого размера, нижнее отрицательное поле такого же размера и окружив столбцы блоком div со скрытым переполнением. Вертикальное центрирование текста немного сложнее, но это должно вам помочь.

#container {
  overflow: hidden;
      width: 100%;
}
#left-col {
  float: left;
  width: 50%;
  background-color: orange;
  padding-bottom: 500em;
  margin-bottom: -500em;
}
#right-col {
  float: left;
  width: 50%;
  margin-right: -1px; /* Thank you IE */
  border-left: 1px solid black;
  background-color: red;
  padding-bottom: 500em;
  margin-bottom: -500em;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head></head>

<body>
  <div id="container">
    <div id="left-col">
      <p>Test content</p>
      <p>longer</p>
    </div>
    <div id="right-col">
      <p>Test content</p>
    </div>
  </div>
</body>

Я думаю стоит упомянуть что предыдущий ответ streetpc имеет недопустимый html, тип документа - XHTML, а атрибуты заключены в одинарные кавычки. Также стоит отметить, чтовам не нужен дополнительный элемент с clearon, чтобы очистить внутренние поплавки контейнера. Если вы используете скрытое переполнение, это очищает поплавки во всех браузерах, отличных от IE, а затем просто добавляя что-то, чтобы дать hasLayout, например width или zoom: 1, IE очистит свои внутренние поплавки.

Я тестировал это во всех современных браузерах FF3 + Opera9 + Chrome Safari 3+ и IE6 / 7/8. Это может показаться уродливым трюком, но он работает хорошо, и я часто использую его в продакшене.

Надеюсь, это поможет.


1
Код, который я дал, проверяется на валидаторе W3C (ну, как только вы добавите элемент <title>, а это не ваша точка зрения). Более того, спецификации позволяют использовать одинарные кавычки согласно этому обсуждению: sitepoint.com/forums/showthread.php?t=54273#6
instanceof me

1
Извините, моя ошибка. Я изменил свой ответ выше. Однако обратите внимание на то, что с помощью вашего метода, если правый столбец становится больше, чем левый, под ним просвечивает красный цвет, так как два поля не совсем правильной высоты. В зависимости от дизайна я бы выбрал либо искусственные столбцы, либо этот метод с нижними полями и отступами.
Натали Даун

2
На самом деле, хотя решение, данное Кевином К. об отсекаемых тенях, работает для верхнего, левого и правого отступов, оно не работает для нижнего. Пока не нашел решения.
JeanMertz 03

1
Отличная работа, Натали. @laarsk Непредсказуемая высота - это как раз то, для чего это нужно, не так ли? См. Демонстрацию: jsfiddle.net/RT3MT/4 переместите «более длинные» абзацы вокруг, чтобы увидеть
jpillora

1
Это один из самых уродливых хаков CSS, который я когда-либо видел, но я собираюсь принять его с распростертыми объятиями, лол. Кажется, это единственный путь вперед
Мэтт Вукас

98

Сейчас 2012 + n, поэтому, если вам больше не нужен IE6 / 7 display:table, display:table-rowи вы display:table-cellработаете во всех современных браузерах:

http://www.456bereastreet.com/archive/200405/equal_height_boxes_with_css/

Обновление 2016-06-17: Если вы думаете, что время пришло display:flex, попробуйте Flexbox Froggy .


30
В каком году будет заменен этот ответ на display: flex?
LandonSchropp

12
Нет, мы сейчас в 2014 году (;
Francisco Presencia

9
ааааааи это 2015 год, может быть, к концу года мы сможем изменить ответ на display: flex :)
MetalWeirdo

5
Я все еще живу в 1950-х.
Джей

1
Привет с 2016 года! Теперь мы можем использовать гибкость
Бретт Грегсон

20

Для этого вам следует использовать flexbox. Он не поддерживается в IE8 и IE9 и только с префиксом -ms в IE10, но все другие браузеры его поддерживают. Для префиксов поставщиков вы также должны использовать autoprefixer .

.parent {
    display: flex;
    flex-wrap: wrap; // allow wrapping items
}

.child {
    flex-grow: 1;
    flex-basis: 50%; // 50% for two in a row, 33% three in a row etc.
}

1
У меня проблема с гибкостью в том, что ему нужна оболочка вокруг столбцов. С помощью техники floats + display: table я могу иметь, например, заголовок и кучу столбцов, и эффект работает с столбцами, не затрагивая заголовок.
Stijn de Witt

10

вы можете заставить это работать с js:

<script>
    $(document).ready(function() {
        var height = Math.max($("#left").height(), $("#right").height());
        $("#left").height(height);
        $("#right").height(height);
    });
</script>

1
Обратите внимание, что этот вопрос уже довольно старый и лучшие решения (без использования javascript) уже предоставлены.
nirazul

1
Мне действительно нравится это решение. Это весело и показывает, что вы можете не только манипулировать своим html с помощью css, но также можете делать это с помощью jquery
csichar

6
Это решение не сработает, если высота столбцов изменится. Это могло произойти при изменении содержимого столбцов. Эту функцию нужно будет запускать: при изменении содержимого и изменении размера браузера. Подход css более идеален, поскольку он позволяет избежать этих проблем
Alexreardon

5

Это классическая проблема CSS. На самом деле решения для этого нет.

Эта статья из A List Apart - хорошее чтение по этой проблеме. Он использует технику, называемую «искусственные столбцы», основанную на наличии одного вертикально мозаичного фонового изображения на элементе, содержащем столбцы, что создает иллюзию столбцов одинаковой длины. Поскольку он находится на обертке плавающих элементов, его длина равна самому длинному элементу.


У редакторов A List Apart есть это примечание к статье:

Примечание редакторов: хотя эта статья превосходна для своего времени, она может не отражать передовой опыт.

Для этой техники требуются полностью статические дизайны ширины, которые не подходят для жидких макетов и техник адаптивного дизайна, которые сегодня популярны для сайтов с несколькими устройствами. Однако для сайтов со статической шириной это надежный вариант.


Спасибо, это похоже на хороший прием. Однако я забыл упомянуть, что в правом столбце должен быть текст по вертикали по центру. Правильно ли я полагаю, что искусственные столбцы не могут этого сделать?
Дениз Доган

4

У меня была аналогичная проблема, и, на мой взгляд, лучший вариант - использовать немного javascript или jquery.

Вы можете добиться одинаковой высоты желаемых div, получив максимальное значение div и применив это значение ко всем остальным div. Если у вас много div и много решений, я предлагаю написать небольшой продвинутый js-код, чтобы узнать, какой из всех div самый высокий, а затем использовать его значение.

С jquery и 2 div это очень просто, вот пример кода:

$('.smaller-div').css('height',$('.higher-div').css('height'));

И напоследок еще одно. Их набивка (верх и низ) должны быть одинаковыми! Если у одного есть большее заполнение, вам необходимо устранить разницу в заполнении.


1

Насколько мне известно, вы не можете сделать это, используя текущие реализации CSS. Чтобы сделать два столбца одинаковой высоты, вам понадобится JS.


1

У меня это работает в IE 7, FF 3.5, Chrome 3b, Safari 4 (Windows).

Также работает в IE 6, если вы раскомментируете более четкий div внизу. Edit : как сказал Натали Даун, вы можете просто добавить width: 100%;к #containerвместо.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <style type="text/css">
        #container {
            overflow: hidden;
            border: 1px solid black;
            background-color: red;
        }
        #left-col {
            float: left;
            width: 50%;
            background-color: white;
        }
        #right-col {
            float: left;
            width: 50%;
            margin-right: -1px; /* Thank you IE */
        }
    </style>
</head>
<body>
    <div id='container'>
        <div id='left-col'>
            Test content<br />
            longer
        </div>
        <div id='right-col'>
            Test content
        </div>
        <!--div style='clear: both;'></div-->
    </div>
</body>
</html>

Я не знаю способа CSS для вертикального центрирования текста в правом div, если div не имеет фиксированной высоты. Если это так, вы можете установить то line-heightже значение, что и высота div, и поместить внутренний div, содержащий ваш текст, с display: inline; line-height: 110%.


1

Используя Javascript, вы можете сделать два тега div одинаковой высоты. Высота меньшего div будет равна высоте самого высокого тега div, используя код, показанный ниже:

var rightHeight = document.getElementById('right').clientHeight;
var leftHeight = document.getElementById('left').clientHeight;
if (leftHeight > rightHeight) {
document.getElementById('right').style.height=leftHeight+'px';
} else {
document.getElementById('left').style.height=rightHeight+'px';
}

Где «left» и «right» являются идентификаторами тегов div.


1

Используя свойство css -> display: table-cell

div {
    border: 1px solid #000;
    margin: 5px;
    padding: 4px;
	display:table-cell;
	width:25%	;position:relative;
}
body{display:table;
	border-collapse:separate;
	border-spacing:5px 5px}
<div>
    This is my div one This is my div one This is my div one
</div>
<div>
    This is my div two This is my div two This is my div two This is my div two This is my div two This is my div two
</div>
<div>
    This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3 This is my div 3
</div>


0

Используя JS, используйте data-same-height="group_name"во всех элементах одинаковую высоту .

Пример: https://jsfiddle.net/eoom2b82/

Код:

$(document).ready(function() {
    var equalize = function () {
        var disableOnMaxWidth = 0; // 767 for bootstrap

        var grouped = {};
        var elements = $('*[data-same-height]');

        elements.each(function () {
            var el = $(this);
            var id = el.attr('data-same-height');

            if (!grouped[id]) {
                grouped[id] = [];
            }

            grouped[id].push(el);
        });

        $.each(grouped, function (key) {
            var elements = $('*[data-same-height="' + key + '"]');

            elements.css('height', '');

            var winWidth = $(window).width();

            if (winWidth <= disableOnMaxWidth) {
                return;
            }

            var maxHeight = 0;

            elements.each(function () {
                var eleq = $(this);
                maxHeight = Math.max(eleq.height(), maxHeight);
            });

            elements.css('height', maxHeight + "px");
        });
    };

    var timeout = null;

    $(window).resize(function () {
        if (timeout) {
            clearTimeout(timeout);
            timeout = null;
        }

        timeout = setTimeout(equalize, 250);
    });
    equalize();
});

0

Мне нужно было сделать что-то подобное, вот моя реализация. Напомним, цель состоит в том, чтобы два элемента занимали ширину данного родительского контейнера, а высота была настолько высокой, насколько это необходимо. По сути, высота равна максимальной высоте самого большого количества содержимого, но другой контейнер находится на одном уровне.

html

<div id="ven">
<section>some content</section>
<section>some content</section>
</div>

css

#ven {
height: 100%;
}
#ven section {
width: 50%;
float: left;
height: 100%;
}

0

Несколько лет назад floatсвойство использовалось для решения этой проблемы с использованием tableподхода display: table;и display: table-row;и display: table-cell;.

Но теперь со свойством flex вы можете решить эту проблему с помощью трех строк кода: display: flex;и flex-wrap: wrap;иflex: 1 0 50%;

.parent {
    display: flex;
    flex-wrap: wrap;
}

.child {
 // flex: flex-grow flex-shrink flex-basis;
    flex: 1 0 50%;
}

1 0 50%являются flexзначениями, которые мы присвоили: flex-grow flex-shrink flex-basisсоответственно. Это относительно новый ярлык в flexbox, позволяющий не вводить их по отдельности. Я надеюсь, что это поможет кому-то там

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.