Испытание: строим сетку [27/32]. Мои 100%, ход мыслей, код-ревью

Всем привет. Задание сделал, хочу по порядку разобрать каждый кусок кода, возможно кому-то поможет. И есть несколько вопрос, плюс, надеюсь, укажут на ошибки.

Для начала - полный код задания от меня.

HTML
<body>
        <div class="header-container">
            <div class="layout-positioner">
                <div class="header">
                    Header
                </div>
            </div>
            <div class="menu-container">
                <div class="layout-positioner">
                    <div class="menu">
                        Menu
                    </div>
                </div>
            </div>
            <div class="layout-positioner">
                <div class="promo promo1">Promo 1</div>
                <div class="promo">Promo 2</div>
            </div>
        </div>
        <div class="layout-positioner">
            <div class="left">Left</div>
            <div class="main">Main</div>
            <div class="right">Right</div>
        </div>
        <div class="footer-container">
            <div class="layout-positioner">
                <div class="footer">
                    Footer
                </div>
            </div>
        </div>
</body>
CSS
html,
body {
    margin: 0;
    padding: 0;
}

body {
    width: 450px;
    height: 335px;
    font-family: "Arial", sans-serif;
    font-size: 10px;
    color: white;
}

.layout-positioner {
    width: 350px;
    margin: 0 auto;
}

.layout-positioner::after {
    display: table;
    content: "";
    clear: both;
}

.header-container {
    min-height: 150px;
    background: #34495e;
    padding-top: 10px;
}

.header {
    background: #c0392b;
    min-height: 25px;
    padding: 5px;
    margin-bottom: 10px;
}

.menu-container {
    background: #3498DB;
}

.menu {
    padding: 5px;
    min-height: 25px;
}

.promo {
    background: #c0392b;
    padding: 5px;
    float: left;
    width: 160px;
    min-height: 50px;
    margin: 10px 0;
}

.promo1 {
    margin-right: 10px;
}

.left,
.main,
.right {
    background: #3498DB;
    float: left;
    padding: 5px;
    margin: 10px 0;
    min-height: 100px;
}

.left,
.right {
    width: 60px;
}

.left {
    margin-right: 10px;
}

.main {
    width: 180px;
    margin-right: 10px;
}

.footer-container {
    background: #34495e;
}

.footer {
    padding: 5px;
    min-height: 30px;
}

/*
    Используемые цвета:
    #34495e – мокрый асфальт
    #c0392b – красный
    #3498DB – синий
*/

Если посмотрим на “макет”, то его условно можно разделить на 3 части. Хедер(с тёмным фоном), основной контент( с 3 блоками), и футер.
Исходя из этого для начала нам нужен общий блок хедера, внутри которого пишем ещё 4 - хедер(с красным фоном), меню, и два промо блока.

      <div class="header-container">
            <div class="header">
                Header
            </div>
            <div class="menu">
                Menu
            </div>
            <div class="promo">Promo 1</div>
            <div class="promo">Promo 2</div>
        </div>

Меню у нас растянуто на всю ширину родительского блока, у него однородный светло-синий фон, и только содержимое выравнивается по центру. Поэтому, я решаю обернуть класс menu в див с классом menu-container, которому позже мы зададим цвет.
Важный момент - не забыть про класс layout-positioner, который выравнивает обёрнутые в него блоки по горизонтали.
По порядку оборачиваем header в layout-positioner, menu-container пропускаем, но класс menu - оборачиваем также в layout-positioner, и дальше два дива с классом promo. Получается следующая картина:

<div class="header-container">
            <div class="layout-positioner">
                <div class="header">
                    Header
                </div>
            </div>
            <div class="menu-container">
                <div class="layout-positioner">
                    <div class="menu">
                        Menu
                    </div>
                </div>
            </div>
            <div class="layout-positioner">
                <div class="promo">Promo 1</div>
                <div class="promo">Promo 2</div>
            </div>
        </div>

Начинаем писать CSS-код. Первым делом пишем сами(лучше так), или копируем из предыдущих заданий класс layout-positioner и дальше псевдораспорку layoute-positioner::after:

.layout-positioner {
    width: 350px;
    margin: 0 auto;
}

.layout-positioner::after {
    display: table;
    content: "";
    clear: both;
}

Ширину подбирал на глаз. Получается, что центровщик на 100рх меньше, чем сам body. Маргин, собственно, и центрует содержимое по горизонтали.
Далее, нужно задать фон и минимальную высоту общему хедеру(header-container):

.header-container {
    min-height: 150px;
    background: #34495e;
}

Оформляем хедер(с красным фоном): задаём фон, минимальную высоту, внутренний отступ в 5 пикселей(к слову, у всех блоков), и внешний отступ снизу, чтобы было расстояние между хедером и меню.

.header {
    background: #c0392b;
    min-height: 25px;
    padding: 5px;
    margin-bottom: 10px;
}

