Перейти к содержимому

Как динамически подгонять шрифт css

  • автор:

Как менять размер текста при изменении размера окна?

Для изменения размера текста веб-страницы совместно с окном браузера есть несколько методов. Рассмотрим наиболее популярные.

Использование единиц vw

Размер текста задаётся с помощью свойства font-size, в качестве значения можно указывать разные единицы — пиксели, пункты, миллиметры и др. Единица vw (от англ. viewport width — ширина области просмотра) соответствует 1% от ширины окна браузера, таким образом, при изменении этой ширины будет меняться и размер текста (пример 1).

Пример 1. Использование vw

Размер текста

Для педагогов

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

Результат данного примера показан на рис. 1.

Рис. 1. а — текст на широком окне; б — текст на узком окне

У единицы vw есть несколько недостатков — главное, что текст уменьшается пропорционально вместе с окном и в какой-то момент становится нечитаемым. Это будет особенно заметно на смартфонах, где ширина экрана меньше ширины мониторов. Чтобы установить минимальный размер текста можно воспользоваться функцией calc(), как показано в примере 2.

Пример 2. Использование calc()

Здесь мы смешиваем разные единицы — для заголовка rem и vw, для основного текста пиксели и vw. Использование calc() гарантирует, что текст не станет меньше указанного значения (для заголовка, к примеру, это 1rem).

Использование медиа-запросов

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

Сперва определяем стиль для больших экранов, затем с помощью конструкции @media screen and (max-width: 1024px) задаём стиль для экранов с шириной до 1024 пикселей. Внутри @media пишется размер текста под этот размер. При желании ниже добавляем ещё несколько @media с разными значениями max-width (пример 3).

Пример 3. Использование @media

Размер текста

Для педагогов

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

Размер текста в данном случае будет меняться не плавно, а ступенчато — при достижении указанной ширины окна размер текста уменьшается или увеличивается.

См. также

  • @media
  • calc()
  • clamp()
  • font-size
  • Единицы размера в CSS
  • Медиа-запросы
  • Отзывчивый веб-дизайн
  • Размер текста
  • Свойства шрифта в CSS

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

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

Предисловие

Для простоты, все условия задачи, реализация, способы применения решение и остальные не относящиеся к делу детали (такие, как стили) будут максимально упрощены, для того, что б сконцентрироваться на требуемом результате. Как и где правильно применить данное решение, зависит только от вас и вашей ситуации. Приведенные ниже примеры кода будут с использованием React и TypeScript, но их знание совсем не обязательно, знаний нативного JavaScript будет вполне чем достаточно.

Задача

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

Готовый баннер.

Разметка баннера максимально простая, это контейнер содержащий в себе 3 элемента — текст №1, картинка и текст №2 которые будут располагаться друг над другом. Внутри каждого текстового контейнера будет располагаться тег

.

   /> 

Возможные варианты, которые были отброшены

Ниже будет список тех вариантов, которые рассматривались как возможное решение, но не подошли по тем или иным причинам.

  1. Media queries — Первое, что пришло в голову — это использование медиа выражений. Эта идея отпала быстро по причине динамической длинны текста, и огромного количества всевозможных комбинаций.
  2. clamp() — Неплохой и довольно-таки гибкий способ, который в большинстве случаев может сгодиться. На эту тему даже есть неплохая статья: Linearly Scale font-size with CSS clamp() Based on the Viewport с рабочей «песочницей», где можно просчитать необходимые для себя размеры. Но, «поигравшись» с данной песочницей, и перепробовав различные варианты (строго установленные размеры баннера, или наоборот никаких размеров), возникали случаи, где текст ломался и выходил за рамки.
  3. SVG — Широко рекомендуемый вариант, но заметно прожорливый при ресайзинге и довольно сложный в настройке, в случае когда мы мало что знаем о размерах (длинна текста, размеры контейнера).
  4. Сторонние библиотеки и плагины — этот вариант был отброшен сразу, что б не засорять проект лишними зависимостями.
  5. Подсчёт количества букв — Была и такая безумная идея, вычислять размеры контейнера в котором находится текст, подсчитывать количество букв получаемого текста, и на основании этого делать расчёты размера шрифта и возможного количества строк. Сложность в вычислениях, входящий текст может быть на разных языках (проблема подсчёта букв), и с различными символами (проблема поиска целого слова).

