Почему «наложенные элементы отрицательной маржи и поплавка» перекрываются? - PullRequest
0 голосов
/ 04 сентября 2018

Прежде всего, пожалуйста, посмотрите на этот код.

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

Но я не могу понять часть этого кода.

.container {
    overflow: hidden;
}

main {
    float: left;
    width: 100%;
    margin-right: -340px;
    background: red;
}

.main-inner {
    margin-right: 340px;
    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>

Вопрос 1

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

Вопрос 2

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

Итак, я думаю, что мы готовим горизонтальную ширину, которая может применить дополнительный элемент, применяя отрицательное поле, но цвет фона основного элемента применяется так же, как когда горизонтальная ширина равна 100%. Почему цвет фона основного элемента отсутствует (100% по ширине)? Как выполняется эта серия рендеринга?

Вопрос 3

Какой документ на W3.org описывает эти действия? Я пытался искать, но не смог найти никакой подробной информации о них.

спасибо.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Нечетное размещение из <main> происходит из css-правила браузера

p {
  display: block;
  -webkit-margin-before: 1em;
  -webkit-margin-after: 1em;
  -webkit-margin-start: 0px;
  -webkit-margin-end: 0px;
}

Вы можете сбросить его с помощью сброса css, например normalize.css .

Однако я рекомендую использовать display: flex. Некоторые замечательные ресурсы.

.container {
  display: flex;
}
main {
  width: 75%;
}
aside {
  width: 25%;
}
0 голосов
/ 04 сентября 2018

Давайте начнем с добавления свойств по одному и посмотрим, что происходит.

По сути, у нас есть этот код без наценки и только с плавающими элементами:

.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 Детали модели визуального форматирования


Вышеприведенное объяснение очень упрощено. Обратитесь к ссылкам спецификации для полного и подробного объяснения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...