Понимание grid placement через создание периодической таблицы HTML
Coding
Я уже давно использую сетку CSS для создания макетов, и все мои проекты на сегодняшний день включали либо несколько явно размещенных отдельных элементов сетки, либо 100% автоматическое размещение.
Раньше мне не приходилось проектировать промежутки между сеткой, но в один прекрасный мартовский день я обнаружил периодическую таблицу HTML на WebsiteSetupOrg.
Теперь он выглядит иначе, чем когда я впервые увидел его, потому что версия, которую я видел, прописано html, и я был полностью увлечен этим.
После моей обычной проверки правой кнопкой мыши, я заметил, что макет не использует сетку, но мой мозг, наполненный Grid, думал, что может здать дизайн используя макет Grid.
Grid manual placement
Одна из лучших частей использования Grid для макета - это возможность размещать элементы сетки именно там, где вы хотите, в созданной вами сетке. Большая часть планирования для таких проектов будет идти в самой сети.
Но в качестве краткого обзора того, как это работает, давайте рассмотрим относительно простую сетку 3х3 с 3 элементами сетки.
Инспектор сетки Firefox включен, поэтому мы знаем, каким линиям назначать наши части.

Вот как выглядит код сетки:
.grid {
display: grid;
grid-template-columns: repeat(3, 24vmin);
grid-template-rows: repeat(3, 24vmin);
}
.grid__item:first-child {
grid-row: 3;
}
.grid__item:nth-child(2) {
grid-row: 2;
grid-column: 2;
}
.grid__item:nth-child(3) {
grid-row: 3;
grid-column: 3;
}
grid-row и grid-column являются сокращениями, чтобы установить начальную и конечную линию их соответствующих размеров.
Элементы сетки по умолчанию будут занимать только одну ячейку сетки, поэтому она работает нормально, хотя я указываю только начальную строку без конечной строки для любого свойства.
Концепция ручного размещения элементов сетки заключается в том, что вы можете расположить свой элемент в сетке на основе номеров строк и столбцов. Нет необходимости в слишком сложных правилах позиционирования и вычислениях.
Grid automatic placement
Если у нас есть большое количество элементов сетки, и мы не хотим явно размещать их все,вот 5-шаговый алгоритм, который браузеры используют для определения того, как размещать элементы сетки, для которых не определено явное положение сетки.
Предположим, что направление потока это row для следующего объяснения.
Шаг 0: создание анонимных элементов сетки
Если выполняется какая-либо непрерывная последовательность дочерних текстов, что означает набор текста без каких-либо тегов вокруг них, браузер обернет его в элемент сетки контейнера анонимного блока.
Давайте немного поговорим об анонимных вещах здесь. Все на веб-странице коробка. Существует много разных типов коробок, но коробка все еще является коробкой. Поэтому, если у вас есть какие-то вещи, которые не связаны с каким-либо элементом, например, фрагмент текста, браузер сгенерирует для них анонимные блоки.
Из спецификации сказано:
При определенных обстоятельствах анонимные блоки создаются для исправления дерева блоков, когда для этого требуется определенная вложенная структура, которая не предоставляется блоками, созданными из дерева элементов.
Ниже приведен пример элемента p блок, содержащего анонимный текст с добавлением em и strong:

Браузер установит элемент p как содержащий блок для 5 встроенных блоков, 3 из которых являются анонимными.
Шаг 1: Поместите все, что не позиционируется автоматически.
Шаг 2: Обработка элементов, привязанных к данному ROW.
Для каждого элемента сетки с явным значением grid-row-start и grid-row-end помещает элемент в самую раннюю строку начала столбца, которая:
Не вызывает совпадение с какими-либо занятыми ячейками сетки и проходит мимо предыдущего элемента сетки, размещенного таким образом.
Если упаковка установлена на dense, игнорируйте второое правило.
Немного про dense
Ключевое слово, указывающее, что алгоритм автоматического размещения использует «плотный» алгоритм упаковки, который пытается заполнить отверстия ранее в сетке,если мелкие предметы появятся позже.
Это может привести к тому, что элементы будут отображаться не в порядке, при этом будут заполнены отверстия, оставленные более крупными элементами.
Если он опущен, используется «sparse» алгоритм где алгоритм размещения только перемещается «вперед» в сетке при размещении предметов.
Это гарантирует, что все автоматически размещаемые элементы отображаются «по порядку», даже если это оставляет дыры, которые могли быть заполнены более поздними элементами.
Шаг 3: Определите столбцы в неявной сетке.
Чтобы создать столбцы неявной сетки, браузер начнет с явных столбцов сетки. Затем для всех элементов с определенной позицией столбца добавьте неявные столбцы в начало и конец неявной сетки, чтобы разместить их.

В приведенном выше примере это явная сетка 4x3, но .rogue был помещен в столбец сетки 8, что привело к генерации еще 4 неявных столбцов после явной сетки.
Если наибольший диапазон столбцов среди всех элементов без определенной позиции столбца превышает число столбцов неявной сетки, добавьте дополнительные столбцы в конец для размещения этого диапазона столбцов.

Шаг 4: Разместите остальные предметы.
Есть нечто, называемое auto-placement cursor которого мы не видим, но он определяет текущий он определяет текущую «точку вставки» в сетке. Эта точка указана в виде пары строк сетки и столбцов.
Если после выполнения предыдущих шагов остались какие-либо элементы, существует 4 возможных сценария, которые повлияют на размещение этих оставшихся элементов.
Когда сетка имеет значение по умолчанию sparse, и элемент сетки имеет определенную позицию столбца:
- Установите позицию столбца курсора в это начальное значение столбца.Если это меньше предыдущей позиции курсора в столбце, увеличьте позицию строки на 1.
- Увеличивайте положение строки курсора до тех пор, пока элемент сетки не перекрывает какие-либо занятые ячейки сетки, создавая неявные строки по мере необходимости.
- Установите начальное значение строки элемента сетки равным положению строки курсора и конечному значению строки на основе его диапазона от начального значения строки.
Когда сетка является значением по умолчанию sparse и элемент сетки автоматически позиционируется на любой оси:
- Увеличивайте положение столбца курсора, пока элемент сетки не перекрывает какие-либо занятые ячейки сетки, или пока позиция столбца курсора плюс диапазон элементов сетки не переполнят неявные столбцы, сгенерированные на шаге 3
- Как только найдена подходящая позиция столбца курсора, установите начало строки и начало столбца элемента сетки в положение курсора. В противном случае увеличьте положение строки курсора, создавая неявные строки по мере необходимости, и установите для позиции столбца курсора самый начальный столбец в неявной сетке.
Когда сетка является значением по умолчанию dense и элемент сетки имеет определенную позицию столбца:
- Установите позицию столбца курсора в это начальное значение столбца. Установите позицию строки курсора в самой начальной строке в неявной сетке.
- Увеличивайте положение строки курсора до тех пор, пока элемент сетки не перекрывает какие-либо занятые ячейки сетки, создавая неявные строки по мере необходимости.
- Установите начальное значение строки элемента сетки на позицию строки курсора.
Когда сетка является значением по умолчанию dense и элемент сетки автоматически позиционируется на любой оси:
- Установите строку курсора и положение столбца для самой начальной строки строки и столбца неявной сетки.
- Увеличивайте позицию столбца курсора до тех пор, пока элемент сетки не перекрывает занятые ячейки или пока позиция столбца курсора плюс диапазон элемента сетки не переполняет неявные столбцы, сгенерированные на шаге 3.
- Как только найдена подходящая позиция столбца курсора, установите начало строки и начало столбца элемента сетки в положение курсора. В противном случае увеличьте положение строки курсора, создавая неявные строки по мере необходимости, и установите для позиции столбца курсора самый начальный столбец в неявной сетке.
Построение макета
Целевой дизайн, который я имел в виду, выглядел следующим образом при нанесении на сетку 20x10:

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

