Если вы планируете строить измерения своих элементов с абсолютными единицами (как в вашем примере), а не с использованием родственных единиц (как %
или em
), и если вы действительно (действительно) не хотите определять другое контейнер внутри вашего элемента .boxes
, и если вам нужно настроить таргетинг на старые браузеры, вы можете использовать абсолютное позиционирование .
Будьте осторожны, позиционирование не рекомендуется, потому что это затрудняет (или делает невозможным) правильное использование стиля адаптивного веб-дизайна с ним.
Элементы, которые относительно расположены, остаются в нормальном потоке документа. Напротив, элемент, который абсолютно позиционирован, вынимается из потока; таким образом, другие элементы позиционируются так, как если бы они не существовали. Абсолютно позиционированный элемент позиционируется относительно его ближайшего предка (то есть ближайшего предка, который не является статичным).
Используя эту технику, вы сможете точно определить, где вы хотите закрепить предметы (относительно предка, а не его предыдущего брата или сестры). Итак, используйте свойства top / bottom
и left / right
, чтобы закрепить элементы от расположенного предка. В качестве примера, top: 5px
будет закреплять элемент от 5px вершины первого расположенного предка (с absolute or relative
). Вы можете установить эти свойства, используя пиксели, проценты или все другие необходимые вам единицы.
Итак, чтобы ответить на ваш вопрос, этот пример, который я написал ниже, сделан для того, чтобы дать способ достичь вашей цели, но я не рекомендую его использовать ... Вы определенно должны создать еще один div чтобы обернуть предметы, которые вы хотите, один над другим.
:root {
--boxes-width: 450px;
--boxes-height: 100px;
--item-padding: 10px;
--item-width: 50px;
}
.boxes {
position: relative;
width: var(--boxes-width);
height: var(--boxes-height);
border:1px solid #fff;
background:#000;
float:left;
}
.item {
position: absolute;
background:#bf00bd;
border:1px solid #999;
top: var(--item-padding);
}
.item:first-child {
width:var(--item-width);
height:calc(var(--boxes-height) - var(--item-padding) * 2);
left: var(--item-padding);
}
.item:nth-child(2),
.item:nth-child(3) {
width: calc(var(--item-width) * 2);
height:calc((var(--boxes-height) - var(--item-padding) * 2) / 2 - (var(--item-padding) / 2));
left: calc(var(--item-width) + (var(--item-padding) * 2));
}
.item:nth-child(3) {
top: calc(var(--boxes-height) / 2 + (var(--item-padding) / 2));
}
.item:nth-child(n+4) {
position: relative;
float: right;
width: var(--item-width);
height: calc(var(--boxes-height) - var(--item-padding) * 2);
margin-right: var(--item-padding);
}
<div class="boxes">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
На самом деле, даже если этот метод не рекомендуется во многих случаях, он может удовлетворить ваши потребности. И иногда лучше всего сделать абсолютное позиционирование. Это зависит от ваших целей, от гибкости, которую дает вам код, и от браузеров, на которые вы хотите ориентироваться. Нет стандартного способа сделать что-то или нет, потому что нет ничего плохого в использовании абсолютного позиционирования.
Тем не менее, существуют наиболее распространенные способы, позволяющие упростить поддержку вашего кода и сделать его более оптимизированным для обеспечения доступности для всех пользователей.
В вашем случае, я думаю, вы можете обернуть предметы, которые вы хотите, друг над другом одним из родителей div
. На самом деле, элементы div
были созданы для того, чтобы дать возможность объединить некоторый код в специальный макет. Не является плохой практикой использование div
в качестве контейнера внутри других div
оболочек. Но вы должны избегать использования бесполезной обертки, когда она не нужна, потому что она замедляет рендеринг, DOM, отношения CSSOM и делает ваш код более трудным для чтения (среди прочих проблем). Вы единственный, кто может судить, если это необходимо или нет. Короче говоря, использование одной или двух оболочек определенно не плохая практика.
Таким образом, в зависимости от браузеров, на которые вы ориентируетесь, хорошим способом достижения этого может быть:
Я обновил свой ответ, чтобы дать вам больше советов, которые позволят вам понять ваши варианты. Так как вы использовали систему float в своем примере, я написал код, который также использовал ее, и которая совместима со многими (и старыми) браузерами.
Следующий код можно оптимизировать в соответствии с вашими потребностями. Я использовал ваш код, когда вы его написали. Кроме того, я добровольно использовал систему float
, а не grid
или flexbox
, чтобы охватить как можно больше браузеров. Имейте в виду, что система сетки - это еще один (действительно) хороший и современный подход к сокращению кода, но пока он не будет работать во всех браузерах. Как написано в другом ответе, макет grid
является мощным, о чем вам следует подумать. Тем более, что все современные браузеры могут использовать его.
.boxes{
position: relative;
width: 100%;
max-width: 450px;
height: 100px;
border:1px solid #fff;
background:#000;
float:left;
padding: 10px;
box-sizing: border-box;
}
.box {
height: 100%;
}
.box--left{ float: left }
.box--left > .item { float: left; }
.box--right{ float: right }
.box--right .item:last-child { margin-right: 0; }
.box-vert {
width: 100px;
float: left;
}
.box-vert .item {
height: calc(50% - 5px);
width: 100%;
}
.item{
background:#bf00bd;
border:1px solid #999;
width: 50px;
height: 100%;
margin-right: 10px;
display: inline-block;
}
<div class="boxes">
<div class="box box--left">
<div class="item"></div>
<div class="box box-vert">
<div class="item"></div>
<div class="item"></div>
</div>
</div>
<div class="box box--right">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>