Как сделать стабильную двухколоночную разметку в HTML / CSS

Я хочу контейнер с двумя столбцами. Подробности:

Контейнер

  • Ширина должна составлять 100% от родительского элемента (это легко сделать).
  • Высота должна регулироваться, чтобы содержать оба столбца (т.е. его высота должна быть точно равна большей высоте двух столбцов, чтобы не было переполнения и полосы прокрутки никогда не отображались)
  • Должен иметь минимальный размер, равный двойной ширине левого столбца.

Колонны в целом

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

Левый столбец конкретно

  • Должен иметь фиксированную абсолютную ширину в пикселях.

Правый столбец конкретно

  • Ширина должна заполнять оставшееся пространство в емкости. Другими словами...
  • Ширина должна равняться ширине контейнера за вычетом ширины левого столбца, так что если я помещаю элемент блока DIV внутри этого столбца, устанавливаю его ширину на 100%, задаю ему высоту примерно 10 пикселей и задаю ему цвет фона, Я увижу цветную полосу высотой 10 пикселей, которая идет от правого края левого столбца к правому краю контейнера (т.е. заполняет ширину правого столбца).

Требуемая стабильность

Контейнер должен иметь возможность изменять размер (путем изменения размера окна браузера) до минимальной ширины (указанной ранее) или до гораздо большей ширины без нарушения макета. "Нарушение" будет включать изменение размера левого столбца вообще (помните, что он должен иметь фиксированную ширину в пикселях), перенос правого столбца под левый, появление полос прокрутки, блокирующие элементы в правом столбце, не занимающие всю ширину столбца , и в целом любая из вышеупомянутых спецификаций не соответствует действительности.

Фон

Если используются плавающие элементы, не должно быть никаких шансов, что правый столбец будет переноситься под левый, что контейнер не сможет содержать оба столбца (путем обрезания любой части столбца или разрешения любой части столбца выходить за пределы его границы. ), или появятся полосы прокрутки (поэтому я бы устал предлагать использовать что-либо, кроме overflow: hidden, для запуска сдерживания плавающих элементов). Применение границ к столбцам не должно нарушать макет. Содержимое столбцов, особенно правого столбца, не должно нарушать макет.

Кажется, есть простое решение на основе таблиц, но при любых обстоятельствах оно терпит неудачу. Например, в Safari мой левый столбец с фиксированной шириной будет уменьшаться, если контейнер станет слишком маленьким, вместо того, чтобы поддерживать указанную мной ширину. Также кажется, что ширина CSS при применении к элементу TD относится к минимальной ширине, так что если внутри него помещается что-то большее, оно расширяется. Я пробовал использовать table-layout: fixed; не помогает. Я также видел случай, когда элемент TD, представляющий правый столбец, не расширяется, чтобы заполнить оставшуюся область, или он будет выглядеть так (например, третий столбец шириной 1 пиксель будет сдвинут до конца вправо), но установка рамки вокруг правого столбца покажет, что она равна ширине встроенного содержимого, а элементы уровня блока с шириной, установленной на 100%, не заполняют ширину столбца, а скорее соответствуют ширине встроенного содержимого (т.е. ширина TD, кажется, полностью зависит от содержимого).

Одно потенциальное решение, которое я видел, слишком сложное; Мне наплевать на IE6, если он работает в IE8, Firefox 4 и Safari 5.


person Triynko    schedule 06.04.2011    source источник


Ответы (3)


Ну вот:

<html>
<head>
  <title>Cols</title>
  <style>
    #left {
      width: 200px;
      float: left;
    }
    #right {
      margin-left: 200px;
      /* Change this to whatever the width of your left column is*/
    }
    .clear {
      clear: both;
    }
  </style>
</head>

<body>
  <div id="container">
    <div id="left">
      Hello
    </div>
    <div id="right">
      <div style="background-color: red; height: 10px;">Hello</div>
    </div>
    <div class="clear"></div>
  </div>
</body>

</html>

Посмотрите, как это работает здесь: http://jsfiddle.net/FVLMX/

