DevGang
Авторизоваться

Повседневные проблемы адаптивного веб-дизайна

Часть 1. Правильный образ устройства

Адаптивный веб-дизайн (RWD) имеет важное значение в современном мире с множеством устройств. Ключевой задачей в RWD является выбор и загрузка изображения правильного размера в зависимости от размера экрана устройства. Это обеспечивает как качество изображения, так и производительность веб-сайта.

Пример использования элемента picture

Роль элемента picture в RWD

Понимание тега <picture>

  • Элемент <picture> в HTML позволяет лучше контролировать ресурсы изображений в различных сценариях.
  • Он содержит один или несколько элементов <source> и один элемент <img>.
  • Браузер оценивает каждый <source>, чтобы найти наилучшее соответствие текущему отображению, и если ни один из них не соответствует или если браузер не поддерживает <picture>, он возвращается к src элемента <img>.

Код в действии

Рассмотрим этот фрагмент кода Vue.js:

<picture>
  <source media="(min-width: 768px)" :srcset="item.largeImage">
  <source media="(max-width: 767px)" :srcset="item.smallImage">
  <img :src="item.defaultImage" :alt="item.altText">
</picture>
  • Динамический выбор изображения: в зависимости от ширины экрана загружаются разные изображения. Изображения большего размера для экранов шириной более 768 пикселей и меньшие для более узких экранов.
  • Эффективность и скорость: Этот метод оптимизирует использование полосы пропускания и сокращает время загрузки страницы за счет загрузки изображений, наиболее подходящих для дисплея зрителя.
  • Резервный механизм: элемент <img> является резервным, если ни один элемент <source> не соответствует. 

Рекомендации по использованию элемента picture

  • Художественное направление: используйте <picture> для изменения изображений для различных условий, например, для загрузки более простого изображения с меньшим количеством деталей на меньших экранах.
  • Гибкость формата: Предлагайте альтернативные форматы изображений, такие как AVIF или WEBP, которые могут поддерживаться не всеми браузерами, наряду с более универсальными форматами.
  • Оптимизированное использование пропускной способности: сэкономьте пропускную способность и сократите время загрузки страницы, загружая изображение, наиболее подходящее для дисплея зрителя.
  • Дисплеи с высоким разрешением: используйте srcset в элементе <img> для дисплеев с высоким разрешением. Это позволяет браузерам выбирать версии с меньшей плотностью в режимах экономии данных.
  • Позиционирование и размер: используйте свойства object-fit и object-position в элементе <img>, чтобы настроить расположение и размер изображения в кадре.

Почему?

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

Рассмотрение альтернативных подходов

Почему бы просто не загружать изображения на основе обнаружения устройства?

Выбор правильного метода загрузки изображений на веб-сайт, особенно в контексте адаптивного дизайна, предполагает учет как эффективности, так и удобства пользователя. Хотя обнаружение устройства пользователя на стороне сервера и последующая подача соответствующих изображений на основе этой информации является возможным подходом, существует несколько причин, по которым использование HTML-элемента <picture> или медиа-запросов CSS может быть более выгодным:

  1. Разнообразие устройств: Диапазон устройств, используемых для доступа в Интернет, огромен и постоянно развивается. Речь идет не только о разнице между настольным компьютером и мобильным устройством; необходимо учитывать различные размеры экрана, разрешения и даже скорость соединения. Использование элемента <picture> или медиазапросов CSS позволяет браузеру принимать решения в реальном времени на основе фактических характеристик устройства.
  2. Гибкость на стороне клиента: с помощью элемента <picture> или CSS решение о том, какое изображение загружать, принимается на стороне клиента на основе фактических условий на момент отображения страницы. Сюда входит не только размер экрана, но и тип соединения (например, Wi-Fi или сотовые данные), который может меняться даже в течение одного сеанса.
  3. Оптимизация производительности и пропускной способности: Обнаружение устройства на стороне сервера и обработка различных изображений на его основе может привести к ненужным накладным расходам. Элемент <picture> позволяет более эффективно загружать изображения, поскольку он может выбирать наиболее подходящее изображение на основе текущего экрана просмотра и плотности пикселей, что потенциально экономит полосу пропускания и сокращает время загрузки.
  4. Масштабируемость и обслуживание: Обслуживание системы обнаружения устройств на стороне сервера может быть сложной задачей и требовать постоянных обновлений по мере выхода на рынок новых устройств. Напротив, использование элемента <picture> или медиа-запросов CSS перекладывает эту ответственность на браузер, который регулярно обновляется для поддержки новых устройств и размеров экрана.
  5. Ориентированность на будущее: Интернет постоянно развивается, равно как и веб-стандарты и браузеры. Использование текущих стандартов, таких как элемент <picture>, гарантирует, что ваш веб-сайт с большей вероятностью останется совместимым с будущими устройствами и браузерами без необходимости существенной доработки.
  6. SEO и доступность: Поисковые системы предпочитают веб-сайты, использующие стандартный семантический HTML. Использование элемента <picture> соответствует стандартам HTML и может быть легче интерпретировано поисковыми системами, что потенциально улучшает SEO. Кроме того, программам чтения с экрана и другим вспомогательным технологиям становится проще интерпретировать информацию, что повышает доступность.

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

Более сложный пример

В этом примере я использую проект Nuxt 3 вместе с моей любимой библиотекой пользовательского интерфейса электронной коммерции Storefront UI.

Соревнование

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

Решение

В этом сценарии подход <picture> работает очень хорошо. Давайте, например, воспользуемся приложением Nuxt 3. Мы можем создать компонент, который будет загружать изображения в зависимости от размера окна браузера. Здесь мы игнорируем множество крайних случаев, чтобы сосредоточиться на рассматриваемой теме.

Давайте сосредоточимся на карусели:

~/components/Carousel.vue
<template>
  <div class="carousel">
    <div class="carousel-track" :style="{ transform: `translateX(-${currentIndex * 100}%)` }">
      <div class="carousel-item" v-for="(item, index) in items" :key="index">
        <picture>
          <source media="(min-width: 768px)" :srcset="item.largeImage">
          <source media="(max-width: 767px)" :srcset="item.smallImage">
          <img class="w-full h-auto md:w-auto" :src="item.defaultImage" :alt="item.altText">
        </picture>
      </div>
    </div>
    <div class="carousel-dots">
      <button class="dot" v-for="(item, index) in items" :key="index" :class="{ 'active': index === currentIndex }"
        @click="goToItem(index)">
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const currentIndex = ref(0);
const items = ref([
  {
    largeImage: '/images/large1.png',
    smallImage: '/images/small1.png',
    defaultImage: '/images/large1.png',
    altText: 'image 1'
  },
  {
    largeImage: '/images/large2.png',
    smallImage: '/images/small2.png',
    defaultImage: '/images/large2.png',
    altText: 'image 2'
  },
  {
    largeImage: '/images/large3.png',
    smallImage: '/images/small3.png',
    defaultImage: '/images/large3.png',
    altText: 'image 3'
  }
]);

let autoSlideInterval = null;

const startAutoSlide = () => {
  stopAutoSlide();
  autoSlideInterval = setInterval(() => {
    nextItem();
  }, 2000);
};

const stopAutoSlide = () => {
  if (autoSlideInterval) {
    clearInterval(autoSlideInterval);
    autoSlideInterval = null;
  }
};

onMounted(() => {
  startAutoSlide();
});

const nextItem = () => {
  currentIndex.value = (currentIndex.value + 1) % items.value.length;
};

const goToItem = (index) => {
  stopAutoSlide();
  currentIndex.value = index;
};

</script>

<style>
.carousel {
  overflow: hidden;
  position: relative;
}

.carousel-track {
  display: flex;
  transition: transform 0.5s ease;
  /* Smooth transition for sliding */
}

.carousel-item {
  flex: 0 0 100%;
  /* Each item takes full width of the carousel */
  /* Other styles for the item */
}

/* Enter and leave transitions */
.slide-enter-active,
.slide-leave-active {
  transition: transform 0.5s ease;
}

.slide-enter,
.slide-leave-to {
  transform: translateX(100%);
  /* Start and end state for sliding */
}

.slide-enter-to,
.slide-leave {
  transform: translateX(0);
  /* End and start state for sliding */
}

.carousel-dots {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
}

.dot {
  height: 10px;
  width: 10px;
  border-radius: 50%;
  background-color: #fff;
  margin: 0 5px;
  cursor: pointer;
  border: none;
  opacity: 0.5;
  transition: opacity 0.3s;
}

.dot.active {
  opacity: 1;
}
</style>

Эта карусель будет хорошо сочетаться с остальной частью моего пользовательского интерфейса:

~/pages/index.vue
<template>
  <div class="flex-col align-middle">
    <Carousel />
    <NewsLetterForm />
    <div class=" flex justify-center">
      <Banner />
    </div>
  </div>
</template>

Вы можете получить код здесь.

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

Источник:

#JavaScript #CSS #HTML
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться