Испытание: строим сетку [27/32]. Мое решение на 100% и подробная инструкция.

Прочитав задание становится понятным, что весь код нам придется писать самому. Итак, с чего же начать? Конечно же с HTML-кода. Для начала стоит определится с количеством блоков которые нам нужны.
:point_up_2:Сразу хочу сказать, что я такой же ученик, поэтому мой код, возможно будет не самым коротким или самым идеальным на Ваш взгляд, но это мой код и мой способ. Я с удовольствием выслушаю все пожелания и критику дабы стать лучше.
:man_student:Приступим к решению задачи.
Во-первых я посчитал сколько всего будет контейнеров :package: div. У меня вышло 8 видимых контейнеров для + 1 для бекграунда.
Изначально мой html-код выглядел просто как набор контейнеров идущих друг за другом. Так-же я решил обернуть все названия блоков в тег p, т.к. все они имеют одинаковые внутренние отступы.

<div class="header"><p>Header</p></div>
<div class="menu"><p>Menu</p></div>
<div class="promo-collum"><p>Promo 1</p></div>
<div class="promo-collum"><p>Promo 2</p></div>
<div class="row collum"><p>Left</p></div>
<div class="row collum"><p>Main</p></div>
<div class="row collum"><p>Right</p></div>
<div class="footer"><p>Footer</p></div>

После нужно было создать контейнер (центровщик) с помощью которого я смогу центрировать необходимые мне контейнеры или их содержимое.
Я создал контейнер :package: с классом layout-positioner и добавил класс центровщика в наш хедер. Вот так:

<div class="header layout-positioner"><p>Header</p></div>

Меню у нас растянуто по всей ширине, а его содержимое центрировано. Чтобы добиться такого эффекта поместим наш центровщик внутрь блока меню, тем самым меню у нас останется растянутым на всю ширину, а его содержимое центрируется:

<div class="menu">
   <div class="layout-positioner"><p>Menu</p></div>
</div>

Дальше, у нас 2 промо-колонки, неплохо было бы иметь контроль над ними сразу и конечно же центрировать, а так же для контейнера родителя в котором будут находится зафлоаченые 2 промо-колонки нам понадобится распорка, дополнительно пропишем класс clearfix. Теперь поместим контейнеры промо-колонок внутрь контейнера :package: с классами promo layout-positioner clearfix. Вот так:

<div class="promo layout-positioner clearfix"> - для контроля, центрирования и распорки
    <div class="promo-collum"><p>Promo 1</p></div>
    <div class="promo-collum"><p>Promo 2</p></div>
</div>

Тоже самое сделаем с блоками контента.

<div class="content layout-positioner clearfix"> - для контроля, центрирования и распорки
        <div class="collum"><p>Left</p></div>
        <div class="collum"><p>Main</p></div>
        <div class="collum"><p>Right</p></div>
</div>

Футер у нас тоже растянут по всей ширине, а содержимое центрировано. Делаем по той же схеме, что и меню:

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

Теперь осталось создать контейнер, который послужит нам фоном. Я решил это сделать в самом конце, не знаю почему. Еще раз посмотрев на пример, мы видим, что фоновый контейнер нам нужен для хедера, меню и промо-колонок. Значит эти контейнеры мы и поместим в наш фоновый контейнер.
В итоге имеем вот такой html-код:

<body>
<div class="container">
        <div class="header layout-positioner"><p>Header</p></div>
    <div class="menu">
       <div class="layout-positioner"><p>Menu</p></div>
    </div>
    <div class="promo layout-positioner clearfix">
       <div class="promo-collum"><p>Promo 1</p></div>
       <div class="promo-collum"><p>Promo 2</p></div>
    </div>
</div>
    <div class="content layout-positioner clearfix">
        <div class="collum"><p>Left</p></div>
        <div class="collum"><p>Main</p></div>
        <div class="collum"><p>Right</p></div>
    </div>
    <div class="footer">
        <div class="layout-positioner"><p>Footer</p></div>
    </div>
</body>

Теперь перейдем к CSS:
Для начала зададим стили для нашего центрирующего контейнера:

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

Далее зададим стили для нашего хедера:

.header {
background: #c0392b;
min-height: 35px;
margin-bottom: 10px;
box-sizing: border-box;
}

Поскольку я не большой фанат математических расчетов и движений пикселями, я буду использовать свойство box-sizing: border-box по возможности, чего и Вам советую.

Далее меню:

.menu {
background: #3498DB;
min-height: 35px;
margin-top: 10px;
margin-bottom: 10px;
box-sizing: border-box;

}

Теперь наши промо-колонки:

.promo .promo-collum {
background: #c0392b;
min-height: 60px; - чтобы высота колонки зависела от содержимого, но была не ниже заданой выс.
margin-bottom: 10px;
width: 170px;
float: left;
margin-right: 10px;
box-sizing: border-box;
}

Убираем марджин справа у второй колонки

.promo .promo-collum:last-child {
margin-right: 0;
}

Дальше наш блок с контентом:

.content .collum {
background: #3498DB;
margin-bottom: 10px;
margin-right: 10px;
margin-top: 10px;
width: 70px;
float: left;
min-height: 110px;
box-sizing: border-box;
}

Так увеличиваем размер второй колонки main:

.content .collum:nth-child(2) {
width: 190px;
}

И убираем марджин у последней:

.content .collum:last-child {
margin-right: 0;
}

:point_up_2: Почему я не объясняю каждый шаг, как в предыдущих гайдах? Я считаю, что это уже пройденный материал, который все усвоили.

Теперь стили для распорки:

.clearfix::after {
display: table;
content: “”;
clear: both;
}

Дальше футер:

.footer {
background: #34495e;
min-height: 40px;
box-sizing: border-box;
}

В конце стили для нашего container что служит бекграундом:

.container {
background: #34495e;
box-sizing: border-box;
padding-top: 10px;
}

Осталось задать отступы всем названиям блоков:

p {
margin: 0;
padding: 5px;
}

Фиксированные высоты промо-колонок и блоков контента были заменены на тянущиеся (min-height).

Готово!:checkered_flag: Задание выполнено на 100%. Я уверен можно решить и другими способами, можно решить более грамотно, можно написать еще более короткий код. Возможно я пересмотрю свою решение и сделаю по-другому, но сейчас у меня вышло так.
С радостью выслушаю Ваши советы по улучшению и сокращению кода и количества используемых классов. :slight_smile: Спасибо за внимание.

11 лайков

Эту инструкцию придется переписывать.
Меню и футер также нуждаются в центровщике. Фиксированные высоты у блоков лучше заменить на min-height.
Распорка вешается на каждый родительский контейнер, внутри которого есть float. По этой причине появилась необходимость в clear:both; для футера.
Помните о том, что width: auto для div считается стилем по умолчанию, а значит явная запись не требуется.

Спасибо за советы, буду вносить изменения и делать семантически правильный код:slight_smile:

Добрый день, Практически во всех испытаниях опираюсь на Ваш опыт, сравниваю с вашим решением. теперь вот сделал полностью все сам, но мне кажется у меня много лишнего и чисто логически не правильно, однако 100%, но это типа кубик Рубика разломать и собрать по цветам))

<body>
        <div class="layout-positioner clearfix">
            <div class="header">Header</div>
            <div class="menu">Menu</div>
            <div class="promo1">Promo 1</div>
            <div class="promo2">Promo 2</div>
        </div>
        <div class="layout-white clearfix">
            <div class="left"> Left</div>
            <div class="main"> Main</div>
            <div class="right">Right</div>
        </div>
        <div class="footer">Footer
        </div>
    </body>

html,
body {
    margin: 0;
    padding: 0;
}

body {
    width: 450px;
    height: 335px;
    font-family: "Arial", sans-serif;
    font-size: 10px;
    color: white;
   
}
.layout-positioner {
    width: 450px;
    background-color: #34495e;    
    box-sizing: border-box;
    margin-bottom: 10px;
    padding-top: 5px;
}
.header {
    width: 350px;
    height: 35px;
    background-color: #c0392b;
    padding: 5px;
    margin: 5px auto 10px;
    box-sizing: border-box;
  
}
.menu {
    width: 100%;
    background-color: #3498DB;
    height: 35px;
    padding: 5px 55px;
    box-sizing: border-box;
    margin-bottom: 10px;
    
}
.promo1 {
    width: 170px;
    height: 60px;
    background-color: #c0392b;
    box-sizing: border-box;
    float: left;
    margin-left: 50px;
    padding: 5px;
    margin-bottom: 10px;
    
}
.promo2 {
    width: 170px;
    height: 60px;
    background-color: #c0392b;
    box-sizing: border-box;
    float: left;
    margin-left: 10px;
    padding: 5px;
    margin-bottom: 10px;
}
.clearfix::after {
    content: "";
    display: table;
    clear: both;
}
.left, .main, .right {    
    height: 110px;
    background-color: #3498DB;
    box-sizing: border-box;
    padding: 5px;
    margin-bottom: 10px;
}
.left {
    width: 70px;
    float: left;
    margin-left: 50px;
}
.main {
    width: 190px;
    float: left;
    margin-left: 10px;
}
.right {
    width: 70px;
    float: left;
    margin-left: 10px;
}
.footer {
    width: 100%;
    background-color: #34495e;
    height: 35px;
    padding: 5px 55px;
    box-sizing: border-box;
}
2 лайка

Переделал, проверяйте, критикуйте, советуйте)

Уже лучше, но не всё еще правильно.

  1. Отдельный плюс за обертку для текста. Единственное, лучше для этих целей подобрать элемент, являющийся блочным по умолчанию. Как насчет тега параграфа <p> или заголовков, например <h2>? Отступы нужно задавать с каждой стороны, а не только сверху и слева.
  1. Отдельный минус за оставшиеся height и clear: both; у футера.

