Единицы измерения viewport в CSS. Все 24 комбинации.

год назад·5 мин. на чтение

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

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

Оригинальные четыре единицы измерения

Основными единицами CSS являются vw, vh, vmin и vmax. Скорее всего, вы использовали или видели их раньше, поэтому рассмотрим их кратко.

vw

vw расшифровывается как Viewport Width и представляет собой процент от ширины окна просмотра. Число, помещенное перед vw, представляет собой процент от ширины области просмотра, которой будет эта длина. Например, если вы написали 10vw, то это будет представлять 10% от ширины вашего окна просмотра. Окно просмотра (viewport) — это по сути размер вашего экрана, поэтому, если бы вы были на большом рабочем столе шириной 1920 пикселей, 10vw означало бы 192 пикселя. Если бы вы вместо этого использовали мобильный телефон шириной 300 пикселей, то 10vw был бы только 30 пикселей.

vh

vh расшифровывается как Viewport Height. Он точно такой же, как vw но для высоты, а не ширины. Эти две единицы можно использовать в комбинации, чтобы легко заставить элемент заполнять весь размер экрана.
.full-screen {
  width: 100vw;
  height: 100vh;
}

vmin и vmax

vmin и vmax представляют собой максимальное и минимальное измерение области просмотра. Например, если вы работаете на телефоне шириной 300 пикселей и высотой 800 пикселей, vmin будет представлять ширину области просмотра, а vmax — высоту устройства. Эти единицы действительно полезны, если вам нужно определить размер элемента на основе наименьшего/наибольшего размера экрана. Например, следующий CSS создаст квадрат, который будет максимально большим, не переполняясь ни в каком направлении, поскольку он никогда не будет больше 100% от наименьшего размера экрана.
.no-overflow {
  width: 100vmin;
  height: 100vmin;
}

Две новых единицы

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

vi

vi расшифровывается как Viewport Inline и представляет собой встроенное (инлайн) направление вашего документа. В горизонтальном направлении это соответствует ширине окна просмотра, а в вертикальном направлении это соответствует высоте окна просмотра. Самый простой способ запомнить направление встроенного текста — помнить, что это то же направление, в котором движется ваш текст. Еще один способ запомнить это: если у вас есть два встроенных элемента (например, два span) рядом друг с другом, направление, в котором они складываются, является вашим встроенным направлением.
.horizontal {
  writing-mode: horizontal-tb;
  width: 10vi; /* То же, что и 10vw */
}

.vertical {
  writing-mode: vertical-lr;
  height: 10vi; /* То же, что и 10vh */
}

vb

vb расшифровывается как Viewport Block и представляет собой направление блока вашего документа. Это противоположно vi, поэтому в горизонтальном направлении это будет соответствовать высоте окна просмотра, а в вертикальном документе это будет представлять ширину вашего окна просмотра. Если вы изо всех сил пытаетесь запомнить эту единицу, просто помните, что направление блока всегда будет направлением, в котором блочные элементы (например, два div) будут складываться друг на друга.
.horizontal {
  writing-mode: horizontal-tb;
  width: 10vb; /* То же, что и 10vh */
}

.vertical {
  writing-mode: vertical-lr;
  height: 10vb; /* То же, что и 10vw */
}

Модификаторы единиц измерения вьюпорта

До сих пор мы рассмотрели шесть основных типов модулей области просмотра, но есть три различных модификатора, которые вы можете добавить к единицам, чтобы они вели себя по-разному, когда ваше окно просмотра может изменять размеры. Например, когда вы просматриваете веб-страницы на мобильном телефоне, вы можете заметить, что адресная строка исчезает при прокрутке вниз. Когда это происходит, ваше окно просмотра технически меняет размер, так как теперь строка URL-адреса больше не занимает часть вашего окна просмотра. Текущие блоки CSS не имеют возможности справиться с этим изменением размера области просмотра, поэтому были добавлены эти модификаторы. Этими модификаторами являются s, l и d. Для того, чтобы использовать модификатор, вам просто нужно разместить модификатор после номера и перед единицей измерения, например 10svw. Это дает нам 4 комбинации для каждого из 6 модулей области просмотра. vw, svw, lvw и dvw. До сих пор все, что мы рассмотрели в этой статье, не использовало модификатор. Если вы не используете модификатор на устройстве, например 10vw или 10vh, браузер автоматически по умолчанию использует один из 3 модификаторов в зависимости от реализации браузера.

Модификатор s

Модификатор s расшифровывается как Small и представляет собой минимально возможное окно просмотра. В нашем примере с мобильным телефоном это будет размер окна просмотра при отображении строки URL. Если вы установите для элемента значение 100svh он будет занимать 100% высоты экрана в зависимости от размера экрана при отображении строки URL. Неважно, видна ли строка URL-адреса или нет, размер этого устройства всегда будет основываться на том, каким будет окно просмотра, если будет отображаться строка URL-адреса.

Модификатор l

Модификатор l расшифровывается как Large и представляет собой максимально возможное окно просмотра. Это в значительной степени противоположно модификатору s. В нашем примере с мобильным телефоном это будет размер окна просмотра, когда строка URL-адреса НЕ отображается. Если вы установите для элемента значение 100lvh, он будет занимать 100% высоты экрана в зависимости от размера экрана, когда строка URL-адреса НЕ отображается. Неважно, видна ли строка URL-адреса или нет, это устройство всегда будет основывать свой размер на том, каким будет окно просмотра, если строка URL-адреса НЕ отображается. Это означает, что если вы установите элемент на 100lvh, а строка URL-адреса показывается, то технически он будет больше, чем экран.

Модификатор d

Модификатор d расшифровывается как Dynamic и представляет текущий размер области просмотра. Это похоже на комбинацию модификаторов s и l. В нашем примере с мобильным телефоном это всегда будет размер текущего окна просмотра, независимо от того, отображается ли строка URL-адреса или нет. Если наша строка URL-адреса отображается, то модификатор d имеет тот же размер, что и модификатор s, а если строка URL-адреса НЕ отображается, модификатор d имеет тот же размер, что и модификатор l. Во время перехода между отображаемой и скрытой строкой URL-адреса это устройство будет динамически увеличиваться в размерах, поэтому оно всегда будет заполнять все доступное пространство. Это здорово, если вам нужно гарантировать, что размер элемента всегда зависит от области просмотра, но может быть обременительным, поскольку это вызовет много перерисовок, поскольку размер постоянно меняется.

Поддержка браузеров

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

Итоги

Хотя 24 юнита могут показаться много, на самом деле это всего лишь шесть юнитов с тремя модификаторами, которые относительно просты. Эти простые комбинации, однако, дают нам большие возможности в построении идеального макета CSS.

Как обрабатывать события в React приложении

год назад·2 мин. на чтение

В этой статье рассмотрим как обработать события в React, а также о том, почему мы связываем ключевое слово `this` в классовых компонентах React.

В JSX нам нужно обернуть выражения JavaScript фигурными скобками { }. Обычный JavaScript:
<button onclick="hitMe()">hit me</button>
В ReactJS:
<button onClick={hitMe}>hitme</button>
Рассмотрим подробнее, как присоединить обработчики событий в функциональных и классовых компонентах.

Функциональные компоненты

function Button() {
  function handleClick() {
    alert('some one clicked me')
  }
  
  return (
    <button onClick={handleClick}>Click me</button>
  )
}
В React нам нужно передать функцию обработчика событий.

Передача аргументов

Мы также можем передавать аргументы в функции обработчика событий, подобные этой.
function Button() {
  function handleClick(name) {
     alert(name)
  }

  return (
    <button onClick={()=>handleClick('react')}>Click me</button>
  )
}

Классовые компоненты

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      num: 0
    }
  }

  handleInc(){
    this.setState({
      num: this.state.num+1
    })
  }

  render(){
    return (
       <div>
        <h1>Counter</h1>
        <h3>{this.state.num}</h3>
        <button onClick={this.handleInc.bind(this)}>Increment</button>
      </div>
    )
  }
}
В компонентах на основе классов нам нужно привязать this к классу, иначе this будет привязано к global window object или в строгом режиме this будет undefined. Мы можем решить эту проблему с помощью стрелочных функций, потому что в стрелочных функциях this будет привязано к его внешнему контексту выполнения. Давайте модифицируем приведенный выше компонент с помощью стрелочных функций.
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      num: 0
    }
  }

  handleInc() {
    this.setState({
      num: this.state.num+1
    })
  }

  render(){
    return (
       <div>
        <h1>Counter</h1>
        <h3>{this.state.num}</h3>
        <button onClick={()=>this.handleInc()}>Increment</button>
      </div>
    )
  }
}

Второй способ использования class fields syntax

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      num: 0
    }
  }

  // стрелочная функция
  handleInc = () => {
    this.setState({
      num: this.state.num+1
    })
  }

  render() {
    return (
       <div>
        <h1>Counter</h1>
        <h3>{this.state.num}</h3>
        <button onClick={this.handleInc}>Increment</button>
      </div>
    )
  }
}

Объект события

Мы также можем использовать объект события таким образом в react.
function Link(){

  function handleClick(e){
     console.log(e);
     e.preventDefault();
  }

  return (
      <a href="#" onClick={handleClick} >Click me</a>
  )
}