CSS: 1 родитель + 2 детей. Возможно ли сделать изображение шире, чем его сиблинги, только когда оно в альбомной ориентации?

Вопрос или проблема

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

<div class="listing">
  <img src="${imgURL}" alt="${name}" />
  <div class="info">
         /* остальная часть кода */
</div>
 .listing {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: center;
    padding: 1rem;

    > img {
      flex: 1 1;
      width: 100%;
      max-width: 400px;
      object-fit: contain;
      background-color: #000000;
      border: 1px solid #000000;
    }

    .info {
      flex: 1 1;
      width: 100%;
      max-width: 400px;
      overflow: auto;
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
      border: 1px solid #000000;
}

Выше приведен код, с которым я settled. Его поведение такое, что IMG/listing всегда имеют одну и ту же ширину. Если изображение широкое, оно использует contain, чтобы добавить черные рамки сверху и снизу. Что я предпочел бы, так это следующее поведение:

квадратное изображение:
в горизонтальном режиме: одинаковая ширина, одинаковая высота с соседним элементом
после flex-wrap, в портретном режиме: одинаковая ширина, одинаковая высота с соседним элементом

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

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

Я экспериментировал с шириной/максимальной шириной у родителя и двух детей, а также с flex-basis у детей, но ничего не подходит. Object-fit – это неправильное свойство для поведения, которое я пытаюсь достичь, потому что оно влияет только на то, как изображение вписывается в контейнер, но я пытаюсь изменить ширину изображения, когда у него широкое соотношение сторон, чтобы оно было шире, чем его сосед, в горизонтальном режиме.

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

Родитель должен иметь идеальную прямоугольную форму, горизонтально в горизонтальном режиме, вертикально в портретном режиме, с обоими детьми, касающимися краев родительского контейнера.

Ответ или решение

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

HTML-структура

У вас уже есть правильная разметка HTML:

<div class="listing">
  <img src="${imgURL}" alt="${name}" />
  <div class="info">
    <!-- остальной код -->
  </div>
</div>

CSS

Исходя из ваших требований, исправьте стили в следующем смысле:

Базовые стили

Добавьте некоторые начальные стили для родителя и дочерних элементов:

.listing {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: center;
    padding: 1rem;
}

img {
    flex: 1 1 auto; /* Позволяет изображению занимать пространство */
    max-width: 100%; /* Отвечает за максимальную ширину изображения */
    height: auto; /* Соответствующая высота изображения */
    object-fit: cover; /* Заключает изображение в квадрат без искажений */
    background-color: #000000;
    border: 1px solid #000000;
}

.info {
    flex: 1 1 auto; /* То же самое для информационного блока */
    max-width: 100%;
    overflow: auto;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    border: 1px solid #000000;
}

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

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

@media (orientation: landscape) {
    .listing {
        flex-direction: row; /* Гироскопическая ориентация */
    }

    img {
        flex: 2 1 0; /* Изображение занимает больше места чем его брат */
    }

    .info {
        flex: 1 1 0; /* Информация занимает меньше места */
    }
}

@media (orientation: portrait) {
    .listing {
        flex-direction: column; /* Вертикальное расположение элементов */
    }

    img {
        flex: 1 1 auto; /* Занимает стандартное место */
        width: 100%; /* Ширина на 100% */
    }

    .info {
        flex: 1 1 auto; /* Информация также занимает стандартное место */
        width: 100%; /* Ширина на 100% */
    }
}

Как это работает?

  1. Горизонтальная ориентация (landscape): Здесь изображение будет занимать больше ширины (например, 2 части, а .info – 1 часть). Это позволяет изображению вытягиваться, когда оно широкое, чтобы превалировать над информацией. В этом случае вы также можете настроить максимальные размеры для дальнейшего управления шириной.

  2. Вертикальная ориентация (portrait): В этом режиме оба элемента занимают равное место по ширине, но высота будет зависеть от контента. Изображение будет подстраиваться под свое содержание.

Заключение

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

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

Капча загружается...