Сделайте два элемента CSS, заполнив их контейнер, бок о бок, с разницей

19

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

<div class='wrap'>
  <div class='element'>HELLO</div><div class='element'>WORLD</div>
</div>​
.wrap {
  background:red;
  white-space:nowrap;
  width:300px;
}
.element {
  background:#009; color:#cef; text-align:center;
  display:inline-block;
  width:50%;
  margin:4px;
}

Как вы можете видеть в ссылке , результат состоит в том, что дети переполняют оболочку:

Поле «world» проходит мимо конца контейнера «wrap»

Как я могу заставить их поместиться в пространстве? К сожалению, для этого случая нет box-sizing:margin-box .

    
задан Phrogz 04.01.2013 в 22:17
источник
  • О, и предполагается, что ширина родительской обертки неизвестна и / или гибка; тот факт, что он жестко запрограммирован на 300 пикселей, предназначен только для демонстрации. Установка детей на ширину: 142px не является приемлемым общим решением. :) –  Phrogz 04.01.2013 в 22:54

4 ответа

40

Техника № 1 - Современный CSS3 calc()

Используя длину calc() CSS3 , вы можете сделать это, установив ширину .element :

.element {
  width: 49%;                     /* poor approximation for old browsers    */
  width: calc(50% - 8px);         /* standards-based answer for IE9+, FF16+ */
  width: -moz-calc(50% - 8px);    /* support for FF4 - FF15                 */
  width: -webkit-calc(50% - 8px); /* support for Chrome19+ and Safari6+     */
}

Демо: Ссылка

Подробнее о том, какие браузеры и версии поддерживают это, см. Ссылка .

Техника № 2 - Старая школьная упаковка

Вычисления могут быть выполнены путем складывания нескольких элементов. В этом случае мы обертываем каждый «элемент» в оболочку шириной 50%, но с дополнением 4px:

<div class='wrap'>
  <div class='ele1'>
    <div class='element'>HELLO</div>
  </div><div class="ele1">
    <div class='element'>WORLD</div>
  </div>
</div>​
.ele1 {
    display:inline-block;
    width:50%;
    padding:4px;
    box-sizing:border-box;          /* Make sure that 50% includes the padding */
    -moz-box-sizing:border-box;     /* For Firefox                             */
    -webkit-box-sizing:border-box;  /* For old mobile Safari                   */
}
.element {
    background:#009; color:#cef; text-align:center;
    display:block;
}

Демо: Ссылка

Техника № 3 - Использование таблиц (CSS)

Тот же результат можно сделать, рассматривая оболочку как «таблицу», а каждый элемент - как ячейку в той же строке. При этом пробелы между элементами не важны:

<div class='wrap'>
  <div class='element'>HELLO</div>
  <div class='element'>WORLD</div>
</div>​
.wrap {
    background:red;
    width:300px;
    display:table;
    border-spacing:4px
}
.element {
    background:#009; color:#cef; text-align:center;
    width:50%;
    display:table-cell;
}
​

Демо: Ссылка

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

    
ответ дан Phrogz 04.01.2013 в 22:17
источник
  • Другим вариантом является использование CSS box-sizing: border-box; –  Falmarri 05.01.2013 в 00:19
  • @Falmarri Нет, это явно не работает, потому что box-sizing: border-box только доходит до края границ. Дополнительная ширина из-за полей не включена в 50%. –  Phrogz 05.01.2013 в 18:55
  • На самом деле я неправильно читаю ваш второй ответ, и вот что я имел в виду –  Falmarri 07.01.2013 в 18:40
2

То, что вы описываете, в основном является границей. Итак, почему бы не использовать свойство CSS border с фоном-клипом? Просто не забудьте соответствующие префиксы поставщика.

Ссылка

.wrap {
    background-color: red;
    white-space:nowrap;
    width:300px;
}
.element {
    background:#009; color:#cef; text-align:center;
    display:inline-block;
    width:50%;
    border:4px solid rgba(0,0,0,0);
    box-sizing: border-box;
    background-clip: padding-box;
}
    
ответ дан Evgeny 04.01.2013 в 23:42
источник
  • Визуальный внешний вид в этом упрощенном тестовом случае оказывается красной рамкой (так что вы можете видеть ширину родительского контейнера), но описанный общий случай - это маржа, предотвращающая визуальное касание двух элементов. К сожалению, граница с цветом прозрачной или rgba (0,0,0,0) приведет к тому, что цвет фона элемента будет светить, предотвращая желаемый эффект. –  Phrogz 04.01.2013 в 23:48
  • можно сделать прозрачную границу с фоном-клипом: padding-box (вы можете комбинировать его с свойством фона ярлыка) –  Evgeny 05.01.2013 в 00:05
  • stackoverflow.com/questions/4062001/css3-border-opacity –  Evgeny 05.01.2013 в 00:05
  • +1 для фонового клипа плюс прозрачный. Ницца! :) –  Phrogz 05.01.2013 в 00:07
0

Ни один из вышеперечисленных методов не работал достаточно для меня. Я нашел несколько иной метод, используя display:table-cell , позволил мне разместить 2 или более элемента рядом друг с другом. Вот пример этого в действии .

CSS:

    display:table-cell;
    background:#009; color:#cef; text-align:center;
    width:22%; /*Set percentage based on # of elements*/
    border:4px solid rgb(255,0,0);/*no longer need background to be red, just make border red*/

Вам больше не нужна оболочка, так как div теперь рассматривается как <td> .

    
ответ дан Joe Komputer 11.03.2014 в 22:39
источник
  • Я не уверен, как ни одно из вышеперечисленных не сработало для вас, но это произошло, когда эта техника является третьей, которую я перечисл в своем ответе. Что мне не хватает? –  Phrogz 11.03.2014 в 23:48
  • Извините, вам следует более внимательно прочитать ответ. Ваш третий метод использует table-cell, как и я, поэтому он работал бы на меня. Хотя в моем ответе я удалил ненужный код. –  Joe Komputer 12.03.2014 в 16:33
0

Хотя я настоятельно рекомендую использовать метод calc() Phorgz, когда это возможно, я также хочу предложить способ старой школы, который использует только одну обертку и position: relative для достижения эффекта.

.two-blocks-by-side () LESS Mixin:

.two-blocks-by-side(@padding) {
  padding: @padding (@padding + @padding / 2);
  font-size: 0;

  & > div {
    position: relative;
    display: inline-block;
    font-size: initial;
    width: 50%;

    &:first-child { left: -1 * @padding / 2 };
    &:last-child { right: -1 * @padding / 2 };
  }
}

Пример JS Bin

    
ответ дан Christophe Marois 12.06.2014 в 17:23
источник