Действительно для оберток текста пединг можно задать общий в 5px.
Заменил span на p, возможно лучше и на h2.
Про футер немного не понял. Поскольку я задал распорки родителям флоатнутых элементов, то необходимость в clear: both; для футера отпала? И почему от height нужно избавиться, или просто заменить на min-height?

Да, именно так.
height нужно заменить на min-height везде. А в идеале высоту не прописывают сеточным блокам вообще, она зависит от содержимого и отступов. Только по этому заданию высота необходима, так как блоки пустые.

Хорошо, спасибо за советы) теперь моя инструкция гораздо лучше.

У меня пока несросты конечно, но объясните почему через флоат решаем задачу? Не через inline-block например? Я колонкам его прописал и они нормально разместились.

1 лайк

Потому, что inline-block изучается дальше)

У вас с моей точки зрения удачно получается html код. Во всяком случае пока его не увидел - путался, div в div-ах… Взял его за основу - стало все гораздо понятней и CSS я уже сам быстро написал :).
Что я сделал не так.
Т.к. в CSS колонки все-равно специфицируются обрамляющим блоком - нет нужды отдельно выделять .promo-collum. Делаем один класс column. Ну и box-sizing: border-box; во многих случаях просто лишний, и мне без него проще.
PS: не получилось почему то сюда вставить нормально код. Мое решение можно посмотреть тут: https://jsfiddle.net/seaman/8rn161xw/

Решить задачу можно несколькими способами. Но я стараюсь не просто решить задачу самым простым способом и получить 100%, я стараюсь решить таким образом, как если бы это был реальный сайт, где нужно иметь контроль над блоком элементов и над каждым элементом по-отдельности. Когда попробуете сверстать реальный проект, а у вас элементы не захотят влезать в сетку, захотите верстать pixel-perfect, тогда поймете, что box-sizing: border-box; очень даже не лишний)

Обязательно ли прописывать дополнительный тег распорки .clearfix?
Я просто задал распорку для

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

и у меня все корректно отображается при таком написании:

<div class="promo layout-positioner"></div>

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

Зачем использовать .promo .promo-column если можно просто .promo-column, ведь больше нет классов с такими же именами?

Почему у блоков уже есть расстояние между ними(нигде маржин не прописан вообще но расстояние есть) и зачем прописывать margin тогда? Я попробовала убрать маржины и расстояние как было 10px между блоками так и осталось. Вопрос: почему?
Если задать margin больше, то расстрояние увеличится, но если не задавать, то уже 10px есть.

Еще попробовала задать margin-bottom: 50px хедеру и margin-top:50px меню. Так и должно быть что они не складываются? Маржины никогда не складываются?

Здравствуйте, спасибо за такое хорошее объяснение, очень помогает.:blush:

Хотел спросить можно ли использовать в начале такой стиль:

* {
box-sizing: border-box;
}

вместо того чтобы в каждом классе писать данное присвоение.

Дуже дякую.

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

Помогайте, 98.2%

<!DOCTYPE html>
<html lang="ru">
  <head>
    <title>Испытание: строим сетку</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
  <div class="container-with-header-menu-bothPromo">
    <div class="layout-positioner Header">
      <p>Header</p>
    </div>
    <div class="Menu">      
      <p class="layout-positioner">Menu</p>
    </div> 
    <div class="layout-positioner">
      <p class="column-for-promo column-1">Promo 1</p>
      <p class="column-for-promo column-2">Promo 2</p>
    </div>
  </div>
  <div class="container-content">
    <div class="layout-positioner">
      <p class="Left">Left</p>
      <p class="Main">Main</p>
      <p class="Right">Right</p>
    </div>  
  </div>
  <div class="Footer"> 
      <p class="layout-positioner">Footer</p>
  </div>
    
  </body>
</html>

html,
body {
  margin: 0;
  padding: 0;
}

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

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

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

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

.container-with-header-menu-bothPromo {
  background-color:#34495e;
  padding-top:10px;
  }

.Header {
  height:25px;
  background-color:#c0392b;
  margin-bottom:10px;  
  padding-top:10px;
     }

.Menu {
  height:25px;
  background-color:#3498db;
  padding:5px 55px;
  }

.column-for-promo {
  width:160px;
  height:50px;
}

.column-1 {
    float:left;
    background-color:#c0392b;
    padding:5px 5px;   
    }

.column-2 {
  float:right;
  background-color:#c0392b;
  padding:5px 5px;
  }


.Left {
  float:left;
  width:60px;
  height:100px;
  background-color:#3498db;
  margin-right:10px;
  padding:5px 5px;
}

.Main {
  float:left;
  width:180px;
  height:100px;
  background-color:#3498db;
  margin-right:10px;
  padding:5px 5px;
}

.Right {
  float:left;
  width:60px;
  height:100px;
  background-color:#3498db;
  padding:5px 5px;
 }

.container-content:last-child {
  margin-right:0px;
}

.Footer {
  background-color:#34495e;
  width:100%;
  height:35px;
  padding:5px 5px;
  
  }