Как написать защитный CSS

внешний интерфейс CSS
Как написать защитный CSS

поскольку@Ahmad ShadeedВ прошлом году я писал в блоге оThe Just in Case Mindset in CSS», у меня тоже возникло желание организовать статью по этому поводу, но я ее еще не написал (честно говоря, на организацию такой статьи уходит очень много времени). В конце прошлого года я увидел, как г-н Ке Чжун опубликовал во внутренней сети статью о «защитной разработке CSS» (@Ahmad Shadeed во внешней сети также опубликовал статью о «Защитная разработка CSS"), желание еще больше. Я думаю, что я должен написать статью и об этом. Надеюсь, что всем будет полезна эта статья!

статус-кво

У учителя @kejun есть этот абзац в начале его статьи (статья в интранете, неудобно публиковать ссылку):

Текущее состояние разработки CSS не оптимистично, я просмотрел все и нашел различные проблемы. Фронтенд-разработка больше фокусируется на JavaScript, который является относительно более техническим. Однако, начиная с фундаментальной ценности интерфейсной технологии, реализация удобного пользовательского интерфейса продукта является первым шагом в пользовательском опыте, который тесно связан с профессионализмом разработчиков CSS. Я думаю, что профессиональный взгляд на разработку CSS — это оборонительная разработка CSS.

Фронтендеры чуть постарше должны знать, что когда нет фронтенд-позиции, есть должность, называемая «рефакторинг» (некоторые компании называют ее рефакторинг-инженером, а некоторые люди смеются над собой как «Четузи»). Ну, это то, откуда я пришел, и это продолжается по сей день. В большинстве случаев основным содержанием работы инженера по рефакторингу являетсяВосстановить пользовательский интерфейс, то есть написание структуры HTML (с семантической структурой HTML), написание CSS (с расширяемостью, ремонтопригодностью), вырезание графиков и т. д.

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

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

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

Фактически? Это все отступления, вернемся к основной теме.

Разработчики CSS (сегодня такой должности нет) первыми представляют дизайн пользователям. CSSеры и дизайнеры часто имеют дело друг с другом, можно сказать, что они «любят друг друга и убивают друг друга». Почему это так? Тогда мы должны начать с «истории восстановления на уровне пикселей».

не знал, что ты слышал"восстановление на уровне пикселейКогда слово? "

вообще говоря,«Восстановление на уровне пикселей» означает, что дизайнер надеется, что проект дизайна пользовательского интерфейса, который вы восстанавливаете, может обеспечить 100% восстановление.. Может быть, и сегодня вы еще будете драться с дизайнером из-за отклонения пикселя в вашей работе, а то и расстанетесь из-за этого пикселя. Честно говоря, за этот пиксель борются разные персонажи с разных сторон:

  • дизайнер: Я надеюсь, что работы, разработанные мной, не будут обесценены при представлении моим пользователям.
  • Разработчик: Не то чтобы я не хотел восстановления на уровне пикселей, но я часто нетерпелив

Другими словами, все они «работающие работники», и ни то, ни другое не легко. Оставив на время эти споры, давайте посмотрим, что такое восстановление на уровне пикселей.

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

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

Это означает, что HTML и CSS могут достичь 100% эффекта дизайна, даже один пиксель — это неплохо.

Я также часто слышу это беспокойство:

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

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

Он выглядит одинаково, но когда мы его складываем, мы видим разницу:

И этот результат можно смело считать несовершенной (не пиксельной) реставрацией. Итак, действительно ли восстановление на уровне пикселей идеально?

Сначала проясните этот вопрос. Строго говоря, я лично считаю, что идеальное восстановление на уровне пикселей невозможно. Потому что веб-разработчики пишут HTML и CSS для работы на различных конечных точках устройств, и сегодня этих конечных точек достаточно, чтобы поразить нас. Другими словами, будет много переменных, которые повлияют на рендеринг наших закодированных веб-страниц. Например, когда эффект Taobao PC в браузерах Chrome и Safari вынимается и просматривается рядом, два скриншота кажутся очень похожими, и проблем нет:

Но когда вы смотрите на них вместе, сразу видна разница:

График выше — это всего лишь разница в одной из переменных (два разных браузера в одной системе). Подумайте, сколько других факторов может повлиять на веб-страницу в действительности, например:

  • Тип устройства (настольный компьютер, ноутбук, планшет, телефон, часы и т. д.)
  • размер экрана (или окна)
  • Плотность пикселей экрана (например, Retina и не Retina)
  • Технология экрана (например, OLED, LCD, CTR и т. д.)
  • Действия пользователя (например, изменение пользователем масштаба экрана, настройка размера шрифта по умолчанию и т. д.)
  • Производительность (например, аппаратное обеспечение устройства, загрузка сервера, скорость сети и т. д.)
  • Цвет устройства правильный (например, ночной режим, темный режим в iOS и т. д.)

Это только то, о чем я могу думать, есть ли еще много того, о чем я не могу думать? То есть мы никогда не можем быть уверены, что значения RGB отдельных пикселей на экране совпадают на 100%. Это невозможный стандарт. Но и это не главное.

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

Разве не было бы идеально без восстановления на уровне пикселей?

Предыдущие два примера показали вам, что всегда есть различия, когда веб-разработчики восстанавливают эскиз проекта, предоставленный дизайнером, и есть много факторов, влияющих на это различие. И этот эффект можно смело считать несовершенным в глазах дизайнеров. Так на самом деле, это действительно несовершенно?

Прежде чем ответить на этот вопрос, вернемся на десять лет назад.

В 2010 году дизайнеры или клиенты требовали, чтобы внешний интерфейс был восстановлен на уровне пикселей при восстановлении эскизов дизайна, что может быть возможно для веб-разработчиков. Потому что в те дни в Интернете было не так много типов терминальных устройств, в конце концов, большинство из них отображалось на настольных компьютерах, не так много ноутбуков, не говоря уже о таком количестве мобильных терминальных устройств сейчас. Веб-разработчикам также не так много размеров экрана, которые следует учитывать. Проще говоря, это размер страницы ПК, например привычной960pxширина или позже1024pxШирина достаточная. Однако с миллионами устройств (умных часов, смартфонов, планшетов, ноутбуков, настольных компьютеров, телевизоров и т. д.) восстановление на уровне пикселей будет непростым или даже невозможным.

Такие слова из устья веб-разработчика веб-разработчики говорят, что не значит, что нет духа изобретательности, без преследования.

Недавно у меня появилось новое слово "видеть (смотреть) и чувствовать". Поместите это в нашем веб-дизайне, «Взгляд (взгляд)» относится к перспективе пользовательского интерфейса, как внешний вид веб-сайта, он ощущается в основном с точки зрения веб-функций и интерактивности.

Я сделал два снимка:

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

Посмотрим на другую картинку:

Левое изображение — оригинальный дизайн, правое изображение — эффект страницы, разработанный веб-интерфейсом!

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

В конце концов вы не достигнете идеального результата!

Веб-разработчику легко исправить эти различия. Однако есть ряд причин, по которым результаты веб-разработчика отличаются от черновика дизайна, и эти причины будут различаться по разным причинам. Например:

  • ты разбираешься в дизайне
  • Хватит ли времени на разработку проекта
  • Как насчет способности в CSS
  • Стоит ли обращать внимание на детали

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

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

Поскольку речь идет об идеальной реставрации, как профессиональный CSSer, какая реставрация является идеальной реставрацией? Это то, что мы собираемся обсудить сегодня.

Имеет защитный код CSS

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

защитное программирование(Защитное программирование) — это конкретное проявление защитного дизайна, который должен гарантировать, что непредвиденное использование программы не нанесет ущерба ее функциям. Это можно рассматривать как идею уменьшить или устранить действие закона Мерфи. Защитное программирование в основном используется в программах, которые могут быть неправомерными, вредоносными или непреднамеренно иметь катастрофические последствия.

В процессе восстановления пользовательского интерфейса проект дизайна, предоставленный дизайнером, является статическим продуктом Хотя отличный дизайнер покажет полиморфную форму интерфейса (форму выражения) в своем дизайн-проекте, он не может поставить динамику Данные отображаются отлично в эскизном проекте. Если веб-разработчики просто восстанавливают проект дизайна один в один при восстановлении пользовательского интерфейса, будет много проблем (закапывание мин). Потому что, когда веб-страница отображается в клиенте, ситуация, с которой он сталкивается, будет очень сложной, например, данные динамические, оборудование разнообразное и так далее. Изменения в этих вещах увеличат вероятность проблем с CSS и даже вызовут странное поведение при отображении страницы. Проще говоря, мы должны убедиться, что восстановленный интерфейс работает в разных условиях.

Чтобы выполнить такое базовое требование, мы должны иметь мышление «а что, если» (на всякий случай), то есть заранее рассмотреть некоторые особые ситуации, такие как некоторые ситуации, которые могут возникнуть в маргинальных условиях. Лично я часто спрашиваю при восстановлении UI:

  • Что делать, если заголовок слишком длинный? Вырезать напрямую или добавить три точки в конце
  • Данные не выплёвываются? Не обрабатывать и не прятать пустой контейнер
  • А контейнеры становятся меньше? Как это должно отображаться?
  • так далее

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

То есть, когда мы восстанавливаем пользовательский интерфейс, у нас всегда должен быть образ мышления «а что, если». Следование этому мышлению, по крайней мере, уменьшит ваши проблемы. Разница между плохим и хорошим часто заключается в строке кода. Часто эта простая строка кода делает ваш CSS более надежным и защищенным.

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

Защитный CSS, связанный с макетом Flexbox

CSS Flexbox — одна из самых популярных технологий верстки в настоящее время (в 2022 году CSS Grid также может стать одной из основных технологий верстки). Многие веб-разработчики также предпочитают Flexbox для верстки, но при использовании Flexbox для верстки необходимо освоить некоторые детали, и освоение этих деталей может сделать ваш код CSS более надежным.

flexещеinline-flex

Как мы все знаем, первым условием использования Flexbox является явное объявление элемента контейнераdisplayценностьflexилиinline-flex, и контейнер становится контейнером Flexbox (т. е. FFC). Их проявления несколько схожи сblockа такжеinline-block.

Когда родительский элемент контейнера flexbox неdisplayЗначение переопределения формата контекста приведено ниже:

  • Установить какflexКонтейнер, его ширина равна ширине родительского контейнера, т.е.widthдля100%, Также известный как контейнерный блок Flexbox
  • Установить какinline-flexКонтейнер, его ширина определяется содержимым его дочерних элементов (элементов-потомков), что эквивалентноwidthдляauto, также известный как встроенный контейнер Flexbox.

Дизайн пользовательского интерфейса также имеет аналогичный сценарий:

Как и в приведенном выше черновике дизайна, некоторые кнопки имеют ту же ширину, что и родительский контейнер, а некоторые зависят от содержимого (т.max-content)решенный. Для этого мы используемdisplayПри явном объявлении контейнеров Flexbox невозможно определить все контейнеры Flexbox какflex, лучший способ определить контекстное форматирование контейнера Flexbox в соответствии с формой пользовательского интерфейса:

.block-container {
    display: flex;
}

.inline-container {
    display: inline-flex;
}

Это также будет связано с будущимdisplayмодули совпадают,CSS Display Module Level 3ОпределенныйdisplayПринимаются два значения:

.block-container {
    display: flex; 
    
    /*相当于*/
    display: block flex;
}

.inline-container {
    display: inline-flex;
    /* 相当于 */
    display: inline flex;
}

Это очень значимо и важно для CSS. Таким образом, код может правильно интерпретировать взаимодействие блоков-контейнеров (блоков) с другими блоками (блоками), т. е. являются ли они блочными блоками или встроенными блоками, а также поведение дочерних элементов. для пониманияdisplayЧто и как и так понятно. Это также хорошо сочетается с формой визуальных элементов пользовательского интерфейса.

Контейнер flexbox должен быть объявлен правильно в соответствии с визуальной формой пользовательского интерфейса, не все контейнеры flexbox могут быть объявлены как блок-боксы!

Важно отметить, что контейнер flexbox для блочных и встроенных блоков также повысит масштабируемость flex-элементов, особенноflex-basisвлиятельный. Конкретное воздействие здесь объясняться не будет.Заинтересованные студенты могут прочитать:

Перенос строк в Flexbox

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

Это предсказуемое поведение, и нельзя сказать, что это проблема рендеринга, но оно отличается от того, что мы ожидали или ожидал дизайнер. Чтобы исправить это, просто явно установите контейнер flexbox.flex-wrapценностьwrap(его значение по умолчаниюnowrap):

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

Мы должны попробовать использовать на контейнере Flexboxflex-wrapчтобы избежать неожиданного поведения макета. Но следует отметить еще одну вещь:flex-wrap: wrapЭто работает только в том случае, если flex-элемент не может автоматически сжиматься и расширяться, другими словами, если это явно установлено в flex-элементе.flex: 1, даже если вы явно установили его для контейнера flexboxflex-wrapдляwrapТакже нельзя обернуть гибкие элементы:

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

.flex-item {
    flex: 1;
}

видео

Хотя явно установлено в контейнере flexboxflex-wrapдляwrapОн может предотвратить переполнение макета, но это не значит, что он установлен на всех контейнерах Flexbox, и должен быть психологический прогноз в конкретном процессе использования. Например, используется следующееflex-wrap: wrapЭффект:

На самом деле, лучший эффект должен быть:

flex-wrap: wrapнаткнулся наflex:1не оборачивает гибкие элементы в строки (или столбцы), дополнительно используйтеflex-wrap: wrapДолжен быть психологический прогноз, иначе UI может быть визуально некрасивым, но верстку не сломает!Выбор всегда болезненный (^_^)

flex:1Не обязательно поровну

В современных веб-макетах, особенно в макетах Flexbox, считается, что равномерное разделение столбцов (другими словами, равномерное деление контейнера, т.е. одинаковая ширина) явно задано в элементе Flex.flex: 1Вот и все.

.item {
    flex: 1;
}

Фактически? Это не должно быть так. Почему ты это сказал?

Путь очень глубокий, скажем такflex:1Ну, это эквивалентно:

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

Если не явно установленflex(этоflex-grow,flex-shrinkа такжеflex-basisсокращенное свойство), его начальное значение равно:

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

когдаflex-basisдляautoКогда ширина гибкого элементаmax-content. То есть,flex:1час,flex-basisстал0%, который переопределит внутренние размеры гибкого элемента (max-content), базовый размер гибкого элемента теперь0, но из-заflex-growсуществует, они оба могут увеличиваться, чтобы заполнить пустое пространство (оставшееся пространство flexbox). На самом деле, в этом случаеflex-shrinkбольше ничего не делает, так как все гибкие элементы теперь имеют ширину0, и растет, чтобы заполнить доступное пространство. Просто в контейнере Flexbox не осталось места или даже недостаточно места. В настоящее время,flex:1Также невозможно разделить контейнер Flexbox поровну. Например:

Как показано на скриншоте выше, ширина последнего гибкого элемента больше, а егоmax-contentбольше, чем другие гибкие элементы (шириной четыре китайских символа):

На самом деле это вызываетflexПограничные случаи нетрудно обнаружить, если вы достаточно внимательно прочитаете спецификацию W3C.Потому что это четко описано в спецификации W3C:

По умолчанию гибкие элементы не уменьшаются ниже минимального размера содержимого (длины самого длинного слова или элемента фиксированного размера).Чтобы изменить это, установите свойство min-width или min-height.

Примерно это означает: "По умолчанию элементы flex flex (установлено наflex:1Flex элемент) при сжатии его ширина не будет меньше минимального размера содержимого (т.min-width, то есть,max-contentили длина элемента фиксированного размера). Чтобы изменить это, вам нужно явно установитьmin-widthилиmin-heightзначение".

Эта ссылка связана, и она будет включатьmin-widthилиmin-heightценность . по умолчанию,min-width(илиmin-height) является значениемauto, он будет рассчитываться как0. Когда элемент является элементом Flex,min-widthилиmin-heightне рассчитывается как0, его значениеmax-content. Это вычисление, которое запускает перепад.

По этой причине, чтобы действительно добиться равномерного разделения столбцов, только явно установитеflex:1Еще нет, вам также нужно явно установить его на элементе flexmin-widthценность0:

.item {
    flex: 1;
    min-width: 0;
}

Это включает в себя знания многих аспектов CSS, например,Внутренние и внешние измерения в CSS, размеры CSS,CSSautoрассчитатьЖдать.

Однако, используяflex:1, требуется дополнительное внимание, посколькуflex:1когда это1будет считатьсяflex-growценность1. Лучше использовать жест, чтобы явно датьflexУстановите три значения, напримерflex: 1 1 0%илиflex: 1 1 100%.

.item {
    flex: 1 1 0%;
    min-width: 0;
}

Если вы сталкивались с макетом CSS Grid, вы, возможно, уже знаете уникальный CSS Grid.frБлок. Вы также можете разделить контейнер сетки поровну, как показано ниже, что делит контейнер сетки на пять равных частей:

.grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
}

