Медиа-запросы

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

Включение медиа-запросов в Stencil

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

  1. Использование CSS внутри компонента Stencil поддерживает инкапсуляцию стилей для каждого компонента. Это означает, что медиа-запросы, написанные в стиле компонента, будут действовать только на его элементы, не затрагивая глобальные стили. Пример простого компонента с медиа-запросами:

    import { Component, h } from '@stencil/core';
    
    @Component({
      tag: 'responsive-component',
      styleUrl: 'responsive-component.css',
      shadow: true
    })
    export class ResponsiveComponent {
    
      render() {
        return (
          <div class="content">
            <p>Пример адаптивного компонента.</p>
          </div>
        );
      }
    }

    В файле стилей responsive-component.css можно прописать медиа-запросы:

    .content {
      background-color: lightblue;
      padding: 20px;
    }
    
    @media (max-width: 768px) {
      .content {
        background-color: lightcoral;
        padding: 10px;
      }
    }

    В этом примере фон компонента изменяется в зависимости от ширины экрана устройства.

  2. Использование глобальных стилей Если требуется задать медиа-запросы для всех компонентов приложения, можно использовать глобальные стили. Для этого создаётся глобальный файл стилей, который подключается к проекту. Например, в файле global.css можно прописать:

    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
    }
    
    @media (min-width: 1024px) {
      body {
        font-size: 18px;
      }
    }
    
    @media (max-width: 480px) {
      body {
        font-size: 14px;
      }
    }

    В этом примере медиазапросы меняют размер шрифта в зависимости от ширины экрана. Эти стили будут применяться ко всем компонентам на странице.

Применение медиа-запросов в сложных компонентах

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

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

Допустим, компонент содержит сетку, которая должна изменяться в зависимости от размера экрана:

@Component({
  tag: 'responsive-grid',
  styleUrl: 'responsive-grid.css',
  shadow: true
})
export class ResponsiveGrid {
  
  render() {
    return (
      <div class="grid">
        <div class="item">Элемент 1</div>
        <div class="item">Элемент 2</div>
        <div class="item">Элемент 3</div>
      </div>
    );
  }
}

В файле стилей responsive-grid.css можно использовать медиа-запросы для изменения количества колонок в сетке:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.item {
  background-color: #f0f0f0;
  padding: 10px;
  text-align: center;
}

@media (max-width: 768px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .grid {
    grid-template-columns: 1fr;
  }
}

Этот код позволяет адаптировать количество колонок в сетке в зависимости от ширины экрана. На экранах с шириной до 768px будет отображаться 2 колонки, а на экранах до 480px — 1 колонка.

Сложные медиа-запросы и условные классы

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

  1. Использование классов с медиа-запросами В Stencil возможно динамическое добавление классов на основе условий, таких как ширина экрана. Пример использования динамических классов с медиа-запросами:

    import { Component, h, State } from '@stencil/core';
    
    @Component({
      tag: 'responsive-class',
      styleUrl: 'responsive-class.css',
      shadow: true
    })
    export class ResponsiveClass {
      @State() isMobile: boolean = false;
    
      componentWillLoad() {
        this.updateIsMobile();
        window.addEventListener('resize', this.updateIsMobile);
      }
    
      updateIsMobile = () => {
        this.isMobile = window.innerWidth <= 768;
      };
    
      render() {
        return (
          <div class={this.isMobile ? 'mobile' : 'desktop'}>
            <p>Этот текст изменяет стили в зависимости от ширины экрана.</p>
          </div>
        );
      }
    }

    В данном примере состояние компонента отслеживает ширину экрана и добавляет соответствующий класс (mobile или desktop). Затем в стилях компонента можно использовать эти классы для изменения внешнего вида элементов:

    .mobile {
      background-color: lightgreen;
    }
    
    .desktop {
      background-color: lightblue;
    }
  2. Использование аттрибутов с медиа-запросами Еще один способ — использование аттрибутов элементов для условного применения стилей. Это позволяет более гибко управлять стилями через аттрибуты, изменяя их на основе медиа-запросов.

Оптимизация производительности при использовании медиа-запросов

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

  • Использование минимального числа медиа-запросов: Старайтесь ограничиваться лишь необходимыми запросами, избегая излишних изменений.
  • Оптимизация изображений: Используйте подходы, такие как srcset, для адаптации изображений к разным разрешениям и размерам экранов.
  • Lazy loading: Загружайте компоненты и ресурсы, связанные с медиа-запросами, только при необходимости, например, с использованием отложенной загрузки.

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