Ширина деления 100% минус фиксированное количество пикселей

316

Как я могу получить следующую структуру без использования таблиц или JavaScript? Белые границы представляют края div и не имеют отношения к вопросу.

Структура 1

Размер области посередине будет меняться, но он будет иметь точные значения пикселей, и вся структура должна масштабироваться в соответствии с этими значениями. Чтобы упростить его, мне нужен способ установить ширину "100% - n px" для верхних, средних и нижних средних элементов.

Я был бы признателен за чистое кросс-браузерное решение, но в случае, если это невозможно, CSS-хаки подойдут.

Вот бонус. Другая структура, с которой я боролся, и в итоге я использую таблицы или JavaScript. Это немного отличается, но вводит новые проблемы. Я в основном использовал его в оконной системе на основе jQuery, но я бы хотел, чтобы макет не использовался в скрипте и управлял размером только одного элемента (среднего).

Структура 2

Removed_account
источник
Что касается второго элемента, вы говорите, что хотите, чтобы высота самого среднего элемента была фиксированной, но остальные элементы были динамическими
Casebash

Ответы:

78

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

Вот пример, который вы можете использовать для размещения изображений в виде левого и правого скругленных углов, а также центральное изображение, которое повторяется между ними.

HTML:

<div class="Header">
   <div>
      <div>This is the dynamic center area</div>
   </div>
</div>

CSS:

.Header {
   background: url(left.gif) no-repeat;
   padding-left: 30px;
}
.Header div {
   background: url(right.gif) top right no-repeat;
   padding-right: 30px;
}
.Header div div {
   background: url(center.gif) repeat-x;
   padding: 0;
   height: 30px;
}
Guffa
источник
Спасибо за это. Мне пришлось немного подправить его для моей ситуации. Для первого вложенного элемента div требовалось поле справа-справа, а не отступ, а центру div также требовалось такое же значение поля справа.
Макс
3
Отличное решение. просто мелочь -> это работает, потому что ".Header div div" переопределяет ".Header div" . Это должны быть ".Header> div" и ".Header> div> div" . В самом деле, «.Header div» означает любого дочернего элемента div или дочернего элемента div, тогда как «.Header> div» означает только прямых потомков .Header
Charles HETIER
@CharlesHETIER: Да, это тоже работает, и его проще использовать, так как вам не нужно переопределять все настройки менее специфического правила. Ответ был написан, когда поддержка >оператора была еще недостаточно хороша, чтобы быть надежной.
Гуффа
1
Это устарело, см. Ответ ниже о функции calc на css.
Мария Ариас де Рейна Домингес
2
@delawen: Вы должны подождать некоторое время, прежде чем оно устареет. В calcIE 8 или в текущих версиях Anroid Browser или Opera нет поддержки . caniuse.com/#search=calc
Guffa
760

Новый способ, с которым я только что наткнулся: csscalc() :

.calculated-width {
    width: -webkit-calc(100% - 100px);
    width:    -moz-calc(100% - 100px);
    width:         calc(100% - 100px);
}​

Источник: CSS ширина 100% минус 100px

rom_j
источник
86
Лучший ответ 2013 года ИМХО. Принятый ответ устарел.
Дунайский моряк
7
Пришло время кто-то наткнулся на это. Я покончил с взломами теперь, когда я это знаю. +1 @lechlukasz
preahkumpii
47
После 10 лет борьбы с CSS этот ответ заслуживает +20000! Все еще не могу поверить своим глазам ...
skobaljic
8
Все, что я могу сказать, это ... youtube.com/…
Jazz
5
Более совместимы? -> $ ('# yourEl'). css ('width', '100%'). css ('width', '- = 100px'); (jQuery)
sboy031
7

Хотя ответ Гуффы работает во многих ситуациях, в некоторых случаях вы можете не захотеть, чтобы левая и / или правая части отступа были родительскими для центрального элемента div. В этих случаях вы можете использовать контекст форматирования блока в центре и перемещать div-отступы влево и вправо. Вот код

HTML:

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
    <div class="center"></div>
</div>

CSS:

.container {
    width: 100px;
    height: 20px;
}

.left, .right {
    width: 20px;
    height: 100%;
    float: left;
    background: black;   
}

.right {
    float: right;
}

.center {
    overflow: auto;
    height: 100%;
    background: blue;
}

Мне кажется, что эта иерархия элементов более естественна по сравнению с вложенными вложенными элементами div и лучше отражает то, что находится на странице. Из-за этого границы, отступы и поля могут быть применены нормально ко всем элементам (то есть: эта «естественность» выходит за рамки стиля и имеет последствия).