person richzilla    schedule 06.04.2011
comment
Это ЕДИНСТВЕННЫЙ способ, который работает, и он чрезвычайно прост. Сводка: левый столбец с float: left и фиксированной шириной в пикселях и правый столбец с width: auto и левым полем, равным ширине левого столбца. Кроме того, я установил переполнение: скрыто в контейнере, потому что в противном случае я видел перенос правого столбца. А чтобы разместить в столбцах дочерние элементы со 100% шириной, вы должны установить {box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box;}, поэтому их заполнение и граница включены в эти 100%, чтобы предотвратить переполнение. - person Triynko; 07.04.2011
comment
Есть ли способ сделать это без четкого div? Некоторое время я работал в магазине, в котором был настроен CSS, который не нуждался в четком div, но я его не писал. Я просто все время им пользовался. Возможно, есть способ поместить его в контейнер div? - person mtmurdock; 11.04.2014
comment
Я часами пробовал отрывки из Интернета, которые так или иначе сломались. Первый комментарий здесь правильный: это очень просто, и это действительно работает - даже когда контент шире, чем область просмотра. (И если это произойдет, вы все равно можете прокрутить, чтобы увидеть это!) - person SirNickity; 14.02.2017

Мне наплевать на IE6, если он работает в IE8, Firefox 4 и Safari 5.

Это делает меня счастливой.

Попробуйте следующее: Live Demo

display: table на удивление хорошо. Если вам не нужен IE7, вы можете его использовать. На самом деле у него нет обычных недостатков <table>.

CSS:

#container {
    background: #ccc;
    display: table
}
#left, #right {
    display: table-cell
}
#left {
    width: 150px;
    background: #f0f;
    border: 5px dotted blue;
}
#right {
    background: #aaa;
    border: 3px solid #000
}
person thirtydot    schedule 06.04.2011
comment
Думаю, я недостаточно хорошо прочитал нижнюю часть вашего сообщения, я только что заметил следующее: "For example, in Safari, my fixed-width left column will shrink if the container gets too small, rather than maintaining the width I specified. It also seems to be the case that CSS width, when applied to a TD element refers to a minimum width, such that if something larger is placed inside it, it will expand. I've tried using table-layout:fixed; doesn't help.". Я посмотрю. - person thirtydot; 07.04.2011
comment
О каких измерениях мы здесь говорим? Какова ширина левого столбца? И обо всем этом? - person thirtydot; 07.04.2011
comment
Вот еще одна измененная версия с глупым 2000px широким изображением: jsfiddle.net/thirtydot/MeFYQ/2 - надеюсь, вы оставите отзыв :) - person thirtydot; 07.04.2011
comment
К сожалению, таблицы просто не работают. Я попробовал display: table / table-row / table-cell, и он просто работал как обычная таблица, где левый столбец уменьшался. На самом деле вы опубликовали нестабличное решение этой проблемы в комментариях к другому заданному мной вопросу (stackoverflow.com/questions/5540485/). См. Также решение здесь, где автор просто заявляет, что его ответ является решением, ха-ха: stackoverflow.com/questions/3568262/ - person Triynko; 07.04.2011
comment
@Triynko: Вы специально пробовали демку, которую я опубликовал в своем последнем комментарии? Забудьте об этом, вот еще одна исправленная версия с min-width: jsfiddle.net/thirtydot/MeFYQ/3 - как вы и просили, я тестировал его в Firefox 4, Safari 5, IE8 - что-то не так? Я не понимал, что вы задаете здесь тот же вопрос, что и в своем последнем; они кажутся совсем другими. И на всякий случай поможет: Торжественно заявляю, что мой ответ - это решение :) - person thirtydot; 07.04.2011
comment
+1 здесь за столь всеми любимый стол без реального стола :-) - person Pavel; 20.02.2014
comment
@thirtydot Я только что протестировал это на виртуальной машине Win XP с IE8, и это просто не работает. Столбцы отображаются во всю ширину своего содержимого и поэтому располагаются один над другим. - person Phill Healey; 14.04.2014
comment
@PhillHealey: Это определенно работает в IE8, вы что-то делаете не так. См. netrenderer.com, установите IE8, jsfiddle.net/thirtydot/MeFYQ/show. Вероятно, ваша тестовая страница была в режиме причуд. - person thirtydot; 14.04.2014
comment
@thirtydot Возможно, вы правы. Если так, то осознание этого могло решить мою проблему. Спасибо. - person Phill Healey; 15.04.2014

Кусок пирога.

Используйте 960Grids. Перейдите на автоматический конструктор макетов и создайте плавный дизайн из двух столбцов. Создайте левый столбец по ширине сетки, которая работает ... это единственная проблема с сетками, и это очень легко, если вы прочитаете учебник. Вкратце, каждый столбец в сетке имеет определенную ширину, и вы устанавливаете количество столбцов, которое хотите использовать. Чтобы получить столбец точно определенной ширины, вам нужно настроить математику так, чтобы ширина столбца была точной. Не слишком круто.

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

Вуаля. Сетки FTW.

person bpeterson76    schedule 06.04.2011