Ты знаешь что это значит? Больше колонок, вот что. Это часть этапа проектирования, которую я называю планированием сетки(англ.grid planning).
Для чего-то подобного вы можете пойти по аналогу (как мне нравится) или импортировать изображение в любую программу, которая позволяет рисовать линии над ним.
Оттуда вы можете вычислить наименьшее возможное количество строк и столбцов, с которыми можете справиться, при этом все ваши элементы сетки будут выровнены по линии сетки.
Так что 40х10 это так.
Построение сетки
Не может быть сетки элементов без некоторой разметки. Для этого вы можете выбрать разметку строки или столбца, вы можете повлиять на направление расположения элементов сетки с помощью свойства grid-auto-flow. Я собираюсь пойти с умолчанию строки. Таким образом, разметка принимает порядок слева направо, сверху вниз.
Теперь давайте создадим сетку из 40 столбцов и 10 строк.
.elements {
display: grid;
grid-template-columns: repeat(40, 5ch);
grid-template-rows: repeat(10, auto);
}
Расположение элементов
Мы также хотим, чтобы каждый элемент сетки охватывал 2 горизонтальных ячейки сетки.
.element {
grid-column: span 2;
}
Теперь настало время, когда диаграмма пригодится, потому что вы можете определить, какие столбцы вы хотите «протолкнуть» остальным элементам сетки в строке, чтобы воссоздать буквы, HTML, в сетке.

В дизайне 5 «полных столбцов» элементов сетки.Вместо того, чтобы строить каждый элемент сетки, мы можем использовать наше новое понимание автоматического размещения, чтобы «вытолкнуть» необходимый пробел между элементами сетки с классами CSS. Затем для более конкретных позиций мы можем просто нацелить их на определенные классы.
.col5 { grid-column: 9 / span 2 }
.col8 { grid-column: 15 / span 2 }
.col11 { grid-column: 21 / span 2 }
.col15 { grid-column: 29 / span 2 }
.col20 { grid-column: 39 / span 2 }
.h1 { grid-column: 27 / span 2 }
.h4 { grid-column: 24 / span 2 }
.h3 { grid-column: 25 / span 2 }
.html { grid-column: 20 / span 2 }
Если бы я установил grid-auto-flow значение dense тогда алгоритм автоматического размещения упаковал бы элементы сетки без явных позиций столбцов сетки в пространства, и мы получили бы что-то вроде этого:

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

После некоторого изменения размера окна, я обнаружил, что дизайн деформировался на ширине ниже 1280 пикселей, что послужило основой для медиа-запроса минимальной ширины.
Позиционированные элементы сетки включаются только тогда, когда ширина области просмотра превышает 1280 пикселей в ширину.
При меньшем значении все элементы автоматически размещаются по алгоритму, поэтому он выглядит как стандартная сетка элементов HTML.
В этом случае мне не нужно было фиксировать количество столбцов в сетке. Вместо этого я позволил браузеру выяснить это с помощью auto-fit
Чтобы убедиться, что у меня не было никаких причудливых пробелов по краям сетки, я сделал ширину столбца в диапазоне между 10ch и 1fr ,поэтому элементы всегда занимают всю ширину области просмотра независимо от того, как изменился размер.
.elements {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(10ch, 1fr));
gap: 0.2em;
a {
padding: 1em 0;
}
}

