Давайте начнем с добавления свойств по одному и посмотрим, что происходит.
По сути, у нас есть этот код без наценки и только с плавающими элементами:
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
}
.main-inner {
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
Понятно, что вы сделали красный элемент width:100%
плавающим слева, а зеленый - плавающим справа с фиксированной шириной. Вы также можете заметить, что элемент p
имеет поле по умолчанию, поэтому синий не полностью покрывает красный.
Теперь, если вы добавите отрицательный margin-right
, вы не будете перемещать элемент или уменьшать ширину, но вы будете вытягивать содержимое справа, чтобы перекрывать элемент. Вот основная иллюстрация:
.box {
width: 200px;
height: 200px;
background: red;
float: left;
}
<div class="box" style="margin-right:-100px;height:220px">
</div>
<div class="box" style="background:blue;">
</div>
Как вы можете видеть, синяя рамка перекрывает красную точно на 100px
, потому что мы применили -100px
к margin-right
красной рамки. Та же логика произойдет в вашем случае, вы применили отрицательное поле, равное размеру боковой панели, поэтому вы создали необходимое пространство для перемещения боковой панели на том же уровне основного элемента.
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
margin-right:-340px;
}
.main-inner {
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
Таким образом, основной элемент по-прежнему имеет ширину 100%, НО боковая панель перекрывает его из-за отрицательного поля.
Теперь последним шагом является добавление поля внутри основного, и в этом случае будет уменьшена ширина внутреннего элемента, чтобы итоговое значение (ширина + поле) всегда равнялось ширине родительского элемента (содержащего блок)
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
margin-right:-340px;
}
.main-inner {
background: blue;
margin-right:340px;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
Вот еще одна иллюстрация поля с не плавающим элементом блока:
.container {
border: 2px solid;
max-width: 50vw;
margin: auto;
}
.first {
height: 100px;
background: red;
margin: 0 -50px;
}
.second {
height: 100px;
background: blue;
margin: 0 50px;
}
<div class="container">
<div class="first">
</div>
<div class="second">
</div>
</div>
В этом случае ширина увеличивается / уменьшается из-за поля, потому что логика всегда: width + margin = width of containing block
.
С такими элементами, как float и inline block, логика одинакова, но у нас не будет изменений ширины, потому что ширина определяется либо содержимым, либо явно.
.container {
border: 2px solid;
display:inline-block;
}
.first {
float:left;
height: 100px;
background: red;
margin-right:-50px;
}
.second {
display:inline-block;
width:200px;
height: 120px;
background: blue;
margin-top:20px;
margin-right:-100px;
}
<div class="container">
<div class="first">
some text here
</div>
<div class="second">
</div>
</div>
Здесь элемент float имеет ширину, определяемую содержимым, а встроенный блок имеет ширину, равную 200px
. Отрицательное поле создает перекрытие, а размер родительского элемента (содержащего блока) равен ширине + поля.
Для справок:
8 Коробочная модель
9 Модель визуального форматирования
10 Детали модели визуального форматирования
Вышеприведенное объяснение очень упрощено. Обратитесь к ссылкам спецификации для полного и подробного объяснения.