Но есть также крайние случаи, такие как элементы Flex, которые должны быть действительно ровными. То есть явно установить на элементе Gridmin-widthдля0:

.item {
    min-width: 0;
}
See the Pen <a href="https://codepen.io/airen/pen/QWqJpYJ"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Для более подробного ознакомления с этим аспектом вы также можете прочитать@KevinJPowellиз"Равные столбцы с Flexbox: это сложнее, чем вы думаете".

Если вас интересует макет CSS Grid, вы можете прочитать "Нельзя пропустить CSS Grid Layouts в 2022 годуУчебные пособия серии Grid, перечисленные в файлах .

Минимальное значение во Flexboxmin-size

При использовании макета Flexbox очень вероятно, что текстовое содержимое одного из flex-элементов будет очень длинным и в конечном итоге приведет к переполнению содержимого.

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

/* ① 长单词断行,常用西文 */
.long-word {
    overflow-wrap: break-word;
}

/* ② 文本截取,末尾添加 ... */
.text-overflow {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ③ 多行文本截取,末尾添加... */

.line-clamp {
    --line-clamp: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: var(--line-clamp);
    -webkit-box-orient: vertical;
}

В таких случаях мы просто хотим, чтобы длинный контент (или длинные слова не портили макет страницы). Как показано ниже:

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

.text-overflow {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

Или ввели вредоносный контент, такой как подчеркнутые URL-адреса или цифры, буквы и т. д. без пробелов:

В таком макете, даже несмотря на то, что наш элемент заголовка является flex-элементом и был явно установленflex:

.card__title {
    flex: 1 1 0%;
}

Вы обнаружите, что значок с правой стороны карты все еще выдавлен из контейнера длинным содержимым (переполнение):

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

.long-word {
    overflow-wrap: break-word;
}

Вы обнаружите, что это не работает:

даже если вы добавитеhyphensдляautoтакже не подействовало.

Вы можете подумать, что это ошибка Flexbox, на самом деле,Соответствующее описание есть и в спецификации W3C.:

On a flex item whose overflow is visibleна главной оси, если указано на главной оси гибкого элементаmin-size property, specifies an automatic minimum size.

Грубо говоря: "Элементы Flex на главной осиoverflowсобственностьvisible, минимальный размер гибкого элемента на главной оси (min-size)будуУкажите автоматический минимальный размерМы также упоминали ранее:

По умолчанию элементы flex flex (установлено наflex:1Flex элемент) при сжатии его ширина не будет меньше минимального размера содержимого (т.min-width, то есть,max-contentили длина элемента фиксированного размера). Чтобы изменить это, вам нужно явно установитьmin-widthилиmin-heightценность .

Поэтому для решения этой задачи необходимо использоватьoverflow-wrapдляbreak-wordместо для сбросаmin-widthценить и заставить его стать0:

.long-word {
    overflow-wrap: break-word;
    min-width: 0;
}

Также следует отметить, что проект Flexoverflowценностьvisibleзначения, отличные отmin-widthценность0, поэтому при перехвате текста в методе ② почему нетmin-width: 0.

Разрыв строки в Интернете также является сложной системой, включающей множество свойств CSS, таких какwhite-space,overflow-wrap,hyphens,word-breakа такжеline-breakЖдать. W3CCSS Text Module Level 3Эти свойства определены и подробно описаны. Также рекомендуем прочитать@frivoalОдна из тем, которыми делились в прошлом»line breaking".

Продолжая возвращаться к этой теме, длинный текст элемента Flex (max-content) или явно задатьwhite-space: nowrapПомимо визуального нарушения макета, он также сжимает соседние гибкие элементы, даже если эти гибкие элементы имеют явный размер. Как в примере выше:

.card__media {
    width: 4em;
    aspect-ratio: 1;
}

.card__action {
    width: 3em;
    aspect-ratio: 1;
}

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

Это вызвано тем, что заголовок (который также является гибким элементом) слишком длинный (max-content), в контейнере flexbox не осталось места для его размещения, а другие flex-элементы на той же оси в это время будут сжаты. Как мы все знаем, проект FlexflexЗначение по умолчанию:

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

flex-shrinkценность1, указывающий, что гибкий элемент можно свернуть. Чтобы решить это явление, у нас есть два способа, самый простой из которых — явно установить заголовок элемента элемента flex.min-widthценность0:

.card__title {
    min-width: 0;
}

Другим решением является явное заданиеwidthилиheightсбросить на гибком элементеflex-shrinkценность0, Сообщает браузеру, что даже если в контейнере Flexbox недостаточно свободного места, вы не сможете втиснуть свое пространство:

.card__media,
.card__action {
    flex-shrink: 0;
}

Условно говоря, или раз и навсегда решениеявно установленflex: 1Элемент Flex явно установленmin-widthценность0.

See the Pen <a href="https://codepen.io/airen/pen/ZEXmNzd"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Прокрутка в Flexbox не работает

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

Содержимое в красной пунктирной рамке на рисунке прокручивается. Поскольку высота контейнера фиксирована (100vh), содержимое, вероятно, превышает высоту контейнера.

При восстановлении UI и взаимодействия этого компонента для вёрстки также используется первый дочерний Flexbox, я явно задал его на скролл-контейнере.flexдля1:

явно задан в контейнере прокруткиoverflow-yдляscrollЭто также не возымело действия (баг был обнаружен в системе iOS на тот момент). Только позже выяснилось, что это был всего лишь крайний случай, который запустил проект Flex. Конечно, для достижения этого требования у него есть определенные требования к структуре HTML:

HTML-код, соответствующий приведенной выше структурной схеме, выглядит следующим образом:

<div class="main-container"> <!-- flex-direction: column -->
    <div class="fixed-container">Fixed Container</div> <!-- height: 100px; -->
    <div class="content-wrapper"> <!--  min-height: 0; -->
        <div class="overflow-container">
            <div class="overflow-content">
            Overflow Content
            </div>
        </div>
    </div>
</div>

Ключевой код CSS:

.main-container {
    display: flex;
    flex-direction: column;
}

.fixed-container {
    height: 100px;
}

.content-wrapper {
    display: flex;
    flex: 1;
    min-height: 0; /* 这个很重要*/
}

.overflow-container {
    flex: 1;
    overflow-y: auto;
}

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

See the Pen <a href="https://codepen.io/airen/pen/KKKGeRO"> Overflow And Flex</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Ключевая частьуже настроенflex: 1Элементы Flex должны быть явно установленыmin-heightценность0, родительский элемент контейнера прокрутки. На самом деле это крайний случай макета Flexbox.

Обратите внимание, что после установкиflex:1Проект Flex должен сбросить свойmin-sizeзначение (когда главная ось находится в горизонтальном направлении (flex-direction: row),настраиватьmin-width, когда главная ось находится в вертикальном направлении (flex-direction: column),настраиватьmin-height), которые обычно сбрасываются на0.

Другой способ прокрутки аннулирования в макете flexbox -flex-end. Я сам не сталкивался с этим случаем и не проверял такой сценарий. Я также видел учителя @zhangxuxin's "flex-end, почему переполнение не может прокручиваться, и решение"Статья для ознакомления. Просто взгляните на этот случай вкратце.

<!-- HTML -->
<Container>
    <Card />
    <Card />
    <Card />
    <Card />
</Container>

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

.container--row {
    overflow-x: scroll;
}

.container--column {
    flex-direction: column;
    overflow-y: scroll;
}

Это нормально, без использования каких-либо свойств, связанных с выравниванием, таких какjustify-content. Весь эффект выглядит следующим образом:

Чтобы сделать прокрутку ближе к собственному клиенту, в примере сделаны некоторые оптимизации для прокрутки, например, использование контейнера прокрутки.overscroll-behaviorОсобенности, связанные с привязкой прокрутки. Если вам это интересно, вы можете прочитатьНовые функции прокрутки, меняющие пользовательский опыт" и "Захват прокрутки CSS:Part1а такжеPart2".

Если мы прокручиваем контейнер.containerЯвно установленоjustify-contentценностьflex-end:

.container {
    justify-content: flex-end;
}

В это время прокрутка не удалась:

Вам может быть интересно, почему это происходит?

Как упоминалось в учебнике г-на Чжан Сюйсиня. В Интернете мы пишем и читаем слева направо (LTR), сверху вниз. То есть в нормальных условиях (без учета других режимов письма) содержимое в горизонтальном направлении переливается вправо, а содержимое в вертикальном направлении переливается вниз, т. е.При разработке полосы прокрутки было решено, что прокручивать нужно только содержимое ниже (или справа) от контейнера..

В контейнере прокрутки (который является контейнером flexbox) явно установленjustify-content: flex-end(направление шпинделя отflex-startзаменяетсяflex-end). Это ведет к,Если над или слева есть содержимое, превышающее предел размера контейнера, полоса прокрутки не изменится.. Так,Направление, в котором содержимое в контейнере прокрутки переполняет контейнер, находится не ниже или справа от контейнера, а сверху и слева от контейнера, поэтому, естественно, полоса прокрутки не может быть активирована.. вообще говоря,flex-endЭто приведет к переполнению содержимого в обратном порядке, и не будет полосы прокрутки, и, естественно, она не будет прокручиваться:

В этом случае на самом деле очень просто заставить прокручиваемый контейнер нормально прокручиваться.margin: autoВот и все.在Flex项目是显式设置marginценностьautoОн имеет уникальный эффект, как показано на следующем рисунке:

Решение очень простое, выравнивание начинается с выравнивания по умолчанию, т.е.justify-contentне установленоflex-end, возьмите значение по умолчанию, затем используйтеmargin: autoдобиться чего-то вродеjustify-content: flex-endЭффект выравнивания. В нашем примере необходимо установить только первый элемент гибкости.margin-left(горизонтальная ориентация) илиmargin-top(вертикальное направление) значениеauto:

.container--row .card:first-child {
    margin-left: auto;
}

.container--column .card:first-child {
    margin-top: auto;
}
See the Pen <a href="https://codepen.io/airen/pen/VwMqepY"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Нажмите кнопку в примере для динамического добавления карточек:

Защитный CSS, связанный с макетом сетки

CSS Grid в настоящее время является единственной технологией двумерной компоновки в Интернете. Он уже поддерживается современными массовыми браузерами, и в 2021 году я трачу почти полгода,Более 20 статей используются для объяснения базовых знаний и связанных с ними приложений макета CSS Grid.Снова чувствую ее мощное место.

По правде говоря, она мощная, но и сложная. Конечно, у нее есть и много менее известных сторон. уже в 2019 году@Мануэль Матузовичиспользовал серию (в настоящее время завершенаPart1а такжеPart2, и некоторые незавершенные ), чтобы проиллюстрировать некоторые из менее известных вещей о макете CSS Grid.

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

сетка или встроенная сетка

gridа такжеinline-gridСлишкомdisplayИх свойства и введенные граниflexа такжеinline-flexнесколько похоже.gridа такжеinline-gridОба используются для явного объявления контейнера сетки, то есть для создания контекста форматирования сетки (GFC). Разница между ними заключается в следующем:

  • gridСозданный контейнер сетки представляет собой блок-бокс, а ширина контейнера сетки равна ширине родительского контейнера (при условии, что родительский контейнер не выполняет другую обработку контекста форматирования).
  • inline-gridСозданный контейнер сетки представляет собой встроенный блок, ширина контейнера сетки будет определяться максимальной шириной, которую он имеет (max-content) дочерних элементов (элементов сетки), чтобы определить

который:

.block-container {
    display: grid; 
    
    /*相当于*/
    display: block grid;
}

.inline-container {
    display: inline-grid;
    /* 相当于 */
    display: inline grid;
}

Но они такие же, как и во Flexboxflexтак же какinline-flexЕсть явные отличия:

  • Макет Flexbox, будь тоflexещеinline-flex, по умолчанию все гибкие элементы будут расположены на главной оси (одна строка или один столбец)
  • Макет сетки, будь тоgridещеinline-grid, по умолчанию не изменит расположение элементов Grid, которые будут в исходном порядке в структуре HTML, если вы явно не используетеgrid-template-*(Например,grid-template-columns,grid-template-rowsилиgrid-template-areas) изменить его расположение

** В CSS Grid, если не используетсяgrid-template-*Явно определите дорожки сетки, затем независимо отdisplayЗначениеgridещеinline-grid, которые отображаются в исходном порядке HTML ** !

Обратите внимание на фиксированное значение дорожки сетки

Существует много способов определить дорожки сетки CSS Grid, за исключением явного использованияgrid-template-*В дополнение к свойствам, определяющим дорожки сетки, вы также можете использоватьgrid-*(Напримерgrid-row,grid-columnилиgrid-area) определяется номером линии сетки (или именем), именем области сетки. Кроме того, метод настройки размера дорожки также очень гибкий, например:

  • значения длины с разными единицами измерения, такими какpx,em,rem,%,vwи т. д. Существуют также единицы, уникальные для макетов сеткиfr
  • ключевые слова, такие какnone,auto,min-contentа такжеmax-content
  • CSS-функции, такие какfit-content(),minmax(),repeat(),min(),max()а такжеclamp()Ждать

Поэтому, чтобы сделать вашу CSS Grid более гибкой (более адаптируемой), при определении дорожек сетки следует максимально использовать внутренние размеры, то есть использовать ключевые слова и функции CSS. Используйте общий случай макета (например,Medium) Уточнить.

Есть много способов добиться эффекта макета изображения выше в CSS, самый простой из них:

.container {
    padding-left: 20px;
    padding-right: 20px;
    width: 100%;
    max-width: 60ch;
    margin-left: auto;
    margin-right: auto;
}

.container--full {
    width: 100%;
}

Эта схема проста, но имеет определенные требования к конструкции. Если мы используем CSS Grid, он станет более гибким, например:

:root {
    --gap: 20px;
    --minWidth: 60ch;
}

.container {
    display: grid;
    gap: 20px;
    grid-template-columns: 1fr min(var(--minWidth), calc(100% - var(--gap) * 2)) 1fr;
}

.container > * {
    grid-column: 2;
}

.container > .full {
    grid-column: 1 / -1;
}
See the Pen <a href="https://codepen.io/airen/pen/wvrOgMQ"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

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

Если вы поместите пример вmin()функция вместо этогоclamp()функцию, вы также можете выбрать значение в интервале, например ширину контейнера содержимого в23ch ~ 65chмежду:

.container { 
    --limit-max-container-width: 65ch; 
    --limit-min-container-width: 23ch; 
    --gutter: 1rem; 
    display: grid; 
    grid-template-columns: 1fr clamp( 
        var(--limit-min-container-width), 
        100% - var(--gutter) * 2, 
        var(--limit-max-container-width) ) 1fr; 
    gap: var(--gutter); 
}

Вы также можете поставитьmin()а такжеminmax()Использовать в сочетании с:

.container { 
    --limit-max-container-width: 65ch; 
    --limit-min-container-width: 23ch; 
    --gutter: 1rem; 
    display: grid; 
    grid-template-columns: 1fr minmax(min(var(--limit-min-container-width), 100% - var(--gutter) * 2), var(--limit-max-container-width)) 1fr; 
    gap: var(--gutter); 
}
See the Pen <a href="https://codepen.io/airen/pen/yLzwbBj"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

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

Если вы используете CSS Grid для разметки, обычно это выглядит так:

.container {
    display: grid;
    gap: 1rem;
    grid-template-columns: 250px 1fr;
    grid-template-areas: "sidebar "main";
}

Однако, если размер области просмотра браузера мал, могут возникнуть проблемы со стилем из-за нехватки места. Чтобы избежать этого, в макетах CSS Grid часто используются медиа-запросы:

.container {
    display: grid;
    gap: 1rem;
    grid-template-areas: 
        "sidebar"
        "main";
}

@media (min-width: 760px) {
    .container {
        grid-template-columns: 250px 1fr;
        grid-template-areas: "sidebar main";
    }
}
See the Pen <a href="https://codepen.io/airen/pen/XWeGRgQ"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Измените размер окна браузера, эффект будет следующим:

В приведенном выше примере мы можем сделать ширину боковой панели более гибкой. При определении размера боковой панели вы можете использоватьfit-content()функция, поставитьgrid-template-columns: 250px 1fr;Замените его на:

.container {
    grid-template-columns: fit-content(250px) 1fr;
}

в кодеfit-content(250px)эквивалентноmin(max-content-size, max(min-content, 250px)). в:

  • ①:max()Параметры функцииmin-content(первый аргумент) и250px(второй параметр), аmax()Функция возвращает больший из двух параметров.
  • ②:max()Возвращаемое значение будет помещено вmin()функция, т.е.max()Возвращаемое значение становитсяmin()Второе значение функции, которое будет таким же, как и максимальный размер содержимого (max-content-size) для сравнения, что является фактической шириной из-за ограничений сетки, но не болееmax-content.min()функция иmax()Аналогично, за исключением того, что возвращает меньшее значение

следовательно,fit-content(250px)Для описания более удобно использовать следующую формулу:

fit-content(200px) = min(min(max-content, available-size), max(min-content, 200px))

в формулеavailable-sizeОтносится к доступной ширине в сетке.

В дополнение к этому в спецификации приведена еще одна формула для описания функции fit-content():

fit-content(<length-percentage>) = max(minimum, min(limit, max-content))

в:

  • ①:minimumозначает автоматическое минимальное значение (обычно, но не всегда равноеmin-contentминимальное значение)
  • ②:limitпередается в качестве параметраfit-content()параметры, то есть<length-percentage>, как в примере250px
  • ③:min()вернутьlimitа такжеmax-contentменьшие значения в , такие как этот пример,min()то, что возвращается250pxа такжеmax-contentменьший
  • ④:max()вернуть даminimumа такжеmin(limit, max-content)большее из двух значений

Если приведенное выше описание не легко понять, мы можем понять его таким образом. например как в примереfit-content(250px), что указывает на то, что ширина дорожки сетки столбцов не будет превышать250px, и может быть сужен до250pxпоследующий.

See the Pen <a href="https://codepen.io/airen/pen/KKXEmOE"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

использоватьfit-content()Перед эффектом контраста:

вообще говоря,В макете CSS Grid при определении размеров дорожки сетки старайтесь не использовать внешние размеры (например, установку фиксированного значения длины).<length>), следует использовать внутренние размеры везде, где это возможно (например,min-content). Даже если вы не используете внутренние размеры, вам следует как можно больше комбинировать функции CSS (например,min(),max()а такжеclamp()и т. д.), чтобы повысить гибкость и адаптируемость размера дорожек сетки.!

Если вы хотите узнать больше о функциях CSS, используемых в примерах, вы можете прочитать:

Разрывы строк в сетке

Прежде всего, упомянутые здесь разрывы строк не относятся к разрывам строк текста или слов.

Как упоминалось ранее, в макете flexbox, если вы хотите сделать разрыв макета, вам нужно явно установить его в контейнере flexbox.flex-wrapдляwrap.

.cards {
    --gap: 18px;
    --columns: 3;
    --min-width: 220px;

    display: flex;
    flex-wrap: wrap;
    gap: var(--gap);
}

.card {
    flex: 1 1 calc((100% - var(--gap) * (var(--columns) - 1)) / var(--columns));
    min-width: var(--min-width);
}
See the Pen <a href="https://codepen.io/airen/pen/XWeGaNV"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Изменяя интервал, количество столбцов и минимальную ширину карты или размер контейнера, макет пользовательского интерфейса можно настроить автоматически:

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

Хотя есть много решений (можете почитать г-на Чжан Сюйсиня "N способов выровнять последнюю строку списка в гибком макете CSS по левому краю», но по сравнению с CSS Grid гибкость гораздо меньше.

В макете CSS Grid приведенный выше пример сценария макета (называемый разрывом строки) является естественным. Просто при определении дорожки сетки, вrepeat()используется в функцииauto-fillилиauto-fitКлючевые слова.

  • auto-fill: количество повторений — это максимально возможное положительное целое число, которое не приводит к переполнению контейнера сетки, если контейнер сетки имеет определенный размер или максимальный размер на соответствующей оси. Если определено, рассматривайте каждую дорожку как функцию ее максимального размера дорожки (grid-template-rowsилиgrid-template-columnsдля каждого определенного значения. В противном случае к расчету добавляется зазор сетки в зависимости от минимального размера дорожки.Если повторений слишком много, значение повторения1. В противном случае, если контейнер сетки имеет определенный минимальный размер на соответствующей оси, число повторений равно наименьшему возможному положительному целому числу, удовлетворяющему этому минимальному требованию. В противном случае указанный список дорожек повторяется только один раз.
  • auto-fit: поведение иauto-fillТо же самое, за исключением того, что после размещения элементов сетки все пустые повторяющиеся дорожки сворачиваются. Пустые дорожки — это элементы сетки, которые не перетекают в сетку и не охватывают сетку. (Если все дорожки пусты, это может привести к сворачиванию всех дорожек.) Считается, что свернутая дорожка имеет одну функцию фиксированного размера дорожки, т.к.0px, прорези с обеих сторон загнуты. Чтобы найти количество дорожек для автоматического повторения, пользовательский агент ограничивает размер дорожки до значения, указанного пользовательским агентом (например,1px), чтобы избежать деления на ноль.

вообще говоря,auto-fitбудет расширять элементы сетки, чтобы заполнить доступное пространство, в то время какauto-fillЭлементы сетки не раскрываются. Напротив,auto-fillДоступное пространство будет сохранено без изменения ширины элементов сетки. Например, на рисунке ниже видно, чтоauto-fitа такжеauto-fillРазница:

увидеть еще одинauto-fitа такжеauto-fill, т.е. когда в контейнере сетки несколько и только один элемент сетки, используйтеauto-fillа такжеauto-fitРазница:

Мы можем использовать эту функцию для модернизации предыдущего примера упаковки Flexbox:

.cards {
    --gap: 18px;
    --min-width: 220px;

    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--min-width), 1fr));
    gap: var(--gap);
}
See the Pen <a href="https://codepen.io/airen/pen/mdBoBaM"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

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

