Какова структура веб-страницы? Какую раскладку вы обычно используете?

CSS

Автор|Ляо Вэйхуа (Большой тапир)

Редактор | Orange Jun

Произведено | Alibaba New Retail Tao Technology

Поскольку веб-технологии продолжают развиваться, CSS в последние годы также стал более мощным, чем несколько лет назад. CSS — неотъемлемая часть веб-разработки, и многие веб-разработчики не знают многих свойств CSS или знают, но забывают использовать наиболее подходящие свойства CSS в самый подходящий момент. И по сей день существуют некоторые свойства CSS, которые позволяют разработчикам экономить еще больше времени. Например, в веб-верстке современные функции CSS могут лучше помочь нам быстро достичь таких результатов, как разметка равной высоты, центрирование по горизонтали и вертикали, классическая компоновка Holy Grail, соотношение сторон, нижний колонтитул внизу и т. д. В этой статье я расскажу о некоторых различных свойствах CSS для достижения этих эффектов, надеюсь, вам будет интересно. Я надеюсь, что это поможет вам в вашей будущей работе.

Центрируется по горизонтали и вертикали

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

Горизонтальное и вертикальное центрирование во Flexbox

В модуле компоновки Flexbox, будь то одна строка или несколько строк, их легко центрировать по горизонтали и вертикали в контейнере, и есть много способов сделать это. Наиболее распространенным является установка выравнивания для flex-контейнеров и margin:auto для flex-элементов.

Давайте сначала рассмотрим настройку выравнивания для гибкого контейнера.

Установите выравнивание для flex-контейнеров и flex-элементов

Возможно, вы уже знаете, что когда значение justify-content и align-items установлено в центр контейнера flex, элемент может быть центрирован по горизонтали и вертикали в контейнере flex. Давайте посмотрим пример:

<!-- HTML -->
<div class="flex__container">
    <div class="flex__item"></div>
</div>