Благодаря центровщику, блок расположен ровно по центру. Осталось сделать отступ хедера с красным фоном сверху от родительского хедера. Нужно покрепче вбить себе в голову момент с выпаданием из родителя. Если задаём вложенному блоку внешний отступ, то он прижмётся к родителю, и отступ будет уже от края браузера. Поэтому маргин внутреннему хедеру в данном случае задавать не нужно. Выходов два - задать границу(рамку) родителю или же задать родителю паддинг. Рамки в макете нет - добавляем классу header-container свойство padding-top: 10px;

.header-container {
    min-height: 150px;
    background: #34495e;
    padding-top: 10px;
}

Приступаем к оформлению меню. Родителю - menu-container задаём цвет фона:

.menu-container {
    background: #3498DB;
}

Далее у нас идёт центровщик, и внутри класс menu. Ему, как и всем другим блокам, нужно задать паддинг в 5 пикселей, и минимальную высоту - 25 пикселей.

.menu {
    padding: 5px;
    min-height: 25px;
}

Приступаем к оформлению двух промо-блоков. Чтобы их было более-менее хорошо видно визуально, зададим им красный цвет фона, флоат, чтобы расположить два блока по горизонтали, и минимальную высоту - 50рх. Нам нужно вычислить ширину блоков. Между блоками есть расстояние, примерно 10рх. После того, как зададим паддинги 5рх, ширина каждого промо-блока увеличится на 10рх. Ширина центровщика 350рх. Отнимем от 350рх маргин 10рх, и два паддинга по 10рх, получим 350 - 30 = 320рх. У нас два промо-блока, значит каждый из них шириной 160рх. Также, нам нужно добавить два внешних отступа - сверху от меню и снизу от края родительского блока. Получаем следующий код:

.promo {
    float: left;
    background: #c0392b;
    min-height: 50px;
    padding: 5px;
    width: 160px;
    margin: 10px 0;
}

После этого блоки будут нужных размеров, но слипнутся, поскольку нам нужно задать внешний отступ у первого промо блока. Я решил это сделать, добавив первому блоку класс promo1. И прописав ему нужное CSS правило.

.promo1 {
    margin-right: 10px;
}

Хедер готов. Приступаем к основному контенту. У нас есть три блока - left, main и right. Они расположены по центру родительского блока, а значит нужно обернуть их в layout-positioner.

<div class="layout-positioner">
    <div class="left">Left</div>
    <div class="main">Main</div>
    <div class="right">Right</div>
</div>

Для начала выделим общие для всех блоков правила - фон, флоат, минимальную высоту 100рх, паддинг 5рх, а также зададим маргин сверху от хедера, и снизу от футера.

.left,
.main,
.right {
    background: #3498DB;
    float: left;
    min-height: 100px;
    padding: 5px;
    margin: 10px 0;
}

Блоки слиплись, поэтому нужно отделить их друг от друга. Начнём с левого блока:

.left {
    margin-right: 10px;
}

Теперь зададим ширину и внешний правый маргин для центрального блока:

.main {
    width: 180px;
    margin-right: 10px;
}

Левый и правый блок у нас имеют одинаковой ширину. Прописываем свойства:

.left,
.right {
    width: 60px;
}

На глаз определить ширину блоков не получается, но если выяснить ширину левого блока, то вычислить ширину оставшихся блоков не составит труда. Напомню, ширина центровщика - 350рх. Ширина левого блока = 60рх + паддинги 10рх = 70рх. Такая же ширина правого блока. Получается 70рх+70рх=140рх. У левого и центрального блока есть маргин справа 10рх. Получается 140рх+10рх+10рх=160рх. 350-160=190рх. Вспоминаем, что паддинги добавляют и центральному блоку 10рх, значит его ширина будет 190-10=180рх.

Остаётся только футер. Здесь точно такая же ситуация, как и с меню. Нам нужен будет див с классом footer-container, которому мы зададим цвет фона(мокрый асфальт), внутри которого будет центровщик, внутри которого будет наш див с классом footer.

<div class="footer-container">
    <div class="layout-positioner">
        <div class="footer">
            Footer
        </div>
    </div>
</div>

Классу footer-container задаём цвет фона:

.footer-container {
    background: #34495e;
}

Далее, самому футеру задаём отступы и минимальную высоту:

.footer {
    padding: 5px;
    min-height: 30px;
}

Задание выполнено. Можно передохнуть и выпить чай с печенькой.
Если есть ошибки или более оптимальные варианты - пожалуйста, укажите на них.
И пара моментов. Я маргин справа первому блоку промо задал через второй класс promo1. Наверное, можно было сделать это и через first-child или nth-child, но если мы будет добавлять блоки или менять их местами, отступ будет уже у другого блока. Правильно ли это или не очень?
И второй момент - видел, что часто в заданиях советуют задавать именно минимальную высоту или ширину. Чем это обусловлено? Тем, что фиксированное что либо - плохая практика? Может быть есть хорошая статья на эту тему?
Третий момент. Есть иерархия menu-container > layout-positioner > menu, и то же самое с футером. Почему, если задавать минимальную высоту menu-container, а не menu - то блок становится по высоте ниже? Почему он не остаётся такой же высоту. Никак не въеду в это.

Ну и, написать и оформить это всё оказалось раз в 10 длиннее, чем это было у меня в голове, в мыслях, поэтому, надеюсь, что не напрасно и кому-то поможет.

3 лайка