Реализовать минимальную адаптивную систему компоновки CSS

CSS

На солнце она сушит свою одежду посреди двора / На ветру четырех времен года она распускает волосы и утешает время

—— Чжао Лэй «Южная девушка»

Адаптивные системы макетов уже широко распространены в популярных CSS-фреймворках. Он в основном состоит из классов-контейнеров и системы сеток, которая согласовывает количество строк и столбцов, формируя скелет фреймворка.

Это отражено в популярных интерфейсных фреймворках Bootstrap и Bulma CSS. как у бутстрапа.container,.row,.col; также Bulma CSS.container,columns,columnОба представляют этот тип системы компоновки. Хотя названия разные, принцип тот же.

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

Теперь давайте посмотрим, как реализовать минимальную адаптивную систему компоновки CSS.

Начнем с контейнера.

Чтобы обеспечить простоту кода реализации, в этой статье для написания будет использоваться SCSS. Если вы не знакомы с SCSS, не беда, используемые точки знаний будут введены в тексте.

контейнер

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

Мы используем.containerзаключить контракт на контейнер.

Во-первых, контейнер располагается по центру горизонтально, что упрощает стилизацию:

.container {
    margin-left: auto;
    margin-right: auto;
}

Так называемый адаптивный контейнер основан на разных точках останова (breakpoints), то есть на текущей ширине области просмотра, чтобы определить, какой контейнер использовать.max-widthстоимость.

Здесь мы заимствуем определение точек останова в Bootstrap и разделяем их на следующие типы устройств в зависимости от ширины окна просмотра:

  1. Очень маленький экран, обычный мобильный телефон, радиус действия[0, 576px)
  2. Маленький экран, большой телефон, радиус действия[576px, 768px)
  3. Средний экран, планшет, радиус действия[768px, 992px)
  4. Большой экран, стационарный компьютер, ассортимент есть[992px, 1200px)
  5. Очень большой экран, большой настольный компьютер, от[1200px, +∞)

Объявить переменную для определения точки останова$breakpoints:

$breakpoints: (
    // Extra small screen / phone
    xs: 0,
    // Small screen / phone
    sm: 576px,
    // Medium screen / tablet
    md: 768px,
    // Large screen / desktop
    lg: 992px,
    // Extra large screen / wide desktop
    xl: 1200px
);

$breakpointsНазывается «список». Это структура данных, которую нам предоставляет SCSS. по одномуkey: valueСостоит из пар ключ-значение. Ключ в приведенном выше примере представляет собой начальную точку допустимого диапазона устройства.

Под разное оборудование контейнер имеет разныеmax-widthстоимость. Итак, здесь мы объявляем еще одну переменную, представляющую ширину контейнера.$container-max-widths:

$container-max-widths: (
    xs: none,
    sm: 540px,
    md: 720px,
    lg: 960px,
    xl: 1140px
);

здесь$container-max-widthsЭто также список, где ключ представляет собой максимальную ширину контейнера под определенное устройство. Например, на устройствах с большим экраном максимальная ширина контейнера1140px, а под нормальными мобильными телефонами максимальная ширина контейнера не устанавливается, что является значением по умолчаниюnone.

Имея идею реализации, следующим шагом будет ее реализация.

Мы можем использовать директиву медиа-запроса@media, в соответствии с диапазоном ширины области просмотра, что дает.containerразныеmax-widthстоимость.

@each $device, $breakpoint in $breakpoints {
    @media only screen and (min-width: $breakpoint) {
        .container {
            max-width: map-get($container-max-widths, $device);
        }
    }
}

7 строчек кода готово!

Приведенный выше код поясняется ниже.

Мы проходим по списку, используя@each...inГрамматика, каждый обход берет соответствующий ключ и значение и получает текущий$device,$breakpoint.map-getЭто метод, предоставляемый SCSS для управления списком: получение значения в соответствии с ключом. Например, когда$deviceзначениеxsкогда,map-get($container-max-widths, $device)Соответствующее значениеnone;когда$deviceзначениеsmкогда,map-get($container-max-widths, $device)Соответствующее значение540px, и так далее.

@media only screen and (min-width: $breakpoint) { ... }Содержит код, представляющий стили CSS, применяемые с текущей точки останова устройства.Когда мы одновременно устанавливаем медиа-запрос двух точек останова в порядке от малого к большому, последний переопределяет стиль первого., что является основным принципом реализации контейнеров разной ширины в разных окнах просмотра.

Затем присвойте полученное значение ширины контейнеру.max-widthсвойства в порядке.

Итак, мы написали отзывчивый контейнер, давайте подытожим код:

$breakpoints: (
    // Extra small screen / phone
    xs: 0,
    // Small screen / phone
    sm: 576px,
    // Medium screen / tablet
    md: 768px,
    // Large screen / desktop
    lg: 992px,
    // Extra large screen / wide desktop
    xl: 1200px
);

$container-max-widths: (
    xs: none,
    sm: 540px,
    md: 720px,
    lg: 960px,
    xl: 1140px
);

.container {
    margin-left: auto;
    margin-right: auto;
}

@each $device, $breakpoint in $breakpoints {
    @media only screen and (min-width: $breakpoint) {
        .container {
            max-width: map-get($container-max-widths, $device);
        }
    }
}

кликните сюдачтобы увидеть эффект.

Далее мы познакомимся с сеткой из 12 столбцов.

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

Сначала используйте макет Flex и напишите минимальный моноширинный макет.

.row {
    display: flex;
    
    .col {
        flex-grow: 1;
        flex-basis: 0;
    }
}

Правильно, это весь код для реализации моноширинного макета с использованием макета Flex. Если не принимать во внимание пустые строки посередине, вам понадобится всего 7 строк кода.

Обоснование здесь заключается в том, что мы ставимflex-basisУстановить как0Другими словами, эти гибкие элементы не имеют ширины перед увеличением или уменьшением, они имеют одинаковую длину. Таким образом, окончательно рассчитанное пространство шпинделя равномерно распределяется между каждым flex-элементом, чтобы они имели одинаковую ширину.

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

  1. Вы не можете размещать элементы неравномерной ширины.
  2. Разрывы строк не поддерживаются.

Разрывы строк легко сделать, добавьте гибкий контейнерflex-wrap: wrapВот и все. Итак, как быть с компоновкой расположения «элементов неравномерной ширины».

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

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

flex-shrink: 0;
flex-grow: 0;
flex-basis: 0;

Сокращение для эквивалентности этих трех свойств:

flex: none;

Затем используйте процентwidthуказанная ширина.

Мы реализуем макет сетки с 12 столбцами в строке. То есть строка делится на 12 столбцов, и ширина каждого столбца составляет около 10% от общей ширины.8.33%. мы используем.is-列数Укажите количество столбцов, которые занимает элемент:

  • .is-1: занимает 1 столбец, что составляет 1/12 ширины
  • .is-2: занимают 2 столбца, что составляет 1/6 ширины
  • .is-3: занимают 3 столбца, что составляет 1/4 ширины
  • .is-4: занимает 4 столбца, что составляет 1/3 ширины
  • .is-5: занимают 5 столбцов, что составляет 5/12 ширины
  • .is-6: занимают 6 столбцов, что составляет 1/2 ширины
  • .is-7: занимает 7 столбцов, что составляет 7/12 ширины
  • .is-8: занимает 8 столбцов, что составляет 2/3 ширины
  • .is-9: занимают 9 столбцов, что составляет 3/4 ширины
  • .is-10: занимают 10 столбцов, что составляет 5/6 ширины
  • .is-11: занимает 11 столбцов, что составляет 11/12 ширины
  • .is-12: занимать 12 столбцов, то есть занимать всю ширину

В соответствии с этим правилом мы можем легко написать код компоновки сетки:

$columns: 12;

.row {
    display: flex;
    
    .col {
        flex-grow: 1;
        flex-basis: 0;
        
        @for $i from 1 through 12 {
            &.is-#{$i} {
                flex: none;
                width: percentage($i / 12);
            }
        }
    }
}

Здесь мы используем@forДиректива@for $var from <start> through <end>синтаксис, увеличивающийся от 1 до 12, определяет.is-*Эта серия имен классов, принцип заключается в том, что мы сказали, чтобы отключить расширение и сжатие элемента Flex и назначить ему ширину в процентах. Ну, это просто.

Затем добавьте разрыв строки (.row.is-multiline) и смещение гибкого элемента (.is-offset-*)служба поддержки.

Подытожим код:

$columns: 12;

.row {
    display: flex;
    
    &.is-multiline {
        flex-wrap: wrap;   
    }
    
    .col {
        flex-grow: 1;
        flex-basis: 0;
        
        @for $i from 1 through 12 {
            &.is-#{$i} {
                flex: none;
                width: percentage($i / 12);
            }
            &.is-offset-#{$i} {
                margin-left: percentage($i / 12);
            }
        }
    }
}

.is-multilineэто следовать.rowиспользуются вместе, что вы получаетеflex-wrap: wrapэффект; смещения элементовmargin-leftреализация имущества.

На этом наша 12-колоночная сетка готова ヾ(◍°∇°◍)ノ゙

полный код

Объединив две приведенные выше части кода, мы можем получить минимальную адаптивную систему макета~ O(∩_∩)O

$breakpoints: (
    // Extra small screen / phone
    xs: 0,
    // Small screen / phone
    sm: 576px,
    // Medium screen / tablet
    md: 768px,
    // Large screen / desktop
    lg: 992px,
    // Extra large screen / wide desktop
    xl: 1200px
);

$container-max-widths: (
    xs: none,
    sm: 540px,
    md: 720px,
    lg: 960px,
    xl: 1140px
);

.container {
    margin-left: auto;
    margin-right: auto;
}

@each $device, $breakpoint in $breakpoints {
    @media only screen and (min-width: $breakpoint) {
        .container {
            max-width: map-get($container-max-widths, $device);
        }
    }
}

$columns: 12;

.row {
    display: flex;
    
    &.is-multiline {
        flex-wrap: wrap;   
    }
    
    .col {
        flex-grow: 1;
        flex-basis: 0;
        
        @for $i from 1 through 12 {
            &.is-#{$i} {
                flex: none;
                width: percentage($i / 12);
            }
            &.is-offset-#{$i} {
                margin-left: percentage($i / 12);
            }
        }
    }
}

МогуПроверьте результаты здесь.

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

Ссылка на ссылку

Grid system, by getbootstrap.com

Вклад на Север

Спасибо, что потратили свое драгоценное время ⏲️ на чтение этой статьи.

Если вы считаете, что эта статья сделала вашу жизнь немного лучше, поощряйте (diǎn) поощряйте (zàn) 😀. Ваши ценные комментарии или мнения правильнее было бы оставлять под статьей, т.к.исследования показывают, Участие в обсуждениях может сделать людей более впечатленными знаниями, чем просто чтение 😉.

(над)