Возможно, вы уже обнаружили, что в приведенном выше примере есть небольшой недостаток,Когда ширина контейнера сетки меньше минимальной ширины карточки, в контейнере сетки появится полоса прокрутки, либо карточка будет перехвачена.为了让布局的灵活性,可防御性更强,我们可以在minmax()используется в функцииmin(), и датьmin()функция передана вvar(--min-width)а также100%два значения. мы знаем,100%вычисляется относительно ширины родительского контейнера, иmin()Функция будет принимать меньшее значение, то есть когда контейнер сетки меньше определенного значения,min()функция прибудет100%Это значение равно ширине родительского контейнера:

.cards {
    --gap: 18px;
    --min-width: 220px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(var(--min-width), 100%), 1fr));

    gap: var(--gap);
}
See the Pen <a href="https://codepen.io/airen/pen/qBPvVZR"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Перетащите ползунок в правом нижнем углу контейнера сетки в примере, когда ширина контейнера сетки меньше--min-widthМакет UI также будет подстраиваться автоматически, и карта не будет перехватываться контейнером или у контейнера будут полосы прокрутки:

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

.section {
    min-width: 180px;
}

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

О сетке CSSauto-fitа такжеauto-fillДля более подробного ознакомления вы можете прочитать "CSS Grid: функции в сетке" статья.

