Css: полное руководство по функции calc()

Общие сведения

Шрифты с засечками и без них

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

Гарнитуры подразделяют на разные виды, например на шрифты с засечками и без. Засечки — декоративный элемент шрифта, но в некоторых случаях они облегчают чтение текста, хотя иногда происходит и наоборот. Первая буква (голубого цвета) на изображении набрана шрифтом с засечками Бодони. Одна из четырех засечек обведена красным цветом. Вторая буква (желтая) — набрана шрифтом Футура без засечек.

Существует множество классификаций шрифтов, например, согласно времени их создания, или стилю, популярному в определенное время. Так, есть шрифты старого стиля — группа, которая включает самые старые шрифты; более новые шрифты переходного стиля; современные шрифты, созданные после переходных шрифтов и до 1820-х годов; и, наконец, шрифты нового стиля или модернизированные старые шрифты, то есть, шрифты, выполненные по старому образцу в более позднее время. Эта классификация в основном используется для шрифтов с засечками. Существуют и другие классификации, основанные на внешнем виде шрифтов, например на толщине линий, контрасте между тонкими и толстыми линиями, и форме засечек. В отечественной печати существуют свои классификации. Например, классификация по ГОСТу группирует шрифты по наличию и отсутствию засечек, утолщению в засечках, плавному переходу от основной линии к засечке, закруглению засечки, и так далее. В классификациях русских, а также других кириллических шрифтов часто бывает категория для старославянских шрифтов.

Скриншот программы для верстки Adobe InDesign компании Adobe Systems.

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

Это особенно важно в верстке

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

Проблемы с современными системами единиц

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

Размер всех трех шрифтов в типографских пунктах одинаков, но высота знака везде разная.

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

Автор статьи: Kateryna Yuri

Единица rem: смесь px и em

Итак, мы рассмотрели:

  • – абсолютные, чёткие, понятные, не зависящие ни от чего.
  • – относительно размера шрифта.
  • – относительно такого же свойства родителя (а может и не родителя, а может и не такого же – см. примеры выше).

Может быть, пора уже остановиться, может этого достаточно?

Э-э, нет! Не все вещи делаются удобно.

Вернёмся к теме шрифтов. Бывают задачи, когда мы хотим сделать на странице большие кнопки «Шрифт больше» и «Шрифт меньше». При нажатии на них будет срабатывать JavaScript, который будет увеличивать или уменьшать шрифт.

Вообще-то это можно сделать без JavaScript, в браузере обычно есть горячие клавиши для масштабирования вроде Ctrl++, но они работают слишком тупо – берут и увеличивают всю страницу, вместе с изображениями и другими элементами, которые масштабировать как раз не надо. А если надо увеличить только шрифт, потому что посетитель хочет комфортнее читать?

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

Следующие кандидаты – и .

Разницы между ними здесь нет, так как при задании в процентах, эти проценты берутся от родителя, то есть ведут себя так же, как и .

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

Попробуем использовать этот подход для .

Протестируем на таком списке:

Пока это обычный вложенный список.

Теперь уменьшим размер шрифта до , вот что получится:

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

Можно уменьшить размер шрифта только на одном «корневом элементе»… Или воспользоваться единицей , которая, можно сказать, специально придумана для таких случаев!

Единица задаёт размер относительно размера шрифта элемента .

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

Получилось удобное масштабирование для шрифтов, не влияющее на другие элементы.

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

Единица не поддерживается в IE8-.

Case 1: Properties of all Elements Scale With The Component’s Font-Size

Let’s begin with an example of what such a component looks like:

How component resizes (Case 1)

Notice how the , and of all elements within the component change at the same time?

If your component behaves in this manner when resized, you need to size everything in s. The code then becomes:

Then, to activate the change in sizes, all you have to do is to change the component’s property.

So far so good.

Now, let’s bring the complexity up a bit.

Imagine if you had a grid like this. The vertical and horizontal spaces between each grid item needs to remain the same across all devices (for good aesthetics).

Equal margins on a 1 + 2 grid!

The markup for this grid is:

I’ve set the gutter width between each grid item to be at a root of . In order words, the computed width of the gutter is .

