Интервью CSS — Перекрытие полей и BFC

CSS

Тема этой статьи:

  • Основная концепция: стандартная модель + модель IE
  • Отличие базовой модели от модели IE: разница в расчете ширины и высоты
  • Как CSS настраивает обе модели (от теории к практике)
  • Как JS устанавливает и получает ширину и высоту, соответствующие блочной модели
  • Примеры вопросов (объясните проблему перекрывающихся полей на основе блочной модели)Надземное расширение
  • BFC (решение перекрытия маржи)Часто задаваемые вопросы на собеседованиях

коробочная модель

основная концепция

Что такое блочная модель CSS? Я считаю, что большинство людей могут ответить на этот вопрос, то есть стандартная модель + модель IE.

Стандартная модель:

IE модель

Это понятно

  • В стандартной модели коробки,widthа такжеheightОтносится к ширине и высоте области содержимого. Увеличение заполнения, границ и полей не повлияет на размер области содержимого, но увеличит общий размер блока элемента.
  • В блочной модели IEwidthа такжеheightОтноситсяcontent+border+padding

Как CSS устанавливает эти две модели

  • Стандартная модель:box-sizing: content-box;
  • IE модель:box-sizing: border-box;

Как установить ширину и высоту блочной модели в JS

  • dom.style.width/height: можно убрать только ширину и высоту встроенного стиля, например:<div id="aa" style="width: 200px"></div>
  • dom.currentStyle.width/heightПолучите стиль мгновенного расчета, но его поддерживает только IE.Для поддержки других браузеров можно использовать следующие способы
  • window.getComputedStyle(dom).width: лучшая совместимость
  • dom.getBoundingClientRect().width/height: используется реже, в основном для вычисления абсолютной позиции на странице.

Поля перекрываются

Что такое перекрытие полей?

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

Границы родительского и дочернего элементов перекрываются

<style>
  .parent {
    background: #e7a1c5;
  }
  .parent .child {
    background: #c8cdf5;
    height: 100px;
    margin-top: 10px;
  }
</style>
<section class="parent">
  <article class="child"></article>
</section>

Ожидаемый эффект:

На самом деле эффект следующий:

Здесь высота родительского элемента составляет не 110 пикселей, а 100 пикселей, где происходит коллапс высоты.

Причина в том, что если блочный элементmargin-topсо своим первым ребенкомmargin-topнет междуborder,padding,inline content,clearanceдля разделения, или между нижним нижним полем блочного элемента и нижним нижним полем его последнего дочернего элемента нет поля margin-bottomborder,padding,inline content,height,min-height,max-heightразделены, поля рухнут. Лишние поля дочерних элементов обрезаются полями родительского элемента.

Границы родственных элементов перекрываются

<style>
  #margin {
    background: #e7a1c5;
    overflow: hidden;
    width: 300px;
  }
  #margin > p {
    background: #c8cdf5;
    margin: 20px auto 30px;
  }
</style>
<section id="margin">
  <p>1</p>
  <p>2</p>
  <p>3</p>
</section>

Видно, что расстояние между 1 и 2, 2 и 3 не равно 50px, а максимальное значение между ними равно 30px, когда происходит перекрытие полей.

Границы пустых элементов перекрываются

Предположим, что есть пустой элемент, у него есть поля, но нет границы или заполнения. В этом случае верхнее и нижнее поля встречаются и сливаются:

BFC

Одним из решений вышеуказанных проблем является создание BFC. Полное название БФКBlock Formatting Context, контекст форматирования на уровне блока.

  • BFC в том же элементе взаимодействия может произойти коллапс маржи;
  • BFC — это независимый контейнер на странице, и дочерние элементы внутри контейнера не будут влиять на внешние элементы, и наоборот;
  • При расчете высоты BFC учитывайте все элементы, содержащиеся в BFC, включая плавающие элементы.
  • Площадь плавающей коробки не будет накладываться на BFC;

Предотвращение перекрытия вертикальных полей

Решение для перекрывающихся границ родительских и дочерних элементов: Добавьте overflow:hidden; к родительскому элементу, чтобы сделать его BFC.

.parent {
  background: #e7a1c5;
  overflow: hidden;
}

Границы родственных элементов перекрываются, создавая контекст BFC для второго дочернего элемента:

<section id="margin">
    <p>1</p>
    <div style="overflow:hidden;">
        <p>2</p>
    </div>
    <p>3</p>
</section>

очистить внутренний поплавок

<style>
  #float {
    background: #fec68b;
  }
  #float .float {
    float: left;
  }
</style>
<section id="float">
  <div class="float">我是浮动元素</div>
</section>

родительский элемент#floatимеет высоту 0, а решение является родительским элементом#floatСоздайте BFC, чтобы высота плавающего дочернего элемента также участвовала в вычислении высоты родительского элемента:

#float {
  background: #fec68b;
  overflow: hidden; /*这里也可以用float:left*/
}

Адаптивный двухколоночный макет

<section id="layout">
  <style>
    #layout {
      background: red;
    }
    #layout .left {
      float: left;
      width: 100px;
      height: 100px;
      background: pink;
    }
    #layout .right {
      height: 110px;
      background: #ccc;
    }
  </style>
  <!--左边宽度固定,右边自适应-->
  <div class="left"></div>
  <div class="right"></div>
</section>

Здесь высота справа установлена ​​выше, чем слева, и вы можете видеть, что избыток слева уходит вправо.Это потому, что плавающий блок не соответствует нормальному потоку документа, поэтому блок box в обычном потоке документа ведет себя как float. В результате box не существует.

Решение состоит в том, чтобы создать BFC для правильного элемента, чтобы BFC не перекрывал плавающий элемент.

#layout .right {
  height: 110px;
  background: #ccc;
  overflow: auto;
}

Ссылаться наПерекрытие полей и BFC