Минимальная ширина в сетке

Как и в макете Flexbox, минимальное значение по умолчанию для содержимого дочерних элементов (элементов сетки) в CSS Grid равноauto. То есть, если размеры элемента превышают элементы сетки, также произойдет переполнение содержимого.

Как показано выше, область контента (Main) содержит карусель (Carousel) с функцией карусели. Код HTML и CSS выглядит следующим образом:

<!-- HTML -->
<div class="wrapper">
    <main>
        <section class="carousel"></section>
    </main>
    <aside></aside>
</div>

/* CSS */
@media (min-width: 1020px) {
    .wrapper {
        display: grid;
        grid-template-columns: 1fr 248px;
        grid-gap: 40px;
    }
}

.carousel {
    display: flex;
    overflow-x: auto;
}

Так как Carousel является неразрывным flexbox-контейнером, его ширина превышает основную область контента (Main), и элементы сетки будут следовать за ней. Следовательно, появляется горизонтальная полоса прокрутки. Есть три разных решения этой проблемы:

  • использоватьminmax()функция
  • Явно устанавливается для элементов сеткиmin-width
  • Явно устанавливается для элементов сеткиoverflow: hidden

В качестве защитного механизма CSS я выбрал первый, используяminmax()функция:

@media (min-width: 1020px) {
    .wrapper {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 248px;
        grid-gap: 40px;
    }
}

Макет CSS Grid имеет уникальную единицу измерения длины, котораяfrединица, которую можно сравнить с%объединились, чтобы понять. вообще говоря:

1индивидуальныйfr(который1fr)то есть100%свободное пространство грид-контейнера;2индивидуальныйfr(который2fr) каждый50%Свободное пространство грид-контейнера, т.е.1frда50%Свободное пространство контейнера сетки. Подобно этому, если у вас есть25индивидуальныйfr(который25fr), то каждыйfr(1fr)то есть1/25или4%.

Мы можем использовать круговую диаграмму для описания сетки.frединица измерения:

Обратите внимание, что круговая диаграмма (круг) эквивалентна доступному пространству контейнера сетки, а количество делений эквивалентно дорожке сетки с установленным коэффициентом эластичности..

В CSS Grid мы можем использоватьfrсделать эффект выравнивания, аналогичный тому, что во Flexboxflex:1. Однако, используяfrПри выполнении равномерно разделенных столбцов вам необходимо явно установить его в соответствующем элементе сетки.min-widthценность0.

позиция: липкая в сетке

CSS Positioned Layout Module Level 3серединаpositionнедавно добавленныйstickyсвойство, с точки зрения выражения, этоrelativeа такжеfixedКомбинация случая по умолчанию ведет себя какrelative, но при соблюдении определенных условий его проявление аналогичноfixed. Но установите элемент сетки в макете CSS Grid.positionдляsticky, его поведение рендеринга отличается от того, что вы понимаете, или поведения рендеринга элементов, не являющихся сетками.

Учащиеся, знакомые с макетом CSS Grid, должны знать, что по умолчанию элементы сетки растягиваются. Как было представлено ранееfit-content()Как показывает пример,<aside>а также<main>Высота двух элементов сетки равна высоте контейнера сетки (даже если содержимого недостаточно для его хранения):

и что мы понимаемposition, в АфрикеstaticПри значении он будет вне потока документа.Наиболее интуитивный эффект заключается в том, что его размер определяется размером содержимого без явной установки размера. Другими словами, если явно задан элемент сеткиpositionдляsticky, чтобы заставить его вести себя так, как мы ожидаем, нам нужно явно установить его в элементе сеткиalign-selfценностьstart:

aside {
    align-self: start;
    position: sticky;
    top: 0;
}
See the Pen <a href="https://codepen.io/airen/pen/poWYLgX"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Конкретный эффект заключается в следующем:

интервал

Всегда было привычно использовать интервалы между элементамиmarginилиpadding, но во многих случаяхmarginа такжеpaddingНе очень гибкий, особенно в макетах Flexbox и Grid. В макетах Flexbox и Grid используйтеgapчтобы установить расстояние между элементами будет меньше, чемmarginЧтобы быть гибким:

Как показано на рисунке выше, если между элементом Flex или элементом Grid и контейнером нет промежутка, между элементом и элементом есть определенное пространство, а затем используйтеgapявляется лучшим.

.flex--container {
    display: flex;
    gap: 20px;
}

.grid--container {
    display: grid;
    gap: 20px;
}

Вообще говоря,gapОн подходит для большинства сценариев, поскольку основной технологией компоновки является Flexbox или Grid. Но многое тормозит развитиеgapСовместимость, особенно в не-Flexbox, Grid и многоколоночных макетах, больше пользыmarginустановить расстояние между элементами. Возьмите приведенные ниже примеры.

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

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

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

.title {
    margin-right: 1rem;
}

Обратите внимание, что если заголовок и кнопка являются элементами Flex или элементами сетки, то установите их явно в родительском контейнере.gapбыло бы лучше. Если нет, мы должныmarginПреимущество этого, установленного на элементе кнопки, заключается в том, что заголовок не имеет дополнительного интервала независимо от того, существует кнопка или нет:

.button {
    margin-left: 1rem;
}

В дополнение к настройке интервала, как указано выше, вы также можете использовать селекторы CSS, расположенные рядом с селекторами (+) устанавливатьmargin:

.title + .button {
    margin-left: 1rem;
}

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

Мы можем установить расстояние между кнопками следующим образом:

.button + .button {
    margin-left: 1rem;
}

Там сказано: "Если одна кнопка рядом с другой, на всякий случай добавьте вторую кнопкуmargin-leftНа самом деле в веб-разработке таких сценариев много.