Обратите внимание, что это работает только для элементов div и других элементов, которые совместно используют свойство «по умолчанию заполнять 100% ширины». Входные данные, таблицы и, возможно, другие потребуют от вас обернуть их в контейнерный блок и добавить немного больше CSS, чтобы восстановить это качество. Если вам не повезло оказаться в такой ситуации, свяжитесь со мной, и я откопаю css.

jsfiddle здесь: jsfiddle.net/RgdeQ

Наслаждайтесь!

Unislash
источник
6

Вы можете использовать макет Flexbox . Вам нужно установить flex: 1на элемент, который должен иметь динамическую ширину или высоту flex-direction: row and columnсоответственно.

Динамическая ширина:

HTML

<div class="container">
  <div class="fixed-width">
    1
  </div>
  <div class="flexible-width">
    2
  </div>
  <div class="fixed-width">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-width {
  width: 200px; /* Fixed width or flex-basis: 200px */
}
.flexible-width {
  flex: 1; /* Stretch to occupy remaining width i.e. flex-grow: 1 and flex-shrink: 1*/
}

Вывод:


Динамическая высота:

HTML

<div class="container">
  <div class="fixed-height">
    1
  </div>
  <div class="flexible-height">
    2
  </div>
  <div class="fixed-height">
    3
  </div>
</div>

CSS

.container {
  display: flex;
}
.fixed-height {
  height: 200px; /* Fixed height or flex-basis: 200px */
}
.flexible-height {
  flex: 1; /* Stretch to occupy remaining height i.e. flex-grow: 1 and flex-shrink: 1*/
}

Вывод:

Манодж Кумар
источник
3

Обычный способ сделать это, как обрисовано в общих чертах Guffa, вложенные элементы. Немного грустно, когда нужно добавить дополнительную разметку, чтобы получить нужные вам крючки, но на практике div-обертка здесь или там никому не повредит.

Если вы должны сделать это без дополнительных элементов (например, когда у вас нет контроля над разметкой страницы), вы можете использовать box-size , который имеет довольно приличную, но не полную или простую поддержку браузера. Хотя, скорее, веселее, чем полагаться на сценарии.

bobince
источник
3

Может быть, я тупой, но разве здесь не очевидное решение?

<div class="parent">
    <div class="fixed">
    <div class="stretchToFit">
</div>

.parent{ display: table; width 100%; }
.fixed { display: table-cell; width: 150px; }
.stretchToFit{ display: table-cell; vertical-align: top}

Другой способ, который я понял в chrome, еще проще, но, черт возьми, это хак!

.fixed{ 
   float: left
}
.stretchToFit{
   display: table-cell;
   width: 1%;
}

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

Джек Франзен
источник
2

Мы можем добиться этого, используя flex-box очень легко.

Если у нас есть три элемента, такие как Header, MiddleContainer и Footer. И мы хотим задать некоторую фиксированную высоту для верхнего и нижнего колонтитула. тогда мы можем написать так:

Для React / RN (по умолчанию «display» - это flex, а «flexDirection» - как столбец), в веб-CSS необходимо указать контейнер тела или контейнер, содержащий их, как display: «flex», flex-direction: «column». как ниже:

    container-containing-these-elements: {
     display: flex,
     flex-direction: column
    }
    header: {
     height: 40,
    },
    middle-container: {
     flex: 1, // this will take the rest of the space available.
    },
    footer: {
     height: 100,
    }
jayiitb
источник
1

Что, если ваш div оборачивания был равен 100%, и вы использовали заполнение для количества пикселей, то если заполнение # должно быть динамическим, вы можете легко использовать jQuery для изменения количества заполнения, когда ваши события запускаются.

dfasdljkhfaskldjhfasklhf
источник
1

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

CSS:

.banner_left {
position: absolute;
top: 0px;
left: 0px;
width: 131px;
height: 150px;
background-image: url("left_image.jpg");
background-repeat: no-repeat;
}

.banner_right {
position: absolute;
top: 0px;
left: 131px;
right: 0px;
height: 150px;
background-image: url("right_repeating_image.jpg");
background-repeat: repeat-x;
background-position: top left;
}

Ключ был правильным тегом. Я в основном указываю, что я хочу, чтобы это повторялось от 131px слева до 0px справа.

Майк Кэри
источник
0

В некоторых контекстах вы можете использовать настройки полей для эффективного указания «100% ширины минус N пикселей». Смотрите принятый ответ на этот вопрос .

хаос
источник