I Shar

I Shar

мир глазами веб-разработчика

CSS. Магия отступов

padding и margin в процентах, как это работает

I Shar

время чтения 4 мин.

Существует вопрос, который я задаю многим разработчикам, но, к сожалению, не получаю верного ответа: “Что означают проценты для свойств CSS padding и margin?”

padding

Полученые ответы были несколько обескураживающими: 70% разработчиков не смогли ответить на вопрос, 30% - предположили, что это процент от свойства родительского элемента.

И для этих тридцати процентов у меня был заготовлен еще один вопрос: “Какое именно свойство родительского элемента является определяющим: width, height, margin, padding, border?”

Эти вопросы вызывают затруднения, не так ли? Не беспокойтесь, только 1% разработчиков знает правильный ответ. Итак, Вы будете удивлены, узнав что:

Свойства margin и padding вложенного элемента, установленные в процентах, являются процентами от ширины родительского элемента.

Обратимся к примеру:

.parent {
    width: 100px;
    height: 150px;
    margin: 2px;
    padding: 1px;
    border: 1px solid red;
}
.child {
    margin: 10%;
    padding: 10%;
    border: 1px dashed blue;
}

Установленный для вложенного элемента padding: 10%; рассчитывается следующим образом:

Child Padding = (Parent Width)*x%

В данном случае результатом будет 10px, что подтверждается и блочной моделью вложенного элемента:

child padding

вложенный элемент с padding 10%

Итак, Вы узнали как правильно рассчитать margin и padding элемента в процентах.

Остается еще один вопрос: “Как вычислить высоту вложенного элемента? Зависит ли она от ширины родителя, так же как margin и padding?”

Давайте проверим:

.parent {
    width: 100px;
    height: 150px;
    border: 1px solid red;
}
.child {
    height: 10%;
    border: 1px dashed blue;
}

child height

вложенный элемент с height 10%

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

Child Height = (Parent Height)*x%


Итак, мы определились с двумя основными правилами:

  1. margin и padding в процентах рассчитываются по ширине родительского элемента,
  2. высота (height) в процентах рассчитывается по высоте родительского элемента.

Эксперимент

Попробуем сделать адаптивный виджет в виде окружности?


    
    Card
    
    
    
.card {
    height: 300px;
    background-color: #ffffff;
    box-shadow: 0 20px 57px 0 rgba(51, 51, 51, 0.1);
    border: none;
    margin: 4%;
}
.outer-circle {
    width: 100px;
    height: 100px;
    background: linear-gradient(to right, rgba(237, 114, 152, 0.4), rgba(236, 136, 113, 0.4));
    margin: 0 auto;
    border-radius: 50%;
}
.inner-circle {
    width: 90px;
    height: 90px;
    background: linear-gradient(to right, rgb(237, 114, 152), rgb(236, 136, 113));
    padding: 10px;
    margin: 0 auto;
    transform: translateY(6%);
    border-radius: 50%;
}


Что получилось?

Получилось неплохо. Однако, спустя некоторое время Вы заметите, что виджет не изменяет свои размеры относительно родителя - карточки. В данном случае виджет, вообще, не является адаптивным.


Что должно получиться

Виджет внутри карточки должен менять ширину и высоту пропорционально изменениям ширины родителя.

Вы ошибетесь, решив что проблема решается заменой единиц измерения: пикселей на проценты.

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

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


Волшебство

Оказывается, у нас есть “волшебная палочка” - padding

Что произойдет, если Вы уберете свойство height у родительского элемента (карточки) и создадите padding-bottom в процентах?

Нижний внутренний отступ (padding-bottom) пересчитывается пропорционально ширине карточки .col-md-6. Это означает, что свойство карточки padding-bottom ведет себя так же, как и width.

Великолепно! Теперь Вы можете задать высоту и ширину элементов виджета .outer-cirlce и .inner-circle в процентах. Свойство height внешнего круга .outer-circle будет зависеть от padding-bottom родителя (а значит высота будет изменяться пропорционально изменению ширины карточки).

.card {
    background-color: #ffffff;
    box-shadow: 0 20px 57px 0 rgba(51, 51, 51, 0.1);
    border: none;
    padding-bottom: 100%;
}
.outer-circle {
    width: 20%;
    height: 20%;
    background: linear-gradient(to right, rgba(237, 114, 152, 0.4), rgba(236, 136, 113, 0.4));
    margin: 0 auto;
    border-radius: 50%;
    position: absolute;
    left: 40%;
}
.inner-circle {
    width: 90%;
    height: 90%;
    background: linear-gradient(to right, rgb(237, 114, 152), rgb(236, 136, 113));
    border-radius: 50%;
    position: absolute;
    left: 5%;
    top: 5%;
}

В данном случае padding-bottom работает как “виртуальная” высота и следовательно создает действительно адаптивный блок.


Надеюсь эта статья помогла разобраться с магией отступов в CSS.


Спасибо за внимание.

    • frontend
    • css

Новые публикации

Далее

Категории

О нас

Frontend & Backend. Статьи, обзоры, заметки, код, уроки.