Интервал можно установить таким же образом:

.cards + .cards {
    margin-top: 20px;
}

.card + card {
    margin-left: 20px;
}

Кроме того, в веб-макете есть сценарии, подобные следующему изображению, которые будут устанавливать отступы в контейнере (padding), затем установитеmargin-bottom, что приводит к значительно большему зазору между последним элементом и контейнером:

Код может быть написан так:

.cards {
    padding: 20px;
}

.card {
    margin-bottom: 20px;
}

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

.cards {
    padding: 20px;
}

.card:not(:last-child) {
    margin-bottom: 20px;
}

/* 或者 */

.card:not(:first-child) {
    margin-top: 20px;
}

Кроме этого, немного лучше использовать соседние селекторы:

.cards {
    padding: 20px;
}

.card + .card {
    margin-top: 20px;
}

В частности, лучшийgap. Однако пока его можно использовать только во Flexbox, Grid и многоколоночных макетах..

Продолжайте использовать приведенную выше карту в качестве примера. в каждой карточке (.card) может быть установлен на определенныйpaddingзначение, но иногда по какой-то причине данные (контент) на карту не выводятся нормально, поэтому эффект вывода может быть следующим:

Чтобы избежать этого явления на картинке выше, мы можем использовать селектор псевдокласса:emptyСбросить заполнение карты на0:

.card {
    padding: 12px;
}

.card:empty {
    padding: 0;
}

В селекторах псевдоклассов CSS, за исключением:emptyКроме того, есть селектор псевдокласса, аналогичный:blank, но пока поддерживает:blankСелекторов очень мало. Если вас интересуют эти два селектора, пожалуйста, прочитайте "Селектор псевдокласса CSS::empty vs. :blank" статья.

Вернемся к макету CSS Flexbox и CSS Grid, в макете Flexbox и Grid, за исключениемgap,marginПомимо установки интервала между элементами Flex или элементами сетки, вы также можете использоватьCSS Box Alignmentчтобы контролировать расстояние между ними:

Хотя с помощью свойств CSS Box Alignment можно управлять расстоянием между элементами, например, в контейнере Flexbox, используйтеjustify-contentХранение элементов Flex отдельно друг от друга не означает, что это идеально. Например, когда количество гибких элементов фиксировано, макет выглядит нормально. Однако когда количество flex-элементов увеличивается или уменьшается, макет может выглядеть очень странно. Например, как показано на рисунке ниже, в контейнере flexbox есть четыре flex-элемента, и расстояние между flex-элементами не определяетсяgapилиmarginбыть под контролемjustify-contentзначение для управления, напримерspace-between:

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

Давайте посмотрим на его странный сценарий, например, количество flex-элементов меньше, чем4Когда это происходит, эффект, который он представляет для пользователя, выглядит следующим образом:

Кромеspace-betweenКроме того, естьspace-aroundа такжеspace-evenlyЕсть похожее явление.

Как показано на рисунке выше, в некоторых сценариях (слишком мало или слишком много элементов Flex) этот эффект не является дружественным, но мы можем справиться с ним следующими способами:

  • marginУстановите поля (но нужны дополнительные хитрости, вы можете прочитать "Flexbox gutters and negative margins, mostly solved"Одна статья)
  • Установить в контейнере Flexbox (или контейнере Grid)gap
  • Добавьте пустые элементы, чтобы занять место

Проще всего использоватьgap:

.wrapper {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

Вы заметили, что в предыдущем примере «аннулирование прокрутки во flexbox», хотя мы явно установилиpaddingзначение, но с правой стороны по горизонтали и с нижней стороны по вертикали в контейнере прокруткиpaddingПо-видимому, потеряно во время визуального представления:

Чтобы избежать этого явления, необходимо применятьpaddingзаменитьborder:

.scroll-container {
    border: 20px solid transparent;
}

Или измените его HTML-структуру, чтобы добавить элемент-оболочку вне контейнера прокрутки:

<!-- HTML -->
<scroll-container-wrapper>
    <scroll-container>
    </scroll-container>
</scroll-container-wrapper>

и поместите использование контейнера прокруткиpaddingв свой упаковочный контейнер:

scroll-container-wrapper {
    padding: 20px
}

Избегайте использования фиксированных размеров

Многие веб-разработчики (особенно неопытные веб-разработчики) предпочитают явно устанавливать элементыwidthа такжеheightдля контроля размера. Это явление еще более распространено в некоторых приложениях Low-Code и D2C (Design To Code). Но, как знает немного опытный веб-разработчик, явно установив его для элементаwidthа такжеheightлегче всего сломать макет.

Эскиз конструкции предоставлен дизайнером, каждый слой (примерный элемент) установленwidthа такжеheightзначение, и эффект в порядке. Но на практике содержание элементов в Сети не такое фиксированное, как в дизайн-проекте, оно динамично и имеет разную длину. То есть при восстановлении черновика дизайна пользовательского интерфейса, если вы установите фиксированный размер для элемента в соответствии с информацией о слое черновика дизайна (widthа такжеheight), это приведет к разрушению макета. Например следующая ситуация:

Чтобы контент не выходил за пределы контейнера, нам нужно использоватьmin-heightзаменитьheight:

.hero {
    min-height: 350px;
}

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

Точно так же при установке ширины элемента ее также следует максимально использовать.min-widthзаменитьwidth. Например, при построении<Button>Когда компонент, вы, возможно, столкнулись с текстом и пробелами слева и справа (без явных настроек)paddingCase) будет выборочно использоваться на кнопкеwidthУстановите фиксированное значение:

.button {
    width: 100px;
}

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

Пучокwidthзаменитьmin-widthЭто явление не произойдет:

.button {
    min-width: 100px;
}

Если он находится в макете Flexbox или Grid, лучше установить максимально фиксированное значение Лучшее решение — использовать внутренний размер для определения размера элемента.

Подробнее об этом вы также можете прочитать:

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

.panel {
    transition: height .2s ease-out;
}

.panel.collapsed {
    height: 0;
}

В таком коде нет эффекта перехода, просто скачок между двумя размерами. Обратите внимание, что это явление возникает, когда элемент начинается и заканчивается.heightдляauto.

heightзначение в других единицах, таких какpx,%Или другие абсолютные единицы могут работать должным образом. Но в реальном производстве, когда мы кодируем, мы не можем предсказать ни содержимое элемента, ни его высоту. Другими словами, если вы явно устанавливаете фиксированное значение, например300px, то макет может сломаться из-за слишком большого количества контента.

В CSS у нас есть несколько решений, позволяющих избежать этого явления:

  • использовать разумныйmax-heightзаменитьheight
  • использоватьtransform: scaleY()

Например:

.collapsible {
    transition: transform 0.5s ease-out;
    transform-origin: top left;
}

.collapsed {
    transform: scaleY(0);
}

Кроме того, часто используются некоторые эффекты аккордеона (Accordion), написанные на чистом CSS.max-heightзаменятьheight:

p {
    max-height: 800px;
    opacity: 1;
    transition: all 500ms ease;
}

input[type=checkbox]:checked ~ p {
    max-height: 0;
    opacity: 0;
}
See the Pen <a href="https://codepen.io/Pavan_Yuvan/pen/gPMdxR"> CSS only Accordion (No JavaScript)</a> by Pavan teja (<a href="https://codepen.io/Pavan_Yuvan">@Pavan_Yuvan</a>) on <a href="https://codepen.io">CodePen</a>.

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

Если вы хотите изменитьwidthДобавьте плавный переход, вышеописанный способ также применимwidth. Самый простой способ использованияmax-widthзаменятьwidth.

Защитный CSS для изображений

Картинки стали важным средством в Интернете.Как говорится, картинка стоит тысячи слов.Есть много способов использовать изображения в Интернете, в дополнение к HTML<img>Изображения могут быть представлены за пределами Интернета, а HTML5 также добавляет<picture>элемент, предоставляющий вам больше возможностей и способов использования изображений в Интернете. Есть также довольно много свойств, которые обслуживают изображения в CSS. Например:

  • использоватьbackground-imageа такжеmask-imageРазмещение изображений в Интернете
  • использоватьbackground-size,mask-size,object-fitи т. д., чтобы контролировать размер изображения
  • использоватьbackground-position,mask-position,object-positionи т. д. может контролировать положение изображения
  • использоватьbackground-repeat,mask-repeatВы можете контролировать расположение изображений
  • так далее...

Использование этих свойств может помочь нам защищаться при работе с веб-изображениями.

Предотвращение растяжения или сжатия изображений

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

Когда пользователь загружает изображение другого размера, изображение будет растянуто (или даже искажено).

Для этого явления можно использоватьobject-fitрешать:

.card__thumb {
    object-fit: cover;
}

Есть некоторыеСбросить CSS в, нравитсяobject-fitприменить ко всемуimgэлемент, чтобы избежать случайного растяжения или сжатия изображений в Интернете:

img {
    object-fit: cover;
}

Это хороший выбор, но это не значит,object-fit:coverПрименимо ко всем сценариям. Иногда также необходимо сделать правильный (или соответствующий) выбор в зависимости от случая. Например@Ahmad ShadeedЕще одна запись в блоге от "Aligning Logo Images in CSS". Пусть изображение логотипа продукта будет лучше представлено в Интернете, как показано на следующем рисунке:

В это время используйтеimgВверхobject-fitатрибутcontainчемcoverБолее подходящий:

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

В таком сценарииobject-fitстоимостьcontainПреимущество заключается в том, что изображение логотипа включается независимо от ширины или высоты и не искажается.

Специальное заявление, вbackground-sizeа такжеmask-sizeИз двух свойств значение также может бытьcoverа такжеcontain, как использовать иobject-fitпохоже, разница естьbackground-sizeдля фоновых изображений,mask-sizeИспользуется для маскировки изображений. Кроме того,object-fitкроме как взятьcoverа такжеcontainКроме того, вы также можете взятьfill,scale-downа такжеnoneэквивалент.

Конечно, некоторые сценарии также не подходят для использованияobject-fit,background-sizeилиmask-sizeиз. Например, если для элемента или изображения явно задано фиксированное значение высоты. В это время используйтеbackground-size: coverилиobject-fit: coverКартинка будет слишком широкой, из-за чего на картинке будут потеряны важные детали, что может повлиять на восприятие картинки пользователем.

.card__thumb {
    height: 220px;
}

Как показано на рисунке выше, поскольку изображение имеет фиксированную высоту, на этот разobject-fit: coverРасширение изображения также приводит к увеличению ширины компонента карточки. Такое поведение вызвано тем, что явно не указано соотношение сторон. мы можем использоватьCSSaspect-ratioчтобы избежать этого явления:

.card__thumb img {
    aspect-ratio: 4 / 3;
}

Обратите внимание, что реализация соотношений сторон в CSS не является вариантом, за исключением использованияaspect-ratioКроме того, есть еще некоторые способы взлома, если вас это интересует, вы можете прочитать "Несколько схем для CSS для достижения соотношения сторон" статья.

Не забудьте *-повторить

здесь*-repeatОтносится к CSS вbackground-repeatа такжеmask-repeat!

В общем, при использовании большего изображения в качестве фонового изображения не забудьте проверить, как страница будет выглядеть на большом экране. Изображение используется в качестве фона и повторяется по умолчанию, потому чтоbackground-repeatЗначение по умолчаниюrepeat.

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

Чтобы этого избежать, нужно явно указатьbackground-repeatценностьno-repeat:

.hero {
    background-image: url('..');
    background-repeat: no-repeat;
}