The challenge in this grid is to separate small component A and small component B with a margin of . We can try setting a of component B to be for start.

Unfortunately, this doesn’t turn out well. The between small component A and small component B is larger than the gutter width at a viewport above 800px.

Space between the two smaller components isn’t equal to the gutters when the screen is wider than 800px

Boo 🙁

This happens because the of the component is (or ) when the viewport is larger than . Since the is , the computed value of becomes , which is different from the we were looking for.

Grrrrr! (╯°□°)╯︵ ┻━┻

Thankfully, we can solve this issue simply by sizing in since we know where the gutter width needs to be sized according to the root .

Vertical space is now equal! 🙂

Tada! Problem solved 🙂 Here’s a Codepen for you to play with.

See the Pen REM vs EM – Case 1 by Zell Liew (@zellwk) on CodePen.

Note: You need to use Flexbox to build this grid. I won’t explain how I built it since it’s way out of scope. Check out this article if you’re interested in finding out more about Flexbox

Oh by the way, I didn’t come up with this technique. Chris Coyier wrote about it a year ago. (He’s a genius).

Anyway, are we good so far? If yes, let’s move on to case 2. If not, feel free to leave a comment and I’ll figure a way to explain this further.

CSS Reference

CSS ReferenceCSS Browser SupportCSS SelectorsCSS FunctionsCSS Reference AuralCSS Web Safe FontsCSS Font CombinationsCSS AnimatableCSS UnitsCSS PX-EM ConverterCSS ColorsCSS Color ValuesCSS Default ValuesCSS Entities

CSS Properties

align-content
align-items
align-self
all
animation
animation-delay
animation-direction
animation-duration
animation-fill-mode
animation-iteration-count
animation-name
animation-play-state
animation-timing-function

backface-visibility
background
background-attachment
background-blend-mode
background-clip
background-color
background-image
background-origin
background-position
background-repeat
background-size
border
border-bottom
border-bottom-color
border-bottom-left-radius
border-bottom-right-radius
border-bottom-style
border-bottom-width
border-collapse
border-color
border-image
border-image-outset
border-image-repeat
border-image-slice
border-image-source
border-image-width
border-left
border-left-color
border-left-style
border-left-width
border-radius
border-right
border-right-color
border-right-style
border-right-width
border-spacing
border-style
border-top
border-top-color
border-top-left-radius
border-top-right-radius
border-top-style
border-top-width
border-width
bottom
box-decoration-break
box-shadow
box-sizing
break-after
break-before
break-inside

caption-side
caret-color
@charset
clear
clip
clip-path
color
column-count
column-fill
column-gap
column-rule
column-rule-color
column-rule-style
column-rule-width
column-span
column-width
columns
content
counter-increment
counter-reset
cursor

direction
display
empty-cells
filter
flex
flex-basis
flex-direction
flex-flow
flex-grow
flex-shrink
flex-wrap
float
font
@font-face
font-family
font-feature-settings
font-kerning
font-size
font-size-adjust
font-stretch
font-style
font-variant
font-variant-caps
font-weight

grid
grid-area
grid-auto-columns
grid-auto-flow
grid-auto-rows
grid-column
grid-column-end
grid-column-gap
grid-column-start
grid-gap
grid-row
grid-row-end
grid-row-gap
grid-row-start
grid-template
grid-template-areas
grid-template-columns
grid-template-rows

hanging-punctuation
height
hyphens
@import
isolation
justify-content
@keyframes
left
letter-spacing

line-height
list-style
list-style-image
list-style-position
list-style-type

margin
margin-bottom
margin-left
margin-right
margin-top
max-height
max-width
@media
min-height
min-width
mix-blend-mode

object-fit
object-position
opacity
order
outline
outline-color
outline
-offset
outline-style
outline-width
overflow
overflow-x
overflow-y

padding
padding-bottom
padding-left
padding-right
padding-top
page-break-after
page-break-before
page-break-inside
perspective
perspective-origin
pointer-events
position
quotes

resize
right

scroll-behavior

tab-size
table-layout
text-align
text-align-last
text-decoration
text-decoration-color
text-decoration-line
text-decoration-style
text-indent
text-justify
text-overflow
text-shadow
text-transform
top

transform
transform-origin
transform-style
transition
transition-delay
transition-duration
transition-property
transition-timing-function

unicode-bidi
user-select

vertical-align
visibility

white-space
width
word-break
word-spacing
word-wrap
writing-mode

z-index

№5. Postcss-preset-env

Раз уж мы говорим про поддержку браузерами, то будет не лишним сказать про postcss-preset-env. Раньше ту же роль выполнял cssnext. Этот плагин будет полезен, если вы интересуетесь новыми веяниями в CSS.

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

Как можно догадаться по названию инструмента, он напоминает одноименный пресет у Babel. Здесь все так же – много преобразователей, собранных в один стабильный набор. Некоторые преобразования требуют последующее подключение скриптов-полифилов на клиенте, но большинство реализуется чисто средствами CSS. Насколько я понимаю, для Stage2+ скрипты не нужны. Во всяком случае не сталкивался с их необходимостью. Поправьте меня, если я что-то там пропустил.

Why Use em Units

The key value units offer is they allow sizing values to be determined by a font size other than that of the element.

For this reason, the primary purpose of units should be to allow for scalability within the context of a specific design element.

For example, you might set the , and around a navigation menu item to use values.

Menu with 0.9rem font size

This way if you change the menu’s font size the spacing around the menu items will scale proportionately, independently of the rest of the layout.

Menu with 1.2rem font size

In the earlier section on inheritance you saw how quickly keeping track of units can get out of hand. For this reason, I recommend only using units if you identify a clear need for them.

T

tab-size Задает ширину символа табуляции
table-layout Определяет алгоритм, используемый для компоновки ячеек таблицы, строк и столбцов
text-align Задает выравнивание текста по горизонтали
text-align-last Описывает, как последняя строка блока или строки перед принудительным разрывом строки выравнивается при выравнивании текста «justify»
text-combine-upright Задает комбинацию нескольких символов в пространстве одного символа
text-decoration Указывает украшение, добавляемое в текст
text-decoration-color Определяет цвет текста-украшение
text-decoration-line Указывает тип линии в тексте-украшение
text-decoration-style Задает стиль линии в оформлении текста
text-indent Задает отступ первой строки в текстовом блоке
text-justify Задает метод выравнивания, используемый при выравнивании текста «justify»
text-orientation Определяет ориентацию текста в строке
text-overflow Указывает, что должно происходить при переполнении содержащегося в тексте элемента
text-shadow Добавление тени к тексту
text-transform Управляет капитализацией текста
text-underline-position Определяет положение подчеркивания, которое задается с помощью свойства Text-декорирование
top Определяет верхнюю позицию позиционного элемента
transform Применяет 2D или 3D преобразование к элементу
transform-origin Позволяет изменить положение на преобразованных элементах
transform-style Определяет способ визуализации вложенных элементов в трехмерном пространстве
transition Сокращенное свойство для задания четырех свойств перехода
transition-delay Указывает, когда начнется эффект перехода
transition-duration Указывает, сколько секунд или миллисекунд требуется для выполнения эффекта перехода
transition-property Задает имя свойства CSS, для которого используется эффект перехода
transition-timing-function Определяет кривую скорости эффекта перехода

Case 2: Properties of Some Elements Scale With The Component’s Font-Size

Case 1 is easy to understand. The downsides though, are that it’s tough for you to stay true to your modular scale, maintain good vertical rhythms and ensure that every component is sized well AT the same time (especially when building responsive websites).

Sometimes you just need to tune a small section of your component instead of resizing everything at once. For example, you might want to change only the header at a larger viewport.

Only the headers change in size when the viewport changes

Let’s start styling this case by taking a look at the basic styles we wrote above:

Since we’re only changing the header’s s at , we can safely size every property in (with the exception of the header’s and properties)

You can then change the header’s at different viewports by simply adding a media query on them:

Tada! Notice how only the header changes as we resize the browser now? That’s how you build for case 2 🙂

One more thing.

Since it’s a best practice to use only a handful of typography sizes, I often abstract the property away from the component. This way, it becomes easy to ensure that your typography remains consistent across all components.

That’s it for case 2! Here’s a Codepen for you to play with:

See the Pen REM vs EM – Case 2 by Zell Liew (@zellwk) on CodePen.

Here’s a question you’ll probably ask, so I thought I’ll answer it first: Which method should you use?

I’ll say it depends on your design.

Personally, I find myself working with Case 2 more often than Case 1 since I prefer abstracting away typography into a file of it’s own.

Пиксели, Em, Ex и проценты — относительные размеры в CSS

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

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

Относительные размеры в CSS могут задаваться с помощью следующих единиц:

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

Далее следуют более хитрые относительные единицы размеров шрифтов, которые используются в CSS — Em и Ex. Первое — это высота шрифта используемого на компьютере пользователя по умолчанию, а Ex — высота прописной буквы «x» в используемом по умолчанию шрифте. Наверное, немного не понятно. Давайте рассмотрим это чуть поподробнее.

Многие браузеры принимают значение Ex равным половине значения Em (например, IE). У любого шрифта есть базовая линия, есть заглавные буквы и некоторые особенные строчные буквы, которые выступают за базовую линию (например, «y»). Есть еще буквы с диакритическими знаками, например, «ё» и «й» в русском языке или какие-нибудь умляуты и т.п. Поэтому размер шрифта (Em) определяется выносными элементами.

Ну, а Ex — это, как я уже говорил — высота прописной (маленькой) буквы «x» (икс) в латинской раскладке. Понятно, что в зависимости от соотношения строчных и прописных букв в шрифте, эти значения Em и Ex могут относиться к друг другу по разному, а не просто как Ex=Em/2.

Единицу относительных размеров Ex используют в CSS довольно редко, в основном применяют Em (не беря в расчет пикселы, которые используют для указания размера еще чаще). Но есть еще один способ задания относительных размеров — проценты, т.е. он должен будет высчитываться относительно чего-либо.

Если напротив правила в колонке «Percentages» ничего не написано, то значит использование процентов для этого правила не доступно. Для тех же стилевых правил, которым разрешено использовать размеры в процентах, в этой колонке будет приведено объяснение для чего это можно будет использовать.

Conclusion

We end here our encounter with CSS rem units. It is obvious that there are many advantages in using these units in our code, like responsiveness, scalability, improved reading experience, and greater flexibility in defining components. Rem units not a universal silver bullet solution but, with careful deployment, they can solve many problems that have irked developers for years. It’s up to each one of us to unlock the full potential of rems. Start your editors, experiment and share your results with the rest of us.

For more on CSS sizing units, see:

  • A Look at Length Units in CSS
  • The New CSS3 Relative Font Sizing Units
  • The Power of em Units in CSS

Body Font Size

In the table below, select a body font size in pixels (px) to display a
complete «px to em and percent» conversion table.

Tip: The default font size is usually 16px.

What is the difference between PX, EM and Percent?

Pixel
is a static measurement, while percent and EM are relative
measurements. Percent depends on its parent font size. EM is relative to the
current font size of the element (2em means 2 times the size of the current
font). So, If the font
size of body is 16 pixels, then 150% will be 24 pixels (1.5 * 16), and 2em will
be 32 pixels (16 * 2).
Look at CSS Units for more
measurement units.

❮ Previous
Next ❯

№3. Stylelint

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

Stylelint – это популярный вариант. Он умеет работать с синтаксисами основных препроцессоров, знает о последних веяниях в CSS, можно настраивать на свой вкус – конфиги похожи на те, что у eslint. Формально этот инструмент можно использовать и сам по себе, без PostCSS, но не упомянуть его здесь было бы неправильно.

O

object-fit Указывает, как содержимое заменяемого элемента должно быть установлено в поле, установленное его используемой высотой и шириной
object-position Задает выравнивание заменяемого элемента внутри его поля
opacity Задает уровень непрозрачности для элемента
order Задает порядок гибкого элемента по отношению к остальным
orphans Задает минимальное число строк, которые должны быть оставлены в нижней части страницы при возникновении разрыва страницы внутри элемента
outline Задает все свойства структуры в одном объявлении
outline-color Задает цвет контура
outline-offset Смещение контура и его выводит за пределы края границы
outline-style Задает стиль контура
outline-width Задает ширину контура
overflow Указывает, что происходит, если содержимое переполнено полем элемента
overflow-wrap Указывает, может ли обозреватель разрывать строки в словах, чтобы предотвратить переполнение (если строка слишком длинная, чтобы вместить ее содержащее поле)
overflow-x Указывает, следует ли обрезать левый/правый край содержимого, если оно переполнено областью содержимого элемента
overflow-y Указывает, следует ли обрезать верхний/нижний край содержимого, если оно переполнено областью содержимого элемента

CSS Properties

align-contentalign-itemsalign-selfallanimationanimation-delayanimation-directionanimation-durationanimation-fill-modeanimation-iteration-countanimation-nameanimation-play-stateanimation-timing-functionbackface-visibilitybackgroundbackground-attachmentbackground-blend-modebackground-clipbackground-colorbackground-imagebackground-originbackground-positionbackground-repeatbackground-sizeborderborder-bottomborder-bottom-colorborder-bottom-left-radiusborder-bottom-right-radiusborder-bottom-styleborder-bottom-widthborder-collapseborder-colorborder-imageborder-image-outsetborder-image-repeatborder-image-sliceborder-image-sourceborder-image-widthborder-leftborder-left-colorborder-left-styleborder-left-widthborder-radiusborder-rightborder-right-colorborder-right-styleborder-right-widthborder-spacingborder-styleborder-topborder-top-colorborder-top-left-radiusborder-top-right-radiusborder-top-styleborder-top-widthborder-widthbottombox-decoration-breakbox-shadowbox-sizingbreak-afterbreak-beforebreak-insidecaption-sidecaret-color@charsetclearclipclip-pathcolorcolumn-countcolumn-fillcolumn-gapcolumn-rulecolumn-rule-colorcolumn-rule-stylecolumn-rule-widthcolumn-spancolumn-widthcolumnscontentcounter-incrementcounter-resetcursordirectiondisplayempty-cellsfilterflexflex-basisflex-directionflex-flowflex-growflex-shrinkflex-wrapfloatfont@font-facefont-familyfont-feature-settingsfont-kerningfont-sizefont-size-adjustfont-stretchfont-stylefont-variantfont-variant-capsfont-weightgridgrid-areagrid-auto-columnsgrid-auto-flowgrid-auto-rowsgrid-columngrid-column-endgrid-column-gapgrid-column-startgrid-gapgrid-rowgrid-row-endgrid-row-gapgrid-row-startgrid-templategrid-template-areasgrid-template-columnsgrid-template-rowshanging-punctuationheighthyphens@importisolationjustify-content@keyframesleftletter-spacingline-heightlist-stylelist-style-imagelist-style-positionlist-style-typemarginmargin-bottommargin-leftmargin-rightmargin-topmax-heightmax-width@mediamin-heightmin-widthmix-blend-modeobject-fitobject-positionopacityorderoutlineoutline-coloroutline-offsetoutline-styleoutline-widthoverflowoverflow-xoverflow-ypaddingpadding-bottompadding-leftpadding-rightpadding-toppage-break-afterpage-break-beforepage-break-insideperspectiveperspective-originpointer-eventspositionquotesresizerightscroll-behaviortab-sizetable-layouttext-aligntext-align-lasttext-decorationtext-decoration-colortext-decoration-linetext-decoration-styletext-indenttext-justifytext-overflowtext-shadowtext-transformtoptransformtransform-origintransform-styletransitiontransition-delaytransition-durationtransition-propertytransition-timing-functionunicode-bidiuser-selectvertical-alignvisibilitywhite-spacewidthword-breakword-spacingword-wrapwriting-modez-index

Rem Units vs. Em Units

The main problem with em units is that they are relative to the font size of their own element. As such they can cascade and cause unexpected results. Let’s consider the following example, where we want lists to have a font size of , in the case where the root font size is the default :

If we have a list nested inside another list, the font size of the inner list will be 75% of the size of its parent (in this case ). We can still overcome this problem by using something along these lines:

This does the trick, however we still have to pay a lot of attention to situations where nesting gets even deeper.

With rem units, things are a simpler:

As all the sizes are referenced from the root font size, there is no more need to cover the nesting cases in separate declarations.

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

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

Adblock
detector