Абсолютне позиціонування ігнорування прокладки батьків


173

Як зробити так, щоб абсолютний розміщений елемент шанував прокладку його батьків? Я хочу, щоб внутрішній дів розтягнувся на ширину його батьківського і був розміщений в нижній частині цього з батьків, в основному футера. Але дитина має шанувати батьківські прокладки, і це не робить. Дитину притискають праворуч до краю батька.

Тому я хочу цього:

введіть тут опис зображення

але я отримую це:

введіть тут опис зображення

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
      <div style="background-color: gray; position: absolute; left: 0px; right: 0px; bottom: 0px;">css sux</div>
    </div>
  </body>
</html>

Я можу зробити це з відривом навколо внутрішнього поділу, але я вважаю за краще не додати цього.


5
Чому б не змінити лівий / правий / нижній внутрішній поділ на style="background-color: gray; position: absolute; left: 10px; right: 10px; bottom: 10px;"?
— j08691

12
Так, я подумав про це, але це швидко стає головним болем у підтримці, тому що кожна дитина повинна мати свій набір компенсацій для його обліку. Якщо вони просто вшановуватимуть батьківські набивки, то ви можете просто встановити його один раз у батьків і не турбуватися про всіх дітей.
— d512

Як було зазначено вище, якщо ви використовуєте значення (відносно розташованого) батьківського накладки як для дитини, так left:і right:для (в абсолютному розміщенні), ваша проблема буде вирішена. Я додаю це b / c, це відповідь, яку інші з тією ж проблемою можуть шукати.
— rda3000

Майте подібну проблему тут: jsfiddle.net/5n4By/6 . Нижній колонтитул шанує ліву підкладку батьків, але справа переповнюється. Ви сподіваєтесь, що він буде шанувати правильну підкладку, а також залишатися послідовними ...
— rafiki_rafi

Відповіді:


186

Спочатку давайте розберемося, чому це відбувається.

Причина полягає в тому, що, на диво, коли у коробці є position: absoluteвміщена скринька, це коробка батьківського набивання (тобто коробка навколо її прокладки). Це дивно, тому що зазвичай (тобто при використанні статичного або відносного позиціонування) поле, що містить, є полем вмісту батьків .

Ось відповідна частина специфікації CSS :

У випадку, якщо пращур є вбудованим елементом, що містить блок - це обмежувальне поле навколо набивних коробок першого та останнього вкладених коробок, створених для цього елемента .... В іншому випадку блок, що містить, формується краєм оббивки предка.

Найпростіший підхід - як пропонується у відповіді Зімової - полягає у використанні padding: inheritна абсолютно встановленому місці div. Це працює лише, якщо ви не хочете, щоб абсолютно позиціоновані divбули власні додаткові накладки. Я думаю, що найбільш загальні рішення (в тому, що обидва елементи можуть мати власну незалежну підкладку):

  1. Додайте додатковий відносно розташований div(без прокладки) навколо абсолютно розташованого div. Це нове divбуде поважати прокладку свого батьківського складу, і абсолютно розміщена divтоді його заповнить.

    Мінус, звичайно, полягає в тому, що ти возишся з HTML просто для презентаційних цілей.

  2. Повторіть прокладку (або додайте до неї) на абсолютно розташованому елементі.

    Мінус тут полягає в тому, що вам потрібно повторити значення у своєму CSS, що є крихким, якщо ви пишете CSS безпосередньо. Однак якщо ви використовуєте інструмент попередньої обробки, як, SASSабо LESSви можете уникнути цієї проблеми, використовуючи змінну. Це метод, який я особисто використовую.


Чому це за замовчуванням position: absolute? Дивно, що коробка, що містить, є коробкою для набивання, але, мабуть, це було причиною, як і я впевнений, що є причина, чому (без box-sizing) width& heightне включають прокладки або рамки.
— трис

1
Просто доповнення: ні на що це не впливає box-sizingмайно на батьків чи дитину. Це тому, що це впливає на розмір , як на ширину / висоту, але не на поле, що містить, хоча, я визнаю, це було б більше сенсу, якби це стосувалося обох.
— трис

2
Це гарна інформація, але це неправильна відповідь. Правильною відповіддю є Зима нижче .... використовуйте підкладку: успадкуйте, і ваш елемент Absolute отримає необхідні вагонки. Не знаю, чому на це більше причин, ніж на правильну відповідь ...: P
— NotaGuruAtAll

1
@NotaGuruAtAll: padding: inheritдобре працює, якщо абсолютно розташований divне потребує власних накладок, і я додав згадку про цю техніку. Це менш гнучко, тому що ви не можете додати ніяких додаткових накладок до абсолютно розташованих div(тобто не можете сказати padding: inherit + 5px). Ось чому я віддаю перевагу техніці, про яку я тут згадую.
— Кевін Крістофер Генрі

1
Спадщина накладки на position:absoluteдочірньому елементі дійсно працює, якщо ви просто шукаєте, щоб дитина поважала батьківські прокладки. Однак якщо ви хочете додати додаткові накладки на дитину, вам доведеться зберегти співвідношення прокладок у вашому коді. Немає чистого способу зробити це лише за допомогою CSS.
— Ділан Пірс

51

Одне, що ви можете спробувати, це використовувати наступний css:

.child-element {
    padding-left: inherit;
    padding-right: inherit;
    position: absolute;
    left: 0;
    right: 0;
}

Це дозволяє дочірньому елементу успадкувати прокладку від батьків, тоді дитина може бути розміщена так, щоб вона відповідала ширині батьків і прокладці.

Також я використовую box-sizing: border-box;для залучених елементів.

Я не тестував це у всіх браузерах, але, здається, працює в Chrome, Firefox та IE10.


Я поєднав цю відповідь та відповідь @NewSpender. У моєму конкретному випадку абсолютний розміщений div не зважав на прокладку, але був обмежений його батьківським елементом. Таким чином, надання абсолютного розміщеного діва з білими товстими рамками імітувало потрібну мені підкладку. Обов’язковою умовою є те, що ваш фон повинен бути одного кольору.
— Ogier Schelvis

Але ОП не хоче, щоб дитина успадковувала батьківські набивки. Він хоче, щоб дитина була зміщена відповідно до батьківської підкладки.
— Майкл Гуммельт

30

Що ж, це може бути не найелегантнішим рішенням (семантично), але в деяких випадках воно буде працювати без будь-яких недоліків. Абсолютно розташовані дочірні елементи будуть шанувати межу, і вона буде надана точно так само (за винятком випадків, коли ви використовуєте межу батьківського елемента для стилізації).



6

Ось мій найкращий знімок у цьому. Я додав ще один Div і зробив його червоним і змінив зріст вашого батька на 200 пікс, просто щоб перевірити його. Ідея полягає в тому, що дитина зараз стає онуком, а батько стає бабусею та дідусем. Так батько поважає свого батька. Сподіваюся, ви зрозумієте мою ідею.

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 200px;">
     <div style="background-color: red;  position: relative; height: 100%;">    
        <div style="background-color: gray; position: absolute; left: 0px; right: 0px;bottom: 0px;">css sux</div>
     </div>
    </div>
  </body>
</html>

Редагувати:

Я думаю, що те, що ти намагаєшся зробити, неможливо зробити. Абсолютна позиція означає, що ви збираєтесь надати їй координати, які він повинен шанувати. Що робити, якщо у батьків є прокладка 5 пікселів. І ви абсолютно позиціонуєте дитину вгорі: -5px; зліва: -5px . Як це припустити одночасно шанувати батьків і вас ??

Моє рішення

Якщо ви хочете, щоб він шанував батьків, тоді не позиціонуйте його абсолютно.


Дякую, я вдячний за публікацію, але це все-таки вирішення справжнього питання. Я дуже хочу знати, якщо ви можете змусити дітей шанувати прокладку батьківського елемента. Якщо виявиться, що відповідь - ні, я дам вам відповідь.
— d512

Якщо ви абсолютно позиціонуєте їх, то вони не будуть шанувати їх батьківський елемент. Вони тебе вшанують. З тієї ж причини, якщо ви абсолютно не розміщуєте їх, ви не можете реально використовувати такі речі, як bottom: 10px, оскільки вони шанують свій батьківський елемент. Але те, що ви хочете зробити, я здогадуюсь, це створить місце для протиріччя, і, таким чином, воно буде відрізнятися в браузерах. Я думаю, що тільки робота навколо буде робити.
— Торкніться

3
Абсолютне позиціонування вшановує батьків, це система координат, яку він використовує. Коли ви говорите верхній 0px, це означає, що 0px від верхньої частини батьків. Питання полягає в тому, чи слід брати до уваги батьків підкладки. Якщо б у батьків було прокладка 5 пікселів, а ви дали дитині верх: -5 пікселів, він би поставив його нарівні з батьком, якщо батьківська прокладка буде шанована, або на 5 пікселів над батьківською, якщо її не було.
— d512

3

1.) Ви не можете використовувати велику межу для батьків - якщо ви хочете мати конкретну межу

2.) Ви не можете додати маржу - якщо ваш батько є частиною іншого контейнера, і ви хочете, щоб ваш батько взяв повну ширина цього батька.

Єдине рішення, яке повинно бути застосоване, - це загортати своїх дітей в інший контейнер, щоб ваш батько став бабусею та дідусем, а потім застосувати накладки до нового дитячого обгортка / батька. Або ви можете безпосередньо застосувати накладки для дітей.

У вашому випадку:

.css-sux{
  padding: 0px 10px 10px 10px;
}

1

Можна було легко зробити, використовуючи додатковий рівень Div.

<div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
  <div style="position: absolute; left: 0px; right: 0px; bottom: 10px; padding:0px 10px;">
    <div style="background-color: gray;">css sux</div>
  </div>
</div>

Демонстрація: https://jsfiddle.net/soxv3vr0/


0

додайте прокладки: успадковуйте в абсолютній позиції

.box{
  background: red;
  position: relative;
  padding: 30px;
  width:500px;
  height:200px;
 box-sizing: border-box;
 

}
<div  class="box">

  <div style="position: absolute;left:0;top:0;padding: inherit">top left</div>
  <div style="position: absolute;right:0;top:0;padding: inherit">top right</div>
  <div style="text-align: center;padding: inherit">center</div>
  <div style="position: absolute;left:0;bottom:0;padding: inherit">bottom left</div>
  <div style="position: absolute;right:0;bottom:0;padding: inherit">bottom right</div>


</div>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.