И затем, браузеры, которые не поддерживают Grid.
Я решил вернуться к гибкому макету, но вы также можете использовать плавающие или встроенные блоки, если хотите. Суть вопроса здесь заключается в запросе функции.
Весь код, связанный с сеткой, помещается в функциональный запрос следующим образом, включая медиа-запрос:
@supports (display: grid) {
.elements {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(10ch, 1fr));
gap: 0.2em;
a {
padding: 1em 0;
}
}
@media screen and (min-width: 1280px) {
.elements {
grid-template-columns: repeat(40, 5ch);
grid-template-rows: repeat(10, auto);
a {
grid-column: span 2;
margin: 0;
}
}
a.col5 { grid-column: 9 / span 2 }
a.col8 { grid-column: 15 / span 2 }
a.col11 { grid-column: 21 / span 2 }
a.col15 { grid-column: 29 / span 2 }
a.col20 { grid-column: 39 / span 2 }
a.h1 { grid-column: 27 / span 2 }
a.h4 { grid-column: 24 / span 2 }
a.h3 { grid-column: 25 / span 2 }
a.html { grid-column: 20 / span 2 }
}
}
Базовые стили, которые находятся за пределами функционального запроса, позаботятся о браузерах, которые не поддерживают Grid. И если вы хотите проверить, как это выглядит, закомментируйте весь блок запросов объектов.
.elements {
font-family: 'Medula One', serif;
display: flex;
flex-wrap: wrap;
justify-content: center;
a {
padding: 1em;
flex: none;
margin: 0.25em;
}
}
Для браузеров, которые не поддерживают запросы функций, это, по сути, так и происходит, потому что браузер игнорирует весь блок в запросе функций.

Посыпать Javascript на код
Хорошо, здесь я хочу отдать должное Майку Ритмюллеру, который также создал действительно хорошую версию периодической таблицы HTML. Это намного красивее, чем у меня, плюс, он имеет функцию определения.

Была также легенда, поскольку элементы были классифицированы в несколько категорий. Когда вы наведете курсор на название категории, соответствующие элементы также будут выделены. Очень хорошо, и я хотел сделать то же самое для моей периодической таблицы тоже.
Отображение определений не было слишком сложным. В нем использовался псевдокласс: target, поэтому при нажатии на любой из элементов в таблице его определение будет отображаться под таблицей. Необходимо сопоставить ссылку привязки элемента с идентификатором элемента, содержащего его определение, чтобы фрагмент URL соответствовал.
Возьмите эту разметку, например:
<a href="#ruby" class="txt-lvl">ruby</a> <div id="ruby"> <dt><a href="https://developer.mozilla.org/en/docs/Web/HTML/Element/ruby"><ruby></a></dt> <dd> <p>The HTML <code><ruby></code> Element represents a ruby annotation. Ruby annotations are for showing pronunciation of East Asian characters.</p> <p><a class="moz-link" href="https://developer.mozilla.org/en/docs/Web/HTML/Element/ruby">https://developer.mozilla.org/en/docs/Web/HTML/Element/ruby</a></p> </dd> </div>
Вы бы заставили его работать со следующим CSS:
div {
padding: 1em;
text-align: left;
display: none;
}
div:target {
display: block;
}
Бит Javascript входит для функции выделения при наведении курсора. И что он делает, так это добавляет класс CSS к элементу body, чтобы соответствующие элементы в выбранной категории получали изменение цвета фона.
Array.prototype.forEach.call(document.querySelectorAll('.legend li'), li => {
li.addEventListener('mouseenter', function() {
document.body.classList.add('hover-' + this.className)
}, false)
li.addEventListener('mouseleave', function() {
document.body.classList.remove('hover-' + this.className)
}, false)
})
У меня было 11 категорий, поэтому я обманул и использовал Sass для генерации CSS, необходимого для этого:
$colours: (
root: #7b9de1,
scripting: #749eef,
int-elem: #5186ed,
meta: #2b6dec,
edits: #155eea,
tab-data: #024ee0,
grp-cont: #0242bc,
emb-cont: #00369c,
forms: #0202ca,
sections: #000080,
txt-lvl: #010151
);
@each $class, $colour in $colours {
.#{$class} {
background-color: #{$colour};
color: white;
}
.hover-#{$class} {
.#{$class} {
background-color: #fdb35f;
color: black;
}
}
}
Завершение
И это в значительной степени так. Это закончилось более длинным сообщением, чем я ожидал, но я надеюсь, что это пролило некоторый свет на некоторые методы CSS, используемые для реализации этой периодической таблицы HTML. Если вы хотите сами покопаться в коде и настроить его, вот CodePen