/* CSS */
.flex__container {
    display: flex;
    justify-content: center;
    align-items: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Этот метод особенно подходит для центрирования значка Icon по горизонтали и вертикали в контейнере.Разница в том, что display: inline-flex отображается в контейнере значка Icon. Например следующий пример:

<!-- HTML -->
<div class="flex__container">
    <svg> </svg>
</div>

/* CSS */
.flex__container {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

В этом режиме, если вы хотите центрировать несколько элементов по горизонтали и вертикали, вам нужно добавить столбец flex-direction:, например:

<!-- HTML -->
<div class="flex__container">
    <div class="avatar">:)</div>
    <div class="media__heading"></div>
    <div class="media__content"></div>
    <div class="action"></div>
</div>

/* CSS */
.flex__container  {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

В макете flexbox вы также можете центрировать flex-элементы по горизонтали и вертикали в flex-контейнере следующим образом:

<!-- HTML -->
<div class="flex__container">
    <div class="flex__item"></div>
</div>

/* CSS */
.flex__container {
    display: flex; // 或inline-flex
    justify-content: center;
}

.flex__item {
    align-self: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Этот метод также работает, если во flex-контейнере есть несколько flex-элементов:

.flex__container {
    display: flex; // 或inline-flex
    justify-content: center;
}

.flex__container > * {
    align-self: center;
}

Например, следующие эффекты:

Demo(код спрей.IO/love/embed…)

Кроме того, вы можете использовать place-content: center для центрирования элементов Flex по горизонтали и вертикали:

.flex__container {
    display: flex;
    place-content: center;
}

.flex__item {
    align-self: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Или заменить:

.flex__container {
    display: flex;
    place-content: center;
    place-items: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Есть два способа применить один и тот же сценарий к нескольким проектам Flex в контейнере Flex:

.flex__container {
    display: flex;
    flex-direction: column;
    place-content: center;
}

.flex__container > * {
    align-self: center;
}

// 或

.flex__container {
    display: flex;
    flex-direction: column;
    place-content: center;
    place-items: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Многие учащиеся могут быть незнакомы с содержанием места и предметами места. На самом деле, place-content — это сокращенный атрибут для align-content и justify-content, а place-items — это сокращенный атрибут для align-items и justify-items. который:

.flex__container {
    place-content: center;
    place-items: center;
}

равно:

.flex__container {
    align-content: center;
    justify-content: center;

    align-items: center;
    justify-items: center;
}

Хотя он расширен до четырех свойств, в конечном итоге он эквивалентен:

.flex__container {
    display: flex;
    align-items: center;
    justify-content: center;
}

// 多行
.flex__container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

Установить на гибкий элементmargin: auto

Если во flex-контейнере есть только один flex-элемент, вы также можете явно установить значение поля на auto в flex-элементе, чтобы flex-элемент можно было центрировать по горизонтали и вертикали в flex-контейнере. Например:

.flex__container {
    display: flex; // 或 inline-flex
}

.flex__item {
    margin: auto;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

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

Demo(код спрей.IO/love/embed…

Горизонтальное и вертикальное центрирование в сетке

Макет CSS Grid, возможно, является серебряной пулей в современных веб-макетах. Кроме того, пока это единственная двумерная система компоновки в системе компоновки.

В макете CSS Grid всего несколько строк кода могут быстро помочь нам добиться эффекта горизонтального и вертикального центрирования. Например следующий пример:

<!-- HTML -->
<div class="grid__container">
    <div class="grid__item"></div>
</div>

/* CSS */
.grid {
    display: grid; // 或 inline-grid
    place-items: center
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

В модуле компоновки CSS Grid, если явным образом установлено отображение: сетка (или встроенная сетка), создаются контейнер сетки и элементы сетки, а линии сетки, а именно строки и столбцы, генерируются автоматически (по умолчанию — одна строка и один столбец).

Без явной настройки grid-template-columns и grid-template-rows в контейнере Grid браузер по умолчанию будет использовать для контейнера Grid размер содержимого Grid:

Этот подход также работает для контейнеров CSS Grid с несколькими дочерними элементами (элементами сетки), такими как:

<!-- HTML -->
<div class="grid__container">
    <div class="avatar">:)</div>
    <div class="media__heading"></div>
    <div class="media__content"></div>
    <div class="action"></div>
</div>

В это время эффект, который вы видите, выглядит следующим образом:

Demo(код спрей.IO/love/embed…)

而且palce-items适用于每个单元格。这意味着它将居中单元格的内容。 Например следующий пример:

<!-- HTML -->
<div class="grid__container">
    <div class="grid__item">
        <h3>Special title treatment</h3>
        <p>With supporting text below as a natural lead-in to additional content.</p>
        <div class="action">Go somewhere</div>
    </div>
</div>

/* CSS */
.grid__container {
    display: grid;
    place-items: center;
    grid-template-columns: repeat(2, 1fr);
    gap: 2vh;
}


.grid__item {
    display: grid;
    place-items: center;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Равновысокая компоновка

Макет с равной высотой также является очень распространенным методом компоновки в Интернете, и существует множество решений для достижения макета с одинаковой высотой. Здесь мы в основном рассматриваем изменения, внесенные в модуль макета Flexbox и модуль макета Grid.

В модулях макетов Flexbox и Grid нам очень просто реализовать макеты равной высоты, такие как:

<!-- Flexbox -->
<flex__container>
    <flex__item></flex__item>
    <flex__item></flex__item>
    <flex__item></flex__item>
</flex__container>

/* CSS */
.flex__container {
    display: flex; // 或 inline-flex
}

Проще говоря, если вы явно задали для display значение flex или inline-flex для контейнера, все дочерние элементы контейнера будут иметь одинаковую высоту, потому что значение по умолчанию для align-items контейнера — stretch.

В это время эффект, который вы видите, выглядит следующим образом:

Demo(код спрей.IO/love/embed…)

Этот метод особенно подходит для карточных компонентов:

Demo(код спрей.IO/love/embed…)

Аналогично в модуле макета сетки:

<!-- HTML -->
<grid__container>
    <grid__item></grid__item>
    <grid__item></grid__item>
    <grid__item></grid__item>
</grid__container>

/* CSS */
.grid__container {
    display: grid;
    grid-template-columns: 20vw 1fr 20vw; /* 根据需求调整值*/
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Также используется в некоторых макетах классов карт:

Demo(код спрей.IO/love/embed…)

Если потребности корректируются, например, в элементе Flex или элементе Grid, высота дочернего элемента совпадает с высотой контейнера.

<!-- HTML -->
<flex__container>
    <flex__item>
        <content></content>
    </flex__item>
</flex__container>

/* CSS */
.flex__container {
    display: flex;
}

.content {
    height: 100%
}

// 或
.grid__container {
    display: grid;
    grid-auto-flow: column;
}

.content {
    height: 100%;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

На основе липкого нижнего колонтитула

Сначала используйте следующий рисунок, чтобы описать эффект макета Sticky Footer:

Схема реализации Sticky Footer такая же, как с равной высотой и вертикальным центрированием, и также существует множество схем, которые можно реализовать (//css-tricks.com/couple-takes-sticky-footer/).

Например, такая структура:

<!-- HTML -->
<header></header>
<main></main>
<footer></footer>

Давайте сначала посмотрим на реализацию в модуле макета Flexbox:

body {
    display: flex;
    flex-direction: column;
}

footer {
    margin-top: auto;
}

Demo(код спрей.IO/love/embed…)

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

Он будет в самом низу страницы, и когда контент превысит один экран, он будет автоматически задержан».

В макете Flexbox вы также можете

Установите следующие стили для области, чтобы добиться такого же эффекта:

body {
    display: flex;
    flex-direction: column;
}

main {
    flex: 1 0 auto;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

flex: 1 0 auto в flex: 1 0 auto эквивалентен:
main {
    flex-grow: 1; /*容器有剩余空间时,main区域会扩展*/
    flex-shrink: 0; /*容器有不足空间时,main区域不会收缩*/
    flex-basis: auto; /*main区域高度的基准值为main内容自动高度*/
}

Если вы хотите избавить себя от проблем, вы можете явно установить flex-grow: 1 на main, так как значения по умолчанию для flex-shrink и flex-basis равны 1 и auto.

В макете CSS Grid мы можем использовать 1fr, чтобы сделать

Площадь вычисляется в соответствии с оставшимся пространством контейнера Grid.

.grid__container {
    display: grid;
    grid-template-rows: auto 1fr auto;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

поровну

В веб-макетах столбцы часто расположены одинаково, наиболее распространенным из них является нижняя панель на мобильной стороне, например эффект, подобный показанному ниже:

До появления Flexbox и Grid, если вы хотите добиться настоящего эффекта выравнивания, вы можете разделить 100% (или 100vw) на определенное количество столбцов. Например:

<!-- HTML -->
<container>
    <column></column>
    <column></column>
    <column></column>
</container>

/* CCSS */
.container {
    inline-size: 50vw;
    min-inline-size: 320px;
    display: flex-row;
}

.column {
    float: left;
    width: calc(100% / 3);
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

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

В макетах Flexbox и Grid добиться вышеуказанных эффектов становится намного проще. Давайте сначала посмотрим на макет во Flexbox:

<!-- HTML -->
<flex__container>
    <flex__item></flex__item>
    <flex__item></flex__item>
    <flex__item></flex__item>
</flex__container>

/* CSS */
.flex__container {
    inline-size: 50vw;
    display: flex;
}

.flex__item {
    flex: 1;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

В модуле компоновки Flexbox, когда значение flex является единственным значением (безразмерным числом), таким как flex: 1 в примере, оно будет рассматриваться как явно заданное flex-grow: 1. Flex рассчитывается браузером:

Далее давайте посмотрим, как добиться эффекта приведенного выше примера в Grid:

<!-- HTML -->
<grid__container>
    <grid__item></grid__item>
    <grid__item></grid__item>
    <grid__item></grid__item>
</grid__container>

/* CSS */
.grid__container {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /*这里的3表示具体的列数*/
}

Конечный эффект тот же:

Demo(код спрей.IO/love/embed…

Этот макет также применяется к другим макетам. Но будь то макет Flexbox или Grid, есть определенные дефекты.Когда в контейнере недостаточно места для размещения элементов Flex (или элементов Grid), элементы Flex или элементы Grid будут переполняться (или скрываться, если контейнер Flex или Grid контейнер явно переполнен: установлен скрытый):

Самый простой способ исправить это — явно установить минимальную ширину (или минимальный встроенный размер) в контейнере Flex или контейнере Grid:

.flex__container {
    min-inline-size: 300px;
}

Тем не менее, он возвращается, например, наш проект Flex (или проект Grid) представляет собой карту, ширина каждой карты одинакова, а позже в контейнере не хватает места, проект Flex (или проект Grid) автоматически раскрывается.

Мы продолжаем показывать вам примеры. Давайте сначала посмотрим на реализацию Flexbox:

.flex__container {
    display: flex;
    flex-wrap: wrap;
}

.flex__item {
    flex: 0 1 calc((100vw - 18vh) / 4); /* calc(100vw -18vh) / 4 是flex-basis的基准值 */
}

Demo(код спрей.IO/love/embed…)

Вы можете попробовать настроить ширину области просмотра браузера. По мере того, как область просмотра браузера становится все меньше и меньше, ширина контейнера flex становится все меньше и меньше. Когда контейнер flex настолько мал, что в нем недостаточно места для четырех элементов flex (для этого примера , оператор), то элемент Flex выстроится в линию:

На основе этого примера, если вы измените значение flex элемента flex на:

.flex__item {
    flex: 0 0 400px;
}

В это время, когда во флекс-контейнере не хватает места, флекс-элемент рассчитает свою ширину в соответствии с flex-basis: 400px, а когда во флекс-контейнере не хватит места, флекс сломается:

И наоборот, если значение гибкого элемента flex изменено на:

.flex__item {
    flex: 1 0 400px;
}

Когда во флекс-контейнере недостаточно места для расположения флекс-элементов, флекс-элемент рассчитает свою ширину в соответствии с flex-basis: 400px, флекс разорвет строку, а когда в той же строке останется место, флекс item будет расширяться, чтобы заполнить весь гибкий контейнер:

Добиться подобного эффекта в Grid немного сложнее. Вы можете использовать функцию repeat(), 1fr и функции автоподбора:

.grid__container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2vh;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Если вас интересуют эти знания, вы также можете прочитать статью «Решения Container Query с CSS Grid и Flexbox(//moderncss.dev/container-query-solutions-with-css-grid-and-flexbox/)».

На самом деле в Grid есть еще одно значение по сравнению с автоподбором, называемое автозаполнением. Но разница между ними очень велика. Используйте следующий рисунок, чтобы описать разницу между автоподбором и автозаполнением:

Кроме того, этот метод пока представляет собой эффект адаптивного макета, не требующий медиа-запросов CSS.

Макет Святого Грааля

Макет Holy Grail (//en.wikipedia.org/wiki/Holygrail(web_design)) — типичный шаблон макета в Интернете (//alistapart.com/article/holygrail/). Это выглядит как на изображении ниже:

Для макета Holy Grail к структуре HTML предъявляются определенные требования, т. е. содержание в первую очередь:

<!-- HTML -->
<header></header>
<main>
    <article></article> <!-- 主内容 -->
    <nav></nav>
    <aside></aside>
</main>
<footer></footer>

Здесь я в основном буду обсуждать с вами, как использовать модули макета Flexbox и Grid для реализации макета Holy Grail. Давайте сначала посмотрим на реализацию Flexbox:

body {
    width: 100vw;
    display: flex;
    flex-direction: column;
}

main {
    flex: 1;
    min-height: 0;

    display: flex;
    align-items: stretch;
    width: 100%;
}

footer {
    margin-top: auto;
}

nav {
    width: 220px;
    order: -1;
}

article {
    flex: 1;
}

aside {
    width: 220px;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

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

Аранжировано ранее, просто небольшая настройка из приведенного выше примера:

nav {
    order: 0;
}

aside {
    order: -1;
}

Эффект следующий:

Обратите внимание, что значение порядка по умолчанию равно 0, и чем больше значение, тем позже он будет!!

На основе приведенного выше примера с помощью характеристик медиаобъектов CSS легко добиться эффекта отзывчивого макета святого Грааля:

@media screen and (max-width: 800px) {
    main {
        flex-direction: column;
    }

    nav, aside {
        width: 100%;
    }
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Попробуйте перетащить браузер, чтобы изменить размер окна, вы можете увидеть эффект, как показано ниже:

В модуле макета Grid проще и гибче реализовать макет Holy Grail, чем в модуле макета Flexbox. В модуле компоновки CSS Grid структура HTML может быть более лаконичной:

<!-- HTML -->
<body>
    <header></header>
    <main></main>
    <nav></nav>
    <aside></aside>
    <footer></footer>
</body>

Существует множество программ может достичь Святого Грааля эффекта макета CSS в терминах. Давайте посмотрим на первое:

body {
    display: grid;
    grid-template: auto 1fr auto / 220px 1fr 220px;
}

header {
    grid-column: 1 / 4;
}

main {
    grid-column: 2 / 3;
    grid-row: 2 / 3;
}

nav {
    grid-column: 1 / 2;
    grid-row: 2 / 3;
}

aside {
    grid-column: 3 / 4;
    grid-row: 2 / 3;
}

footer {
    grid-column: 1 / 4;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

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

Как и в макете Flexbox, положение каждой области сетки можно изменить в медиа-запросе:

@media screen and (max-width: 800px) {
    body {
        grid-template-rows: auto;
        grid-template-columns: auto;
    }

    header,
    main,
    nav,
    aside,
    footer {
        grid-column: 1 / 2;
        min-height: auto;
    }

    main {
        grid-row: 3 / 4;
        margin: 0;
    }

    nav {
        grid-row: 2 / 3;
    }

    aside {
        grid-row: 4 / 5;
    }

    footer {
        grid-row: 5 / 6;
    }
}

Demo(код спрей.IO/love/embed…)

В дополнение к grid-template (то есть grid-template-columns и grid-template-rows) комбинация свойств grid-area и grid-template-areas также может использоваться в макете Grid, что также может легко реализовать Святой Грааль CSS. макет . Основываясь на приведенном выше примере, просто настройте свой CSS так:

body {
    display: grid;
    grid-template-areas:
        "header header header"
        "nav main aside"
        "footer footer footer";
}

header {
    grid-area: header;
}

main {
    grid-area: main;
}

nav {
    grid-area: nav;
}

aside {
    grid-area: aside;
}

footer {
    grid-area: footer;
}

@media screen and (max-width: 800px) {
    body {
        grid-template-areas:
            "header"
            "nav"
            "main"
            "aside"
            "footer";
    }
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Вы могли заметить различия между ними:

В этом последнем примере

, равный ширине области. Это связано с тем, что в нашем примере для объявления сетки используется grid-template-areas.Когда grid-template-areas используется для создания сетки, линии сетки также создаются неявно, но он отличается от grid-template тем, что grid-template может указать размер дорожки сетки явно, а области шаблона сетки в этом примере эквивалентны размеру дорожки сетки 1fr.

если мы хотим

Область становится больше, затем вы можете внести коррективы в области сетки-шаблона:

body {
    display: grid;
    grid-template-areas:
        "header header header header header"
        "nav main main main aside"
        "footer footer footer footer footer";
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

В настоящее время разделение области сетки выглядит следующим образом:

Хотя эффект был скорректирован, он по-прежнему сбалансирован. Лучшим решением является объединение областей grid-template-areas и grid-template:

body {
    display: grid;
    grid-template-areas:
        "header header header"
        "nav main aside"
        "footer footer footer";
    grid-template-columns: 220px 1fr 220px;
    grid-template-rows: auto 1fr auto;
}

header {
    grid-area: header;
}

main {
    grid-area: main;
}

nav {
    grid-area: nav;
}

aside {
    grid-area: aside;
}

footer {
    grid-area: footer;
}

@media screen and (max-width: 800px) {
    body {
        grid-template-areas:
            "header"
            "nav"
            "main"
            "aside"
            "footer";
        grid-template-columns: 1fr;
        grid-template-rows: auto auto 1fr auto auto;
    }

    main {
        margin-left: 0;
        margin-right: 0;
    }
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Вы можете обнаружить, что в это время область линии сетки называется как на следующем изображении:

12-колоночная сетка

12-колоночная сетка была впервые предложена 960.gs в качестве системы компоновки сетки (//960.gs/):

12-колоночная сетка часто используется в дизайн-системах и CSS Framework, например, классический отраслевой Bootstrap (//getbootstrap.com/) использует 12-колоночную сетку:

В сообществе также есть много онлайн-инструментов, которые помогут нам быстро построить систему сетки из 12 столбцов, например, инструменты, перечисленные в статье Бесплатные инструменты и ресурсы CSS Grid для разработчиков (//1stwebdesigner.com/free-css-grid- инструменты-ресурсы/).

Demo (paulhebertdesigns.com/gridley/)

Но здесь я в основном хочу взглянуть на то, как 12-колоночная система разметки сетки реализована в модулях разметки Flexbox и Grid.

Давайте сначала посмотрим на модуль макета Flexbox. HTML-структура макета сетки из 12 столбцов обычно выглядит следующим образом:

<!-- HTML -->
<flex__grid>
    <flex__row>
        <flex__item col4></flex__item col4>
        <flex__item col4></flex__item col4>
        <flex__item col4></flex__item col4>
    </flex__row>
</flex__grid>

Обратите внимание, что в сетке из 12 столбцов сумма значений столбцов в одной строке обычно равна ровно 12. Например, в приведенной выше HTML-структуре есть три столбца в строке, и каждый столбец имеет ровно четыре ширины сетки плюс два интервала между столбцами. И есть зрелая формула расчета при расчете:

И также будут различия в дизайне, например, есть ли зазор между двумя сторонами контейнера и т. Д .:

Эти различия немного отличаются в оформлении расчетных формул и стилевых кодов. Давайте использовать один из них в качестве примера:

:root {
    --gutter: 10px;
    --columns: 12;
    --span: 1;
}

.flex__container {
    display: flex;
    flex-direction: column;
    padding-left: var(--gutter);
    padding-right: var(--gutter);
}

.flex__row {
    display: flex;
    margin-left: calc(var(--gutter) * -1);
    margin-right: calc(var(--gutter) * -1);
}

.flex__row + .flex__row {
    margin-top: 2vh;
}

.flex__item {
    flex: 1 1
        calc((100% / var(--columns) - var(--gutter)) * var(--span));
    margin: 0 var(--gutter);
}

.flex__item1 {
    --span: 1;
}

.flex__item2 {
    --span: 2;
}

.flex__item3 {
    --span: 3;
}

.flex__item4 {
    --span: 4;
}

.flex__item5 {
    --span: 5;
}

.flex__item6 {
    --span: 6;
}

.flex__item7 {
    --span: 7;
}

.flex__item8 {
    --span: 8;
}

.flex__item9 {
    --span: 9;
}

.flex__item10 {
    --span: 10;
}

.flex__item11 {
    --span: 11;
}

.flex__item12 {
    --span: 12;
}

Эффект, который вы увидите, выглядит следующим образом:

Demo(код спрей.IO/love/embed…)

В этом примере функции, связанные с пользовательскими свойствами CSS, используются для упрощения всего расчета.

Для использования модуля макета CSS Grid для реализации макета сетки из 12 столбцов, условно говоря, будет проще как структура HTML, так и код CSS. При использовании модуля макета CSS Grid для реализации макета сетки из 12 столбцов будут использоваться такие функции, как repeat(), minmax(), gap и fr. Возьмем конкретный пример.

<!-- HTML -->
<grid__container>
    <grid__item></grid__item>
</grid__container>

Давайте посмотрим на код CSS:

  • Используйте fr, чтобы разделить сетку на равные значения, то есть ширина каждого столбца равна 1 fr; с функцией repeat(), то есть repeat(12, 1fr), создает сетку из 12 столбцов

  • Использование зазора может использоваться для управления расстоянием между сетками.

  • С помощью minmax() вы также можете установить минимальное значение сетки

Конкретный код выглядит следующим образом:

:root {
    --columns: 12;
    --gap: 10px;
    --span: 1;
}

.grid__container {
    display: grid;
    grid-template-columns: repeat(var(--columns), 1fr);
    grid-template-rows: 1fr;
    gap: var(--gap);
    padding-left: calc(var(--gap) / 2);
    padding-right: calc(var(--gap) / 2);
}

.grid__item {
    min-block-size: 10vh;
    grid-column: span var(--span);
}

.col1 {
    --span: 1;
}

.col2 {
    --span: 2;
}

.col3 {
    --span: 3;
}

.col4 {
    --span: 4;
}

.col5 {
    --span: 5;
}

.col6 {
    --span: 6;
}

.col7 {
    --span: 7;
}

.col8 {
    --span: 8;
}

.col9 {
    --span: 9;
}

.col10 {
    --span: 10;
}

.col11 {
    --span: 11;
}

.col12 {
    --span: 12;
}

Эффект, который вы увидите, выглядит следующим образом:

Demo(код спрей.IO/love/embed…)

В этом примере grid-template-columns: repeat(12, 1fr) создает сетку, как показано ниже:

В дополнение к вышеупомянутому грубому методу вы также можете быть более гибким, создавая автоподгонку, minmax() и grid-auto-flow: плотности и т.д.:

.grid__container {
    padding: 1em;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
    gap: 1em;
    grid-auto-flow: dense;
}

Для .grid__item вы можете управлять положением элементов сетки через grid-column и grid-row:

Demo(код спрей.IO/love/embed…)

При использовании grid-auto-flow: плотно элементы сетки автоматически перемещаются в соответствующую позицию в соответствии с пространством контейнера сетки:

Этот макет очень подходит для журнальных макетов. Для более подробного ознакомления с этим вы можете прочитать @Keir Watson’s Responsive Grid Magazine Layout всего за 20 строк CSS(//css-tricks.com/responsive-grid-magazine-layout-in-just-20-lines-of- css/)».

оправданный

Необходимость обоснования часто встречается в веб-макетах. В макетах Flexbox значение justify-content часто явно задается во flex-контейнере:

.flex__container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;

    width: 100%;
}

Но в конце строки, если количество строк не такое, как в предыдущей строке (элементы Flex), появится следующий эффект:

Эффект, подобный изображенному выше, не то, что нам нужно, потому что мы хотим расположить flex-элементы рядом друг с другом, когда flex-элементов в последней строке недостаточно для заполнения строки:

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

.flex__container::after {
    content: "";
    display: flex;
    flex: 0 1 32vw;
}

Обратите внимание, что flex-basis псевдоэлементов рекомендуется устанавливать равным flex-basis (или ширине) карточки. На этом этапе вы увидите пример, подобный следующему:

Demo(код спрей.IO/love/embed…)

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

Столкнувшись с таким сценарием, нам нужно добавить во flex-контейнер дополнительный пустой элемент label:

Количество элементов-заполнителей = максимальное количество столбцов в строке - 2

Но после появления атрибута gap добиться такого эффекта несложно:

body {
    padding: 1vh;
}

.flex__container {
    display: flex;
    flex-wrap: wrap;
    gap: 2vh;

    width: 100%;
}

.flex__item {
    flex: 0 1 calc((100vw - 8vh) / 4);
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Обратите внимание, что гэп, используемый во Flexbox, до сих пор поддерживался только браузером Firefox. В приведенном выше примере, используя браузер Firefox, вы можете увидеть следующий эффект:

В макете CSS Grid вы можете использовать пробел напрямую:

body {
    padding: 1vh;
}

.grid__container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1vh;
}

Эффект следующий:

Demo(код спрей.IO/love/embed…)

Выберите лучшее значение

Много раз для разных сценариев дизайнеры предоставляли нам разные стили дизайна, такие как размер элемента:

С появлением функции clam() все стало намного проще.

Функция clam() принимает три параметра, а именно clam(MIN, VAL, MAX), где MIN — минимальное значение, VAL — предпочтительное значение, а MAX — максимальное значение. между ними:

  • Если VAL находится между MIN и MAX, используйте VAL в качестве возвращаемого значения функции;

  • Если VAL больше MAX, используйте MAX в качестве возвращаемого значения функции;

  • Если VAL меньше MIN, используйте MIN в качестве возвращаемого значения функции.

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

.element {
    /**
    * MIN = 100px
    * VAL = 50vw ➜ 根据视窗的宽度计算
    * MAX = 500px
    **/

    width: clamp(100px, 50vw, 500px);
}

Например, текущая позиция окна браузера имеет ширину 1200 пикселей, тогда результат рендеринга .element будет следующим:

В настоящее время ширина элемента .element составляет 500 пикселей. В настоящее время зажим (100 пикселей, 50vw, 500 пикселей) эквивалентен зажиму (100 пикселей, 600 пикселей, 500 пикселей), а соответствующее значение VAL равно 600 пикселей, что больше, чем значение MAX. Затем значение, возвращаемое функцией зажима (). в это время это МАКС, что составляет 500 пикселей.В это время значение ширины .element составляет 500 пикселей (то есть значение МАКС).

Если мы уменьшим окно браузера до 760 пикселей:

В настоящее время ширина элемента .element составляет 50vw. На этом этапе clip(100px, 50vw, 500px) эквивалентен clip(100px, 380px, 500px), а соответствующее значение VAL равно 380px, что больше минимального значения (100px) и меньше максимального значения (500px). ), затем clip( Значение, возвращаемое функцией ) равно VAL, то есть 50vw. В это время значение ширины .element равно 50vw (то есть значение VAL).

Если вы продолжаете уменьшать область просмотра браузера до 170 пикселей:

В настоящее время ширина элемента .element составляет 100 пикселей. На данный момент зажим (100 пикселей, 50vw, 500 пикселей) эквивалентен зажиму (100 пикселей, 85 пикселей, 500 пикселей), а соответствующее значение VAL равно 85 пикселей, что меньше минимального значения (100 пикселей), тогда значение, возвращаемое зажимом () в это время составляет MIN , то есть 100 пикселей.В это время значение ширины .element составляет 100 пикселей (то есть значение MIN).

Для этого примера clip(100px, 50vw, 500px) также можно понимать так:

  • Ширина element.element не будет меньше 100 пикселей (что-то вроде настройки элемента min-width: 100px)

  • Ширина element.element не будет превышать 500 пикселей (что-то вроде элемента с максимальной шириной: 500 пикселей).

  • Предпочтительное значение VAL — 50vw, которое допустимо только тогда, когда ширина области просмотра больше 200 пикселей и меньше 1000 пикселей, то есть ширина элемента .element равна 50vw (что-то похожее на настройку ширины элемента: 50vw).

Конкретные эффекты следующие: Щелкните здесь, чтобы просмотреть (код спрей.IO/love/embed…

Выравнивание значков логотипа

Я думаю, вы могли столкнуться со сценарием, подобным приведенному ниже, в веб-разработке:

Как показано на изображении выше, изображение логотипа может быть большим или маленьким (разной ширины и высоты). Столкнувшись с таким бизнес-сценарием, дизайнеры часто должны предоставлять изображения одинакового размера. Но это неизбежно отразится на внешнем виде логотипа.

Некоторое время назад я увидел, как @Ahmad Shadeed написал в блоге сообщение «Выравнивание изображений логотипа в CSS (//ishadeed.com/article/aligning-logos-css/)», в котором рассказывается, как добиться эффекта макета, подобного приведенному выше. картина.

На самом деле, для достижения такого эффекта макета главным приложением является атрибут CSS «подгонка объекта», и этот атрибут много лет назад поддерживался основными основными браузерами.

Здесь мы используем простой пример, чтобы увидеть конкретный процесс реализации. Давайте сначала посмотрим на структуру HTML:

<!-- HTML -->
<ul class="brands">
    <li class="brands__item">
        <a href="#">
            <img src="img/logo.png" alt="">
        </a>
    </li>
    <li> <!-- ... --> </li>
</ul>

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

.brands {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    grid-gap: 1rem;
}

.brands__item {
    background: #eee;
}

.brands__item a {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
}

.brands__item img {
    width: 130px;
    height: 75px;
    object-fit: contain;
}

Это позволит достичь эффекта, показанного выше. Возможно, вы заметили, что некоторые изображения логотипов имеют фоновый цвет. Если вы хотите улучшить эффект, вы можете использовать функции, связанные с режимом наложения CSS:

.brands__item img {
    width: 130px;
    height: 75px;
    object-fit: contain;
    mix-blend-mode: multiply;
}

В это время эффект, который вы видите, выглядит следующим образом:

В дополнение к значению contains у object-fit есть несколько других значений.Подробнее см. в этом примере (код спрей.IO/love/embed…

На самом деле, эта схема также подходит для изображений товаров, аватаров персонажей и других макетов.

резюме

Статья в основном знакомит с идеями реализации и конкретными схемами некоторых макетов в сети. На самом деле упомянутые в статье эффекты, такие как горизонтальное и вертикальное центрирование, равновеликая верстка, равномерно распределенные колонки и Sticky Footer и т. д., всегда имели множество решений в CSS, но с появлением верстки CSS Flexbox модуль и модуль компоновки CSS Grid. Достижение этих эффектов становится более гибким и лаконичным.

Конечно, в статье упоминаются только некоторые из наиболее распространенных эффектов, на самом деле в веб-верстке есть много интересного, особенно в верстке Flexbox и верстке Grid, но они не перечислены по порядку из-за недостатка места. Если вам интересно, вы можете раскопать еще кое-что.Если у вас есть лучший опыт или решения в этом отношении, пожалуйста, поделитесь в комментариях ниже. Наконец, я надеюсь, что эта статья поможет вам в вашей обычной работе.