Обратите внимание, что если вы разрабатываете, используйте CSSmaskсвойств, то такое явление будет проявляться и вmask-repeat, необходимо установитьno-repeat:

.hero {
    mask-image: url('..');
    mask-repeat: no-repeat;
}

Если вы хотите узнать большеbackground-repeatа такжеmaskДля получения соответствующих знаний вы можете прочитать его шаг за шагом:

дополнительные 4 пикселя внизу изображения

использовать<img>При переносе изображений в Интернет по умолчанию при отображении в браузере изображений нижняя часть примерно4pxбелое пространство.

Это ошибка? Конечно нет, это поведение по умолчанию.

<img>Элементы по умолчаниюЗамененный элемент. по умолчанию,<img>Нижняя часть контейнера совпадает с базовой линией контейнера (baseline) выровнять. Базовый уровень примерно такойa,b,c,dгде находится такая буква, что означает что-то вродеg,j,yТакие буквы, части которых лежат ниже базовой линии (кстати, эти части называются «каплями»). Это примерно то, что вы видите по умолчанию4px, так как изображение визуализируется на базовой линии, оставляя место для нисходящей линии.

Проблема связана с тем, что изображение находится относительно других элементов в той же строке.vertical-alginвызвано, мы можем легко исправить это:

  • Изменятьvertical-alignсвойства, такие как явная установка не-baselineзначение (baselineЯвляется ли его значением по умолчанию),Такие какtop,bottomилиmiddleи т. д., но атрибут работает только со встроенными элементами
  • Изменятьdisplayзначение атрибута, сделать<img>быть блочным элементом вместо встроенного элемента
  • Есть еще несколько трюков, в том числе установка родительского контейнераline-heightдля0, который устанавливает родительский контейнерfont-sizeдля0

Что касается меня, я предпочитаю сбрасывать таблицу стилей, даваяimgДобавьте глобальный стиль, чтобы он не отображался внизу изображений в Интернете.4pxПоявляется лишнее белое пространство:

img {
    display: block;
}

Обратите внимание, что в HTML<iframe>а также<video>элементы и<img>Однотипные элементы этикетки, это явление также существует в этих элементах, при использовании подобных<img>При замене элементов рекомендуется явно задавать их при сбросе CSS.displayценностьblock.

текст на изображении

В Интернете текст появляется поверх изображений во многих случаях:

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

Так как "Несколько поз для работы с текстовыми эффектами на картинках«В статье представлено множество способов справиться с этим, например следующий пример:

.card__content {
    background-image: linear-gradient(
        to top,
        hsla(0, 0%, 0%, 0.62) 0%,
        hsla(0, 0%, 0%, 0.614) 7.5%,
        hsla(0, 0%, 0%, 0.596) 13.5%,
        hsla(0, 0%, 0%, 0.569) 18.2%,
        hsla(0, 0%, 0%, 0.533) 22%,
        hsla(0, 0%, 0%, 0.49) 25.3%,
        hsla(0, 0%, 0%, 0.441) 28.3%,
        hsla(0, 0%, 0%, 0.388) 31.4%,
        hsla(0, 0%, 0%, 0.333) 35%,
        hsla(0, 0%, 0%, 0.277) 39.3%,
        hsla(0, 0%, 0%, 0.221) 44.7%,
        hsla(0, 0%, 0%, 0.167) 51.6%,
        hsla(0, 0%, 0%, 0.117) 60.2%,
        hsla(0, 0%, 0%, 0.071) 70.9%,
        hsla(0, 0%, 0%, 0.032) 84.1%,
        hsla(0, 0%, 0%, 0) 100%
    );
    color: #fff;
}
See the Pen <a href="https://codepen.io/airen/pen/MWvyGWp"> Handling Text Over Images in CSS</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Но немногие студенты будут учитывать при написании CSS<img>Отображение изображения при загрузке не удается. Например, на картинке ниже левая сторона — это когда изображение загружается нормально, а правая — когда изображение не загружается.

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

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

На самом деле, более защитный CSS должен быть в<img>Установите цвет, который имеет некоторый контраст с цветом текста. напримерgreyЦвета, чтобы изображение не загружалось, не влияя на читаемость текста на изображении:

.card__thumb img {
    background-color: grey
}

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

Конечно, вы можете сделать что-то вроде@Ire AderinokunСообщение в блоге, опубликованное в 2016 году,Styling Broken Images"Сюда,С псевдоэлементами CSS::beforeа также::afterНастройте более красивый и стильный дизайн для изображения, которое не загружается:

img { 
    /* Same as first example */
    min-height: 50px;
}

img::before,
img::after {
    position: absolute;
    width: 100%;
    left: 0;

}

img:before { 
    content: " ";
    top: -10px;
    height: calc(100% + 10px);
    background-color: rgb(230, 230, 230);
    border: 2px dotted rgb(200, 200, 200);
    border-radius: 5px;
}

img:after { 
    content: "\f127" " Broken Image of " attr(alt);
    font-size: 16px;
    font-style: normal;
    font-family: FontAwesome;
    color: rgb(100, 100, 100);
    top: 5px;
    text-align: center;
}

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

See the Pen <a href="https://codepen.io/airen/pen/OJxGNyR"> Styling Broken Images with CSS</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

максимальная ширина изображения

В общем, не забудьте установить для всех картинокmax-width: 100%. Это можно добавить к стилям сброса CSS, которые вы используете:

img {
    max-width: 100%;
    height: auto;
    object-fit: cover;
}

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

Уменьшить яркость изображения в темном режиме

если вашВеб-приложения должны иметь темный режим, обработка изображений также является деталью, которую нельзя игнорировать. В небольшом приложении вы можетеиспользуя HTML5<picture>элемент, загружать изображения разных форматов для разных режимов:

<picture>
    <source srcset="settings-dark.png" media="(prefers-color-scheme: dark)">
    <source srcset="settings-light.png" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)">
    <img src="settings-light.png" id="screenshot" loading="lazy">
  </picture>

Однако для среднего и крупного веб-приложения этот метод может не предоставить две версии источника изображения для веб-приложения. В этом случае,Фильтры, которые могут использовать CSSfilterфункция уменьшения яркости изображения, То естьdarkУменьшить яркость изображения в режиме:

@media (prefers-color-scheme: dark) {
    :root {
        --image-filter: grayscale(50%);
    }

    img:not([src*=".svg"]) {
        filter: var(--image-filter);
    }
}

использоватьfilterУменьшите оттенки серого изображения (grayscale(50%)) ХотяdarkРежим — это быстрое решение для снижения яркости фонового изображения, но это не лучшее решение. Это рекомендуется только в том случае, если у вас нет специального изображения для темного режима.

Внутренняя тень на картинке

Я не знаю, имел ли<img>Чтобы использовать внутреннюю тень для элемента, используйте ее следующим образом:

img { 
    box-shadow:inset 5px 5px 5px 5px #09fa00; 
}

Если вы дадитеimgУстановите внутреннюю тень, вы, должно быть, обнаружили, что внутренняя тень, примененная к изображению, теряется:

Основной причиной этого явления является «imgЭлемент считается пустым элементом, а не элементом-контейнером.".

Обратите внимание, что в HTML, кроме<img>Element — Заменяемый элемент (Replaced Element), есть<iframe>,<video>,<embed>и т. д. Кроме того, некоторые элементы также считаются заменяемыми элементами при определенных обстоятельствах, например,<option>,<audio>,<canvas>,<object>а также<applet>Ждать. Кроме того, спецификация HTML также говорит:<input>Элементы заменяемы, потому чтоimageТип<input>элементы похожи<img>также заменяются. Но другие формы элементов управления, в том числе другие типы<input>Элементы, которые явно перечислены как незаменяемые элементы.

Хотя есть много сменных элементов,box-shadowВнутренняя тень (inset) для этих заменяемых элементов будут рассматриваться только как пустые элементы<img>,<video>,<iframe>а также<embed>. Например, вы<video>использовать наbox-shadowНаходясь во внутренней тени, он ведет себя и<img>Такой же.

See the Pen <a href="https://codepen.io/airen/pen/PoJdyKv"> box-shadow for Replaceable Element</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Чтобы избежать этого явления, необходимо<img>а также<video>Внешний слой элемента обернут элементом-контейнером, напримерdiv, и будет использоваться для<img>(или<iframe>) внутренняя тень элемента применяется к его элементу-контейнеру:

<!-- HTML -->
<div class="media--wrapper">
    <img src="" alt="" >
</div>

/* CSS */
.media--wrapper {
    box-shadow: inset 0 0 4vmin 3vmin rgb(0 0 0 / .5);
}

.media--wrapper img, 
.media--wrapper video {
    position: relative;
    z-index: -1;
}

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

Но это не лучшее решение, для картинок прикладывайте картинку кbackground-imageявляется лучшим решением, но для<video>, приведенное выше решение является лучшим решением.

Если вас интересует использование теней в паутине, вы можете прочитать "Иллюстрированный CSS: тени CSS" статья.

Сегодня изображения являются одним из важных мультимедийных элементов Сети.Большинство разработчиков считают, что отображение изображений в Сети очень просто и существует множество способов. Лично я так не думаю, особенно в 2021 году, когда я отказываюсь от производительности рендеринга, адаптивного дизайна и т. д., мне трудно правильно использовать изображения в Интернете. Если вам интересна эта тема, вы можете прочитать следующие статьи, связанные с картинками:

Защитный CSS, связанный с прокруткой

Эта часть представляет собой настройку свойств CSS, связанных с прокруткой. Большинство этих свойств используются для улучшения взаимодействия с прокруткой.

Блокировка роликовой цепи

катящаяся цепь относится кzНесколько контейнеров оси отображаются для прокрутки.