Решение

Логика решения довольно проста. И вкратце состоит из нескольких шагов:

  1. Находим необходимые текстовые узлы.
  2. Вычисляем размеры родительского контейнера (высоту и ширину).
  3. Пытаемся подобрать максимально возможный размер шрифта, что б текст не вылазил за рамки родительского контейнера.

Последний пункт звучит немного «костыльным», как будто мы пытаемся методом тыка попасть в нужную нам точку. Отчасти так и есть, но мы не пытаемся глупо добавлять по 1px , а делаем это более элегантным путём, что б сократить количество ненужных вычислений и уменьшить нагрузку.

Структура

Структура максимально простая и понятная с использованием npx create-react-app. В некоторых местах используются стили, для более приятного визуального восприятия.

├── package-lock.json ├── package.json ├── public │ └── index.html ├── src │ ├── App.css │ ├── App.tsx │ ├── components │ │ ├── Banner │ │ │ ├── Banner.scss │ │ │ └── Banner.tsx │ ├── constants │ │ └── index.ts │ ├── hooks │ │ ├── useStretchingText.ts │ ├── index.css │ ├── index.js │ └── static │ └── vs.png └── tsconfig.json
Описание решения

Пройдёмся в целом по структуре проекта и реализации решения.

В корневом компоненте App.tsx расположен главный Banner.tsx , который циклом проходится по переменной OPPONENTS отрисовывая значения различной длинны для наглядности.

import React from "react"; import "./App.scss"; import < Banner >from "./components/Banner/Banner"; import < OPPONENTS >from "./constants"; export const App = () => < return ( 
( /> ))>
); >;

Основной Banner.tsx также максимально прост, в нём содержится простая разметка, которая содержит имя первого оппонента, иконку, и имя второго оппонента. И как уже можно заметить, функцию которая и отвечает за отзывчивость текста, но об этом немного попозже.

import "./Banner.scss"; import < useStretchingText >from "../../hooks/useStretchingText"; const icon = require("../../static/vs.png"); export const Banner = (< text_1, text_2 >) => < useStretchingText("banner__text"); return (   /> ); >; 

Немного о стилях Banner.scss , в большинстве своём они тут всего лишь для красоты, но некоторые моменты я бы хотел объяснить.

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

    c именем оппонента) вычисляются равномерно, вычитая размеры картинки, паддинги.

// Variables. $banner_width: 100px; $banner_height: 300px; $banner_padding: 16px; $icon_width: 100px; $icon_height: 100px; $color_grandis: #fed480; $color_shakespeare: #45a7cd; $color_sandy_brown: #f59977; // Banner icon. .banner__img < width: $icon_width; height: $icon_height; >// Banner. .banner < height: $banner_height; padding: $banner_padding; display: flex; flex-direction: column; justify-content: center; align-items: center; border: 5px solid; border-image-slice: 1; border-image-source: linear-gradient(to left, #fed480, #45a7cd); border-color: #45a7cd #45a7cd #fed480 #fed480; >// Banner text container. .banner__text-container < width: 100%; height: calc( (#/ 2) - (#) - # ); > // Banner text. .banner__text < font-weight: 900; text-align: center; word-break: break-word; text-shadow: 1.5px 0px 0px black, -1.5px 0px 0px black, 0px 1.5px 0px black, 0px -1.5px 0px black; >.banner__text_1 < color: $color_shakespeare; >.banner__text_2

Далее начинается самое интересное, реализация решения вынесена в кастомный хук (для тех кто не работал с React — воспринимайте это как обычную функцию) useStretchingText.ts . Буду проходиться по нему построчно и объяснять что там происходит. Хук принимает два аргумента:

  1. textClassName — Это класс, по которому мы будем находить необходимый текст.
  2. initialMinFontSize — Изначально минимально допустимый размер шрифта. На случай если мы не хотим допустить значение ниже установленного.

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

let fontSize: number, maxHeight: number, maxWidth: number, parentElement: HTMLElement, maxCycles: number = 100; 

Находим текстовые ноды по указанному классу:

const textElements: NodeList = document.querySelectorAll( .$ );

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

if (textElements.length) < textElements.forEach((element) =>< // Some logic. >); >

Делаем некоторые вычисления, на основании родительского контейнера (с классом .banner__text-container ), рассчитываем максимально возможные размеры контейнера с текстом (с классом .banner__text ), устанавливаем минимальный и максимальный размеры шрифта. Для ясности хочу сказать, что в условиях задачи нам нужно найти максимальный размер шрифта, но в логике решения мы будем отталкиваться от минимального значения. То есть, не ниже которого, наши требования не будут удовлетворены. После получение значений, применяем стиль к текстовому узлу.

parentElement = element.parentElement; maxWidth = parentElement.clientWidth; maxHeight = parentElement.clientHeight; fontSize = maxHeight; let minFontSize = initialMinFontSize; let maxFontSize = fontSize; element["style"].fontSize = $px;

После того как мы применили первый размер шрифта, происходит вычисление и проверка, удовлетворяет ли текущее значение наши требования, и так до тех пор, пока не будет найдено оптимальное значение. Пару слов о происходящем: Цикл продолжается до тех пор, пока текущий размер шрифта не равняется минимально удовлетворяющему размеру шрифта. Если высота и ширина текстового узла (с классом .banner__text ) меньше или равны максимально допустимым, значит мы меняем значение minFontSize, если же наоборот, мы вылезли за допустимые рамки, мы меняем значение maxFontSize. После чего мы рассчитываем новое вероятно подходящее для нас значение размера шрифта. Но, что б не делать лишних вычислений, прибавляя по 1px , мы делаем это по следующей формуле:

В дополнении к этому, мы обезопасили себя заранее с помощью переменной, которую мы объявляли выше maxCycles: number = 100; . Чтобы по каким-либо причинам не «провалиться» в бесконечный цикл, мы прервём вычисления, достигнув установленного лимита.

while (fontSize !== minFontSize) < element["style"].fontSize = `$px`; if ( element["offsetHeight"] else < maxFontSize = fontSize; >fontSize = Math.floor((minFontSize + maxFontSize) / 2); --maxCycles; if (maxCycles > 

Ниже на анимации показано, что происходит если задать слишком маленькое занчение для maxCycles: number = 100; . Это не сломает работу, но также и не даст нам зависнуть на бесконечных вычислениях.

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

element["style"].fontSize = $px;

Ещё один небольшой приём оптимизации, с помощью использования функции throttle, библиотеки Lodash. С её помощью, мы будем ограничивать максимальное количество вызовов функции в заданный интервал. Я использую значение 15 , так как где-то встречал информацию, что браузеры производят перерисовку контента страницы на ранее чем каждые 16 миллисекунд.

const debouncedFunction = throttle(stretchingText, 15);

Если установить слишком большое значение для throttle функции (в нашем случае 100 мс уже является большим значением), то будут явно заметны задержки в работе:

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

P.S. Навешивание прослушивателя таким образом является не совсем хорошим решением и в данном случае и сделано исключительно для показания работоспособности.

useEffect(() => < window.addEventListener("resize", debouncedFunction); debouncedFunction(); return () =>< window.removeEventListener("resize", debouncedFunction); >; >, []);

Конечный результат готового хука выглядит так:

import < useEffect >from "react"; import < throttle >from "lodash"; export const useStretchingText = ( textClassName: string, initialMinFontSize = 3 ): void => < const stretchingText = () =>< let fontSize: number, maxHeight: number, maxWidth: number, parentElement: HTMLElement, maxCycles: number = 50; const textElements: NodeList = document.querySelectorAll( `.$` ); if (textElements.length) < textElements.forEach((element) =>< parentElement = element.parentElement; maxWidth = parentElement.clientWidth; maxHeight = parentElement.clientHeight; fontSize = maxHeight; let minFontSize = initialMinFontSize; let maxFontSize = fontSize; element["style"].fontSize = `$px`; while (fontSize !== minFontSize) < element["style"].fontSize = `$px`; if ( element["offsetHeight"] else < maxFontSize = fontSize; >fontSize = Math.floor((minFontSize + maxFontSize) / 2); --maxCycles; if (maxCycles > element["style"].fontSize = `$px`; >); > >; const debouncedFunction = throttle(stretchingText, 15); useEffect(() => < window.addEventListener("resize", debouncedFunction); debouncedFunction(); return () =>< window.removeEventListener("resize", debouncedFunction); >; >, []); >; 

Что можно было бы улучшить

  1. Кеширование. Возможно реализовать какое-то простое кеширование, которое будет запоминать последнее (или несколько последних) вычисленных значений, и применять к остальным элементам. Это хорошо подходит для нашего баннера, так как контейнеры обоих оппонентов абсолютно равны, и вычислив значение для одного, нам не нужно производить те же операции для другого.
  2. Использование хука и подписок. Сейчас это сделано в качестве кастомного хука и добавлением addEventListener на ресайзинг страницы, но возможно это и не пригодится, достаточно вызывать функцию лишь при изменении ориентации экрана.
  3. Глобальное использование. Возможен вариант когда данное вычисление придётся применить глобально ко всему проекту, соответственно вызов функции нужно будет вынести куда-то на верхний уровень.
  4. Ограничения размеров. У нас уже есть минимально допустимый размер шрифта, как опциональный второй аргумент initialMinFontSize . Вполне вероятно, что кому-то понадобится также добавить максимально допустимое значение, на случай если текст может состоять всего из одного слова, а сам баннер будет растянут на весь экран.
  5. Согласованность. В данный момент, каждый текстовый узел рассчитывает свои стили отдельно. Это значит, что каждый текст будет иметь свой размер шрифта. И если на примере нашего баннера имя первого оппонента будет состоять всего из одного слова, а имя второго из множества слов, разница в размере шрифта может быть значительной. Это не минус, а всего лишь один из способов решения. Возможно кому-то нужно иметь единый размер шрифта для всех оппонентов баннера (основываясь на меньшем), а кому-то наоборот, каждый оппонент должен иметь свой размер шрифта. Это всего лишь предложение, которое стоит взять во внимание.

Полезные материалы

  1. Код проекта: GitHub.
  2. Онлайн песочница: Codesandbox.

Как автоматически подогнать размер шрифта, чтобы он полностью заполнял контейнер и зависел от высоты контейнера?

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

Подскажите пожалуйста, как можно решить эту проблему, может есть какая-то библиотека для этого?

пример, как должен подстраиваться шрифт
62cb0ec99e02f452036784.jpeg
62cb0ed5cd884490839059.jpeg

Спасибо за любой совет.

  • Вопрос задан более года назад
  • 708 просмотров

13 комментариев

Простой 13 комментариев

SemanticMoscow

Semantic.Moscow @SemanticMoscow

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

Иван Гришов @IvanGrishov Автор вопроса
Semantic.Moscow, ссылку на что? А какие могут быть неожиданные последствия?

SemanticMoscow

Semantic.Moscow @SemanticMoscow
Иван Гришов, на документ (сайт), где это будет применено.
Иван Гришов @IvanGrishov Автор вопроса
Semantic.Moscow, нет пока что ссылки

aliencash

Не думаю, что удастся полностью решить вопрос как вы хотите, но попробуйте функцию clamp().
Иван Гришов @IvanGrishov Автор вопроса

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

aliencash

Иван Гришов, вы путайте. https://developer.mozilla.org/en-US/docs/Web/CSS/clamp
Иван Гришов @IvanGrishov Автор вопроса
Андрей Федоров, спасибо, посмотрю
Иван Гришов @IvanGrishov Автор вопроса

Андрей Федоров здесь высота блока не постоянная, если использовать clamp(). И шрифт не изменяется автоматически исходя из длины текста

aliencash

Иван Гришов, ну тогда ждите полноценной поддержки медиавыражений от контейнера. К сожалению, это все что вам может предложить css.

Иван Гришов @IvanGrishov Автор вопроса

Андрей Федоров, мне не важно css или js, может есть библиотека для этого на js или другое решение, бы было круто

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

Иван Гришов @IvanGrishov Автор вопроса
wadowad, спасибо большое. Ваше решение «в лоб» оказалось самым адекватным.
Решения вопроса 0
Ответы на вопрос 3

tolfy

Фирменный стиль
Ответ написан более года назад
Нравится 1 7 комментариев

SemanticMoscow

Semantic.Moscow @SemanticMoscow

ахаха!
вот это решение!
браво!
очень красиво.
только как это применить к размеру отдельного блока?

но всё равно, утащил в заметки.

Ankhena

Ankhena @Ankhena Куратор тега CSS
Хотя бы как это применить, чтобы вписался во вьюпорт и условно полностью занял его?

tolfy

Ankhena, подбором параметров, иначе пляски с буб.. JS

Ankhena

Ankhena @Ankhena Куратор тега CSS

Antony Bark, так и я о том же, что проблему это не решит. Даже при известном тексте.
Да JS не очень, при странных пропорциях блока.

tolfy

Ankhena, погодите.. У нас есть W-viewport, с неясным scroll (положим, мы не хотим ловить его ч\з JS). Есть блоковый box с известными метриками в пространстве вьюпорта. Всё, что неизвестно в уравнении, это параметры конкретного шрифта, влияющие на ширину. Количество внутренних box-ов, размер кегля, количество символов + пробелы, плавающие параметры площадок глифов, трекинг, кернинг и проч. нюансы. Так дадим чуть больше воздуха, используем хаки, типа align center. В целом, не включая перфекционизм, с VW VH можно жить. Реально злой минус — это поддержка технологии в старых версиях браузеров

tolfy

ps ищем: Fluid Font Sizes

* вообще, ребята славно поработали в направлении стандартизации CSS

tolfy

Semantic.Moscow, шагом выше привёл путь, гляньте

SemanticMoscow

Semantic.Moscow @SemanticMoscow

но это такое себе, странное.

ну нет, точно нет.

Ответ написан более года назад
Иван Гришов @IvanGrishov Автор вопроса
это другое что-то, с начертаниями шрифтов связано

SemanticMoscow

Semantic.Moscow @SemanticMoscow

есть такая фишка, называется window.getComputedStyle
можно вытягивать значения через getPropertyValue

остаётся только получить overflow: scroll и менять шрифт пока scrool не пропадёт.

olegbarabanov

Олег Барабанов @olegbarabanov
Semantic.Moscow, несколько похожее решение (с похожим принципом) как-раз представил в своем ответе.

olegbarabanov

Олег Барабанов @olegbarabanov
Программист, фрилансер (ИП)

На похожий вопрос я уже отвечал на stackoverflow, поэтому чтобы не дублировать просто дам ссылку на свой ответ c пояснением и примером кода.

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

Если вкратце, то текст в блоке оборачивается дополнительным контейнером с overflow: hidden под размер блока и враппером, который просто оборачивает текст. Взяв огромный размер шрифта (так, чтобы враппер переполнял контейнер) и затем уменьшая его, мы уменьшаем размеры враппера и как только этот враппер перестает переполнять контейнер — убираем все лишнее(и контейнер и враппер) и оставляем подобранный размер. Данный пример похож на тот, что упоминал Semantic.Moscow, с расчетом размера шрифта за счет overflow: scroll и снижения размера шрифта до тех пор, пока скролл не пропадет.

Решение не самое лучшее, но возможно оно вам поможет.

Изменение размеров в CSS

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

Необходимые условия: Базовая компьютерная грамотность, Установка базового ПО, базовые знания работы с файлами, основы HTML (Введение в HTML), и общее представление о том, как работает CSS (Введение в CSS.)
Цель: Изучить различные способы задания размеров объектов в CSS.

Размер по умолчанию или внутренний размер

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

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

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

Присваивание определенного размера

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

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

Использование процентного соотношения

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

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

Margins и paddings в процентах

Если вы установите margins и padding в процентах, вы можете заметить странное поведение. В приведенном ниже примере у нас есть блок. Мы присвоили внутреннему блоку margin 10% и padding 10%. Padding и margin сверху и снизу имеют тот же размер, что и margins слева и справа.

Например, вы можете ожидать, что процентное значение верхнего и нижнего margins будет в процентах от высоты элемента, а процентное левое и правое margins — в процентах от ширины элемента. Тем не менее, это не так!

При использовании margins и padding, заданных в процентах, значение рассчитывается на основе inline размера блока — следовательно, ширины при работе с горизонтальным языком. В нашем примере все поля и отступы составляют 10% width. Это означает, что вы будете иметь margins и padding одинакового размера по всему полю. Этот факт стоит запомнить, если вы действительно пользуетесь процентами.

Минимальные и максимальные размеры

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

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

Это очень полезно при работе с переменным объемом контента, избегая при этом переполнения.

Часто max-width применяют для уменьшения масштаба изображений, если недостаточно места для их отображения.

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

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

В приведенном ниже примере мы использовали одно и то же изображение трижды. Первому изображению было задано width: 100% и оно находится в контейнере, который больше его ширины, поэтому он растягивается до ширины контейнера. Второму изображению задано max-width: 100% , изображение достигло 100% своей ширины не растягивается, чтобы заполнить контейнер. Третье поле снова содержит то же изображение, также с max-width: 100% в этом случае вы можете увидеть, как он уменьшилось, чтобы поместиться в контейнер.

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

Единицы вьюпорта

Вьюпо́рт — это видимая область вашей страницы в браузере, который вы используете для просмотра сайта. В CSS у нас есть единицы измерения, которые относятся к размеру вьюпорта — vw единицы ширины вьюпорта и vh высоты вьюпорта. Используя эти единицы измерения, вы можете изменять размер чего-либо относительно вьюпорта пользователя.

1vh равен 1% от высоты вьюпорта и 1vw равен 1% ширины вьюпорта. Вы можете использовать эти единицы измерения для размеров блоков, а также текста. В приведенном ниже примере у нас есть блок размером 20vh и 20vw. В блоке есть буква A , которой присвоено значение font-size 10vh.

Если вы измените величину vh и vw — это изменит размер блока или шрифт; изменение размера вьюпорта также изменит их размеры, поскольку они имеют размер заданный относительно вьюпорта. Чтобы увидеть изменение примера при изменении размера вьюпорта, вам нужно будет загрузить пример в новое окно браузера, размер которого можно изменить (поскольку встроенное приложение , содержащее показанный выше пример, является его окном просмотра). Откройте пример, измените размер окна браузера и посмотрите, что происходит с размером поля и текста.

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

Проверьте свои навыки!

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

Заключение

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

В этом модуле

  1. Каскад и наследование
  2. Селекторы CSS
    • Селекторы типа, класса и ID
    • Селекторы атрибута
    • Псевдоклассы и псевдоэлементы
    • Комбинаторы
  3. Блочная модель(The box model)
  4. Фон и границы
  5. Обработка разных направлений текста
  6. Переполнение содержимого
  7. Значения и единицы измерения
  8. Размеры в CSS
  9. Элементы изображений, форм и медиа-элементы
  10. Стилизация таблиц
  11. Отладка CSS
  12. Организация вашей CSS (en-US)

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 3 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *