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

<div>
  <Menu />
  <div css={css`
      overflow-y: scroll;
      height: calc(100vh - 100px);
  `}>
        <Content/>
   </div>
</div>

Я использую реакцию и @emotion/react для написания CSS, как показано выше.

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

Чтобы решить эту проблему, мы можем использовать свойство window.innerHeight в JavaScript для динамической регулировки высоты в зависимости от фактического размера области просмотра. window.innerHeight похож на «vh», но он меняется, когда адресная строка исчезает. Вот как вы можете это сделать:

mport { useState, useEffect } from 'react';

function App() {
  const [height, setHeight] = useState(window.innerHeight);

  useEffect(() => {
    const handleResize = () => {
      setHeight(window.innerHeight);
    };

    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return (
    <div>
      <Menu />
      <div css={css`
          overflow-y: scroll;
          height: calc(${height}px - 100px);
      `}>
        <Content />
      </div>
    </div>
  );
}

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

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