Полосы прокрутки отображаются для нескольких контейнеров (zНаиболее распространенный сценарий заключается в том, что когда вы открываете всплывающее окно (модальное) и прокручиваете вниз (в вертикальном направлении), если вы продолжаете прокручивать вниз, это приводит к тому, что содержимое под всплывающим окном (обычноbodyЭлементы будут продолжать прокручиваться. Это также проявление поведения цепочки прокрутки:

Чтобы предотвратить распространение прокрутки на другие контейнеры прокрутки, мы можем поместить CSS в верхний контейнер прокрутки.overscroll-behaviorсвойство установлено наcontain:

.modal__content {
    overscroll-behavior-y: contain;
    overflow-y: auto;
}

В нашем случае задайте его явно в Modaloverscroll-behaviorПосле этого контейнер прокрутки во всплывающем окне не будет влиять на дно после прокрутки дна (body) свитка:

Уведомление,overscroll-behaviorАтрибуты порождают только эффекты при возникновении прокрутки. Для получения дополнительных введений об этом атрибуте вы можете прочитать "CSS overscroll-behavior" статья.

Показывать полосы прокрутки, когда это необходимо

В случае относительно длинного контента можно установитьoverflowОпределяет, отображается ли полоса прокрутки. Но здесь более рекомендуетсяoverflowЗначение установлено наauto. если вы будетеoverflowЯвно установлен наscroll, независимо от длины содержимого контейнера, полоса прокрутки будет отображаться, как показано ниже:

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

.element {
    overflow-y: auto;
}

настройки контейнераoverflow-yдляauto, полоса прокрутки будет отображаться для пользователя только тогда, когда содержимое слишком длинное, чтобы переполнить контейнер прокрутки, и полоса прокрутки не будет отображаться, если содержимое не переполняет контейнер:

пространство полосы прокрутки

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

Внимательно сравнив изменения до и после рисунка выше, нетрудно обнаружить, что полоса прокрутки сузила область белого содержимого. мы можем установитьscrollbar-gutterсвойства, чтобы избежать этой проблемы.

.element {
    scrollbar-gutter: stable;
}

scrollbar-gutterдаCSS Overflow Module Level 4 Добавлена ​​новая функция. С помощью этого свойства разработчики могут лучше управлять полосой прокрутки или устранять различия в макете, вызванные разными типами полос прокрутки. На рисунке ниже показаноscrollbar-gutterЭффект от взятия значения время от времени:

Украсить пользовательский интерфейс полосы прокрутки

Однако, если вы хотите украсить пользовательский интерфейс полосы прокрутки, вам все равно придется использовать недавно выпущенный W3C 9 декабря 2021 года.CSS Scrollbars Styling Module Level 1Предоставленная спецификацияscrollbar-colorа такжеscrollbar-widthдва свойства. Позже мы можем использовать их, чтобы легко настроить стили полосы прокрутки:

.section {
    scrollbar-color: #6969dd #e0e0e0;
    scrollbar-width: thin;
}

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

Сделайте прокрутку более плавной

В некоторых случаях вы можете обнаружить, что прокрутка заикается. Мы можем установить прокручиваемый контейнерscroll-behaviorценностьsmoothчтобы сделать прокрутку более плавной. Во многих случаях, чтобы сделать прокрутку страницы более плавной, рекомендуетсяhtmlУстановите этот стиль для элемента:

html {
    scroll-behavior: smooth;
}

захват прокрутки

Спецификация привязки прокрутки CSSПредоставляет некоторые функции для оптимизации процесса прокрутки,Документ можно прокручивать до определенной точки (местоположения), когда пользователь прокручивает его.. Это полезно для создания более похожего на приложение (собственного клиента) опыта для определенных типов приложений (например, компонентов слайдера) на мобильных устройствах или даже на ПК.

Вкратце, захват прокрутки CSS может:

  • Предотвращение неудобных положений прокрутки при прокрутке
  • Создайте лучший опыт прокрутки

Например следующий пример:

.container {
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
}

img {
    scroll-snap-align: center;
    scroll-snap-stop: always;
}

При пролистывании изображений в приведенном выше примере прокрутка аналогична пролистыванию в клиентском приложении. Каждый раз, когда вы прокручиваете, вы можете прокручивать только одно изображение:

Для более подробного ознакомления с захватом прокрутки вы можете прочитать следующие две статьи:

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

Если вас интересуют свойства, упомянутые выше, и вы хотите узнать больше, вы можете прочитать следующие статьи:

Защитный CSS, связанный со скругленными углами

посколькуДобавлен CSSborder-radiusАтрибутыПосле этого создание закругленных углов в паутине стало очень простым, и больше не нужно было полагаться на технологию раздвижных дверей для получения закругленных углов. но используяborder-radiusЕсть несколько моментов, о которых следует помнить при установке закругленных углов для элементов.

Расчет вложенных скруглений

использоватьborder-radiusИногда создается визуальный эффект закругленных углов:

Феномен вложенных закругленных углов может возникать на одном элементе, между вложенными элементами или даже на обоих. В обычных условиях, когда веб-разработчик восстанавливает пользовательский интерфейс, элементborder-radius的值是直接从视觉稿的图层属性中获取,很少在开发的过程中会注意圆角的嵌套现象。 Давайте рассмотрим простой пример:

<!-- HTML -->
<div class="card">
    <img src="" alt="" >
</div>

/* CSS */ 
:root {
    --border-radius: 10px;
    --border-width: 0px;
    --padding: 0px;
}

.card {
    border-width: var(--border-width);
    border-radius: var(--border-radius);
    padding: var(--padding);
}

.card img {
    --radius: calc(var(--border-radius) - var(--border-width) - var(--padding));
    border-radius: var(--radius);
}
See the Pen <a href="https://codepen.io/airen/pen/BawEbLr"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

В примере регулировкиborder-radius,border-widthа такжеpaddingзначение, вы можете увидеть контейнер.cardи содержаниеimgэлементальborder-radiusИзменение:

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

r = R - BW - PW

в:

  • Rэто сам контейнерborder-radiusРадиус (радиус бычьего угла)
  • BWэто сам контейнерborder-widthзначение (толщина границы)
  • PWэто сам контейнерpaddingзначение (внутреннее расстояние)
  • rсодержание областиborder-radiusРадиус (радиус скругления)

Если несколько элементов вложены друг в друга и явно заданы только в самом внешнем контейнереborder-radiusзначение, то радиус угла первого вложенного дочернего элемента будет рассчитан по приведенной выше формуле, а полученное значение радиуса станет радиусом угла второго вложенного дочернего элемента (R). И так до тех пор, пока не будет вычисленоborder-radiusценность0(меньше, чем0значение будет рассматриваться как0).

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

Что происходит, когда радиусы перекрываются

В Интернете есть несколько стилей пользовательского интерфейса, которые выглядят как формы «капсулы»:

Мы часто называем этот стиль пользовательского интерфейса «капсульным пользовательским интерфейсом», который часто используется в некоторых приложениях.button,checkboxа такжеradioна элементе.

CSS реализует эффект такого капсульного пользовательского интерфейса. Чтобы достичь его раз и навсегда, он часто дает элементуborder-radiusЗначение установлено на большее значение, например999rem,999vmaxкакой-то тип. Таким образом, независимо от высоты элемента, можно добиться эффекта капсульного пользовательского интерфейса:

.pill {
    border-radius: 999vmax;
}

Думаю, все понимают смысл этой строчки кода..pillЧетыре угла элемента «Филе» - радиус999vmax. Это удобно, потому что нам не нужно знать размеры элемента (прямоугольника), и все будет работать нормально.

Однако в некоторых пограничных случаях наблюдается странное поведение. Например, небольшая корректировка на основе приведенного выше примера заключается в том, чтобы поставитьborder-radiusУстановлено значение:

.pill {
    border-radius: 100px 999vmax 999vmax 100px;
}

вы найдете элементы.pillХотя верхний левый и нижний левый углы установленыborder-radiusРадиус100px, но без закругленных углов:

Вам может быть интересно, почему верхний левый и нижний левый100pxизborder-radiusПочему это не сработало?На самом деле ответ был дан в спецификации W3C.:

Пусть f = min(Li/Si), где i ∈ {верхний, правый, нижний, левый}, Si — сумма двух соответствующих радиусов углов на стороне i, а Ltop = Lbottom = ширина ящика, и Lleft = Lright = высота коробки.Если f .

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

Формула выглядит запутанной, даже голова болит. Но нам нужно помнить только одно:Цель этой формулы — предотвратитьborder-radius(Угловой радиус) Перекрытие. вообще говоря:

Клиент (браузер), по сути, думает: «Уменьшить все радиусы (border-radius) до тех пор, пока между ними не будет перекрытия"!

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

Во-первых, он вычисляет отношение длины каждой стороны прямоугольника (элемента) к сумме радиусов, которые его касаются:

元素每条边宽度 / (相邻圆角半径1 + 相邻圆角半径2)

такие как элементы.pillУстановить стиль:

.pill {
    width: 600px;
    height: 200px;
    border-radius: 400px;
}

Для этого примера, следуя приведенной выше формуле, можно «вычислить.pillОтношение длины каждого ребра элемента к сумме радиусов, которые его касаются":

Затем умножьте радиус всех углов на наименьшее из этих соотношений (расчетных соотношений для каждого ребра). Значение отношения, рассчитанное в приведенном выше примере, составляет всего.75а также.25, возьмите меньшее значение.25, то расчетное значение радиуса угла равно:

400px x .25 = 100px

наша стихия.pillизheightда200px(длина самой короткой стороны), вычисленоborder-radiusбываетheightполовина100px. Это также позволяет нам реализовать эффект пользовательского интерфейса «капсулы».

Чтобы понять немного яснее, давайте вернемся к предыдущему рассматриваемому примеру, за исключением того, что мы используем400pxзаменить999vmax,Например:

.pill {
    width: 600px;
    height: 200px;
    border-radius: 100px 400px 400px 100px;
}

Также рассчитайте отношение каждой стороны по приведенной выше формуле:

Ratio » 元素每条边宽度 / (相邻圆角半径1 + 相邻圆角半径2)

Top    » 600px / (100px + 400px)  = 1.2
Right  » 200px / (400px + 400px)  = 0.25
Bottom » 600px / (400px + 100px)  = 1.2
Left   » 200px / (100px + 100px)  = 1

Наименьшее отношение четырех направлений равно0.25, то все заданные радиусы углов умножаются на это соотношение:

Top-Left     » 100px x 0.25 = 25px
Top-Right    » 400px x 0.25 = 100px
Bottom-Right » 400px x 0.25 = 100px
Bottom-Left  » 100px x 0.25 = 25px

Таким образом, обращаясь к.pillэлементальborder-radiusзначение25px 100px 100px 25px:

Вам не кажется, что это очень чудесно. Я думаю, что эта часть ответит на некоторые странные явления, с которыми вы обычно сталкиваетесь, а именноиспользоватьborder-radiusстранное явление!

Закругленные углы сочетаются с трансформацией

Как упоминалось ранее, в CSS, если вы хотите присвоить элементуwidthилиheightОбработка анимации требует применения других технических решений. Например, с помощью CSStransform. Но у этого есть и обратная сторона. Например, наборы элементовborder-radius. Как показано на рисунке ниже, установлен закругленный угол (border-radius) использование элементовtransformДля имитации анимации изменения ширины или высоты закругленные углы элемента не перерисовываются, а просто масштабируются.

Если закругленные углы должны быть перерисованы, движок рендеринга должен уметь перерисовывать (Repaint), но GPU этого не делает, он обрабатывает только пиксели, а не содержимое элемента. Поскольку GPU очень стесняется обрабатывать пиксели (GPU должен обрабатывать только тот пиксель, который отображает элемент), поэтомуtransformоперация очень быстрая. Это также используетtransformОдна из основных причин обработки анимации ширины или высоты элемента.

Если вы хотите избежать этого явления, вам нужно использовать некоторые технические средства, чтобы избежать его. Например@Rik SchenninkВ своей статье "Animating CSS Width and Height Without the Squish Effectупоминается в9-фрагментное масштабирование. Вот пример, я сделал небольшую корректировку примера в своей статье:

<!-- HTML -->
<div class="radius">
    <div class="content"></div>
</div>

/* CSS */
.radius {
    height: 100px;
    display: flex;
    justify-content: flex-start;
}

.radius::before,
.radius::after {
content: "";
    width: 20px;
    background: #098fae;
}

.radius::before {
    border-radius: 20px 0 0 20px;
}

.content {
    background: #098fae;
    width: 1px;
    transform: scale3d(1, 1, 1);
    transform-origin: left;
}

.radius::after {
    border-radius: 0 20px 20px 0;
    transform: translate3d(0, 0, 0);
}

@keyframes right-animate {
    0% {
        transform: translate3d(0, 0, 0);
    }
    100% {
        transform: translate3d(80px, 0, 0);
    }
}

@keyframes center-animate {
    0% {
        transform: scale3d(1, 1, 1);
    }
    100% {
        transform: scale3d(81, 1, 1);
    }
}

.content {
    animation: center-animate 1s linear infinite alternate;
}

.radius::after {
    animation: right-animate 1s linear infinite alternate;
}
See the Pen <a href="https://codepen.io/airen/pen/xxXevpY"> Untitled</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

В приведенном выше примере:

  • Замена абсолютного позиционирования исходного примера макетом Flexbox
  • Замена 2D-преобразования исходного примера на 3D-преобразование
  • Используйте псевдоэлементы::beforeа также::afterЗаменяет исходный пустой элемент метки.leftа также.right

Лучшим решением является использованиеПользовательские свойства в CSS Houdini@property(также называемые переменными в CSS Houdini),@propertyМожет дополнительно расширить анимацию CSS. Например, в приведенном выше примере@propertyЭто можно сделать следующим образом:

@property --width {
    initial-value: 1px;
    inherits: false;
    syntax: "<length>";
}

@keyframes square {
    to {
        --width: 300px;
    }
}

.content {
    width: var(--width);
    animation: square 2s ease infinite alternate;
}

Выше приведен только код ключа, используемый в примере (@propertyа также@keyframesраздел), пожалуйста, обратитесь к примеру на Codepen для подробного кода:

See the Pen <a href="https://codepen.io/airen/pen/gOGyyRy"> Animating CSS width with @property</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

В левой части примера используется макет Flexbox, а в правой части — макет Grid. Но в анимации используется та же схема, и эффект почти такой же:

Почему z-индекс не работает?

Если вы фронтенд-интервьюер, спросите во время интервью: «Какие способы вызватьz-indexвступить в силу"? Думаю, большинство разработчиков скажут:

когдаpositionСтоимость имущества неstatic, это вызоветz-indexЭффективно!

Такой ответ не является проблематичным, но недостаточно исчерпывающим. Активировано в CSS на сегодняшний деньz-indexэффективным не толькоpositionзначение неstatic, Есть много способов.На MDN есть более полный список., который описывает триггерz-indexЭффективный способ:

  • корневой элемент документа (<html>)
  • positionзначениеabsoluteилиrelativeа такжеz-indexзначение неautoЭлементы
  • positionзначениеfixedилиstickyЭлементы
  • Проект Flex,z-indexзначение неauto
  • Элемент сетки иz-indexзначение неauto
  • opacityстоимость имущества меньше1Элементы
  • mix-blend-modeстоимость имущества неnormalЭлементы
  • transform,filter,perspective,clip-path,mask,mask-image,mask-borderРавное значение атрибута неnoneЭлементы
  • isolationСтоимость свойстваisolateЭлементы
  • -webkit-overflow-scrollingСтоимость свойстваtouchЭлементы
  • will-changeЗначение задает любое свойство, и свойство находится вnon-initialЭлемент, который создает контекст стека, когда значение
  • containСтоимость свойстваlayout,paintили составное значение, содержащее один из них (какcontain: strict、contain: content)Элементы

Устанавливаем на элементz-indexЭто значение в основном предназначено для управления элементами вzпорядок на оси. Его значение может бытьauto,0, положительные и отрицательные целые значения, гдеautoявляется его значением по умолчанию, но в производительностиz-indexстоимостьautoа также0несколько отличаются:

  • не установленz-indexзначение, по умолчаниюauto. Слой по умолчанию0Пол
  • z-index: 0без определенияz-index, то есть,z-index: autoВ пределах одного уровня нет различий между высоким и низким уровнем, и те, которые появляются позже в потоке документов, перезапишут те, которые появляются раньше.
  • z-index: 0создаст контекст стекаz-index: autoконтекст стека не создается

Общее использованиеz-indexПри определении порядка укладки будут обсуждаться следующие два случая:

  • Если элемент контекста стека не зависит отz-indexзначение, порядок наложенияz-index:autoможно рассматривать какz-index:0уровень
  • Если элемент контекста стека зависит отz-indexзначение, порядок наложения задаетсяz-indexЗначение определяется, чем больше значение, тем больше на верхнем уровне

Для обсуждения этого вы можете подробно прочитать следующие статьи:

Но в реальном процессе разработки мы будем время от времени сталкиватьсяz-indexне вступает в силу, даже еслиpositionзначение неstaticна элементе. Не так давно одноклассник нашей команды явно задал элемент позиционирования (фиксированное позиционирование) при разработке страницы.z-indexдля9999, но его родительский элемент является контейнером прокрутки, чтобы контейнер прокрутки лучше скользил на устройствах iOS, используйте-webkit-overflow-scrolling: touch;. Однако в это время он позволит своим дочерним элементамpositionЗатем наstaticзначения игнорируются, а поведение рендеринга аналогичноstatic,z-indexЭто также терпит неудачу. Чтобы избежать этого явления, мы можемtransform: translateZ(0)способ перезапуститьz-indexэффективный.

другая воляz-indexСценарий отказа находится вtransform3D-сцена, активируемая атрибутами. вообще говоря,transformиногда делатьz-index«Временное признание недействительным» (то, что оно неz-indexне удалось) простоz-indexиспользуются в разных контекстах стека (контексты стека), отличных от контекста стека по умолчанию, для одинакового сравненияzуровень оси. где находится DOMtransform, DOM находится в новом контексте стека,z-indexЭто также относительно этого контекста стека, поэтому он фактически показывает уровень контекста стека.После окончания анимации DOM возвращается к контексту стека по умолчанию.В это времяz-indexсравниваются в одном контексте. Есть примерно два решения этого явления:

  • Метод 1: родитель, произвольный родитель, не-bodyуровень, наборoverflow:hiddenВосстановление того же рендеринга, что и в других браузерах
  • Способ 2: Бороться с ядом ядом. Также можно использовать 3D-преобразования, напримерtranslateZ(0)

По моему личному опыту, частоz-indexЕсли недействительно, используйтеtranslateZ(0)Гарантия ОК!

Избегайте переполнения: скрытое не действует

При разработке интерактивного проекта в 2019 году наступил наoverflow:hiddenНеэффективные кейсы.

.root {
    overflow-x: hidden;
    width: 100vw;
}
See the Pen <a href="https://codepen.io/airen/pen/zQMgqv"> How to fixed overflow-x not working on mobile</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

В приведенном выше примере вы найдетеoverflow-x:hiddenНе активен:

Почему это так? Проще говоря, пример запускает:

  • имеютoverflow:hiddenэлемент не имеетpositionотрицатьstaticзначение
  • внутренние элементы черезposition:absoluteнайти

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

Обрезать ли контейнер блочного элемента, когда его содержимое выходит за границы блочной модели элемента. Это влияет на отсечение всего содержимого примененного элемента. Но если содержащий блок элемента-потомка представляет собой всю область просмотра (обычно относится к видимой области содержимого браузера, это можно понимать какbodyэлемент) или контейнер (который определяетoverflowэлемент) не влияет.

Обычно блок, содержащий элемент, определяется границами содержимого его ближайшего предка на уровне блока. Но когда для элемента задано абсолютное позиционирование, содержащий его блок определяется ближайшимpositionнетstaticЭлемент-предок . Таким образом, легче понять, что вызывает проблему. Просто установитеoverflow:hiddenдобавлено в элементpositionимущество, оцененноеstaticВот и все.

На самом деле, эта ситуация не без проблем, часто нам нужно предотвратить установку абсолютно позиционированных элементов.overflow:hiddenЭлемент скрыт. Например, всплывающие подсказки:

Для сценария приведенного выше примера нам нужна такая структура:

<div class="grand-parent">
    <div class="parent">
        <div class="child"></div>
    </div>
</div>

Стиль такой же простой:

.grand-parent {
    position:relative;
}

.parent {
    overflow:hidden;
}

.child {
    position:absolute; 
    top:-10px; 
    left:-5px;
}
See the Pen <a href="https://codepen.io/airen/pen/RmELwY"> Overflow and Position</a> by Airen (<a href="https://codepen.io/airen">@airen</a>) on <a href="https://codepen.io">CodePen</a>.

Кроме тогоoverflowа такжеposition:fixedКогда элементы используются вместе,fixedэлемент сломаетсяoverflowОбвязка контейнера. Например, у нас есть такая структура:

<!-- HTML -->
<div class="overflow">
    <img class="" src="" class="fixed" />
</div>

/* CSS */
.overflow {
    width: 50vw;
    height: 50vh;
    overflow: hidden;
}

.fixed {
    position: fixed;
    top: 2vw;
    left: 2vw;
}

Как мы все знаем,position:fixedЕсли это не ограничено специальными свойствами, его позиционирование определяется относительно края окна просмотра. даже если его родительский контейнер устанавливаетoverflow:hiddenтакже потерпит неудачу. Как и в примере выше, картинка ломает настройкиoverflow:hiddenконтейнерdiv:

Если вы хотите сломать такую ​​игру, пустьfixedэлементы также обрезаются, мы можем использоватьtransformсделать это, т.transformКромеnoneЛюбое значение, отличное от , создает контекст стека и содержащий блок. Затем этот элемент будет содержащим блок фиксированного элемента.

.overflow {
    overflow: hidden;
    transform: translateZ(0);
}

В будущем аналогичный эффект может быть достигнут с помощью CSS Containment. использоватьcontain: paintПусть элемент действует как блок с абсолютно позиционированными и фиксированно позиционированными потомками.

Если вы хотите узнать больше о CSSoverflowсвойства, вы также можете прочитатьМодуль переполнения CSS, о котором вы не знаете" статья.

Избегайте ямы 100vh

существует"КСС в 2022 году"Представляет новый оконный блок в статьеlvh,svhупомянулИспользование Safari на iOS100vhдавняя ошибка. его нельзя сочетать сvhБлок подходит хорошо. Если вы установите высоту контейнера на100vh, приведет к тому, что элемент будет слишком высоким (появятся полосы прокрутки). Основная причина этого в том, что Safari на мобильных устройствах вычисляет100vhигнорируя части своего пользовательского интерфейса.

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

body {
    height: 100vh;
}

@supports (-webkit-touch-callout: none) {
    body {
        height: -webkit-fill-available;
    }
}

селектор объединения

Селекторы объединения не рекомендуются для стилей, которые одновременно влияют на разные браузеры. Например, установкаinputсерединаplaceholder, вам нужно использовать соответствующий селектор для каждого браузера. Согласно w3c, если мы используем селектор объединения в этом сценарии, то все правило стиля становится недействительным. Приведенный ниже код не рекомендуется.

/* 请不要像这样使用 */
input::-webkit-input-placeholder,
input:-moz-placeholder {
    color: #222;
}

Код ниже рекомендуется.

input::-webkit-input-placeholder {
    color: #222;
}

input:-moz-placeholder {
    color: #222;
}

Альтернативное значение пользовательского свойства

Пользовательские свойства CSS (переменные) все чаще используются в веб-разработке.. Чтобы не нарушать пользовательский интерфейс, нам нужно выполнить дополнительную обработку, если значение пользовательского свойства CSS по какой-либо причине равно нулю.

Особенно при использовании JavaScript для установки значения настраиваемых свойств CSS уделяйте больше внимания недопустимому значению настраиваемого свойства. Например следующий пример:

.message__bubble {
    max-width: calc(100% - var(--actions-width));
}

calc()В функции используется пользовательское свойство--actions-width, а его значение предоставляется кодом JavaScript. Если в некоторых случаях код Javascript не выполняется, тоmax-widthЗначение будет рассчитываться какnone.

Чтобы избежать этой проблемы, используйтеvar()чтобы установить альтернативное значение, которое вступит в силу, когда значение пользовательского свойства станет недопустимым.

.message__bubble {
    max-width: calc(100% - var(--actions-width, 70px));
}   

Таким образом, если пользовательское свойство--actions-widthне определено, будет использовано альтернативное значение70px. Этот метод используется в сценариях, где значения пользовательских свойств могут не работать, например, когда значение поступает из JavaScript. В других сценариях в этом нет необходимости.

продолжение следует...

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