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

Сценарий:

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

Испытанный случай:

  • Лучшее, что я придумал, - это установить ширину и высоту изображения на 100%, а затем использовать object-fit: contain.
  • Однако object-fit: contain плохо работает с границами. Вместо того, чтобы окружать только изображение, граница окружает весь родительский div.
  • Эта проблема: Если есть высокое худое изображение, оно может увеличиваться или уменьшаться до 30% ширины и 100% высоты. Хотелось бы, чтобы граница тоже была в районе 30% и 100%. Однако граница размещается в области 100% ширины и 100% высоты, что я не хочу.

Какой еще метод подойдет мне здесь лучше?

Вот упрощенный взгляд на мой код:

 <!DOCTYPE html>
    <html>
    <style>
    html, body { width: 100%; height: 100% }
    #outer {
    	width: 100%; 
    	height: 100%;
    	display: flex;
    	background-color: green;
    	flex-direction: column
    }
    #top, #bottom {
    	flex: 1;
    	display: flex;
    	border: solid black 1px;	
    }
    #first, #third {
    	flex: 1;
    	background-color: blue;
    }
    #second {
    	flex: 3;
    	background-color: yellow;
    }
    #second img {
    	border: solid black 5px;
    	object-fit: contain;
    	width: 100%;
    	height: 100%;
        box-sizing: border-box;
    }
    </style>
    
    <body>
    <div id = "outer">
    	<div id = "top">
    		<div id = "first">First</div>
    		<div id = "second">
    			<img src = "https://via.placeholder.com/350x800/faa">
    		</div>
    		<div id = "third">Third</div>		
    	</div>
    	<div id = "bottom">
    		Bottom
    	</div>
    </div>
    </body>
    </html>

Если вы запустите приведенный выше фрагмент кода, вы увидите, что толстая рамка окружает всю родительскую область (показана желтым), а не просто появляется вокруг самого изображения (розовая область).

Что сделать, чтобы граница была только вокруг самого изображения?

Разъяснение

Мне нужно что-то, отвечающее следующим критериям:

  • Меньшие изображения масштабируются, чтобы соответствовать размеру родительского div.
  • Большие изображения уменьшаются, чтобы соответствовать размеру родительского div.
  • Изображения должны быть пропорциональными (т.е. изображения должны сохранять свое соотношение сторон и не искажаться).
  • Изображение должно быть по центру родительского div.
  • Изображение должно иметь границу только вокруг изображения, а не большую область.
  • Код должен работать как для портретных, так и для альбомных изображений.
  • В большинстве случаев только две стороны изображения будут касаться родительской границы, оставляя остальную часть родительского div пустым (т.е. желтый фон в моем примере кода)

На самом деле я очень удивлен, учитывая, насколько далеко продвинулся CSS, что, похоже, для этого нет простого решения.

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
0
89
3

Ответы 3

Б / у object-fit: cover так что изображение будет покрывать весь родительский элемент.
Другое решение - вставка изображения, на котором уже есть граница.
Изображение можно редактировать в режиме онлайн, чтобы прикрепить границу к самому себе.

<!DOCTYPE html>
    <html>
    <style>
    html, body { width: 100%; height: 100% }
    #outer {
    	width: 100%; 
    	height: 100%;
    	display: flex;
    	background-color: green;
    	flex-direction: column
    }
    #top, #bottom {
    	flex: 1;
    	display: flex;
    	border: solid black 1px;	
    }
    #first, #third {
    	flex: 1;
    	background-color: blue;
    }
    #second {
    	flex: 3;
    	background-color: yellow;
    }
    #second img {
    	border: solid black 5px;
    	object-fit: cover;
    	width: 100%;
    	height: 100%;
        box-sizing: border-box;
    }
    </style>
    
    <body>
    <div id = "outer">
    	<div id = "top">
    		<div id = "first">First</div>
    		<div id = "second">
    			<img src = "https://via.placeholder.com/350x800/faa">
    		</div>
    		<div id = "third">Third</div>		
    	</div>
    	<div id = "bottom">
    		Bottom
    	</div>
    </div>
    </body>
    </html>

Обновленное решение:
Итак, для этого мы можем поместить изображение в контейнер, который будет возьмите высоту и ширину в соответствии с изображением. Поместите этот div контейнера изображений в основной контейнер div. Итак, в этом случае мы поместили следующий код в #second conatiner и настроили соответствующий CSS для достижения желаемого результата.

html, body { width: 100%; height: 100% }
    
    img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    
        transform: translate(-50%, -50%);
        position: relative;
        left: 50%;
        top: 50%;
}
    #testing {
        display: inline-block;
        /* text-align: center; */
    }
    #outer {
    	width: 100%; 
    	height: 100%;
    	display: flex;
    	background-color: green;
    	flex-direction: column
    }
    #top, #bottom {
    	flex: 1;
    	display: flex;
    	border: solid black 1px;	
    }
    #first, #third {
    	flex: 1;
    	background-color: blue;
    }
    #second {
    	flex: 3;
    	background-color: yellow;
        display: flex;
        margin: 0 auto;
        justify-content: center;
    }
    #second img {
        border: solid black 5px;
        object-fit: contain;
        box-sizing: border-box;
    }
<!DOCTYPE html>
    <html>
    <body>
    <div id = "outer">
    	<div id = "top">
    		<div id = "first">First</div>
    		<div id = "second">
                <div id='testing'>
    		   
           <img src = "https://via.placeholder.com/1000x350/faa">
                </div>
    		</div>
    		<div id = "third">Third</div>		
    	</div>
    	<div id = "bottom">
    		Bottom
    	</div>
    </div>
<div id = "outer">
    	<div id = "top">
    		<div id = "first">First</div>
    		<div id = "second">
                <div id='testing'>
    		   
           <img src = "https://via.placeholder.com/350x1000/faa">
                </div>
    		</div>
    		<div id = "third">Third</div>		
    	</div>
    	<div id = "bottom">
    		Bottom
    	</div>
    </div>
    </body>
    </html>

Граница по-прежнему окружает родительский элемент, а не само изображение.

kojow7 27.09.2018 05:31

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

Abhishek Kumar 27.09.2018 05:33

Спасибо. И да, вы правы. Я просто изменил свой код, чтобы установить box-sizing: border-box на образ. Кажется, он делает то же самое, что и ваш код. Считаете ли вы, что один метод предпочтительнее другого?

kojow7 27.09.2018 05:35

Я не знаю, как я пропустил это свойство box-sizing: border-box, оно настолько распространено, что я думал, что вы изо всех сил пытались сохранить изображение с включенным этим свойством. Но да, сейчас он работает, но я думаю, вы также можете попробовать удалить object-fit: contain, чтобы посмотреть, работает ли он, я думаю, что так и будет.

Abhishek Kumar 27.09.2018 05:38

Нет, не работает. Если я удалю object-fit: contain, мой объект непропорционально растянется, чтобы заполнить как ширину, так и высоту на 100%.

kojow7 27.09.2018 06:35

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

kojow7 27.09.2018 06:39

Я обновил свой вопрос, добавив в фрагмент кода розовое изображение. Мне нужна граница вокруг этой области, а не вокруг желтой области.

kojow7 27.09.2018 06:57

@ kojow7 видите, ответ. Я знаю, что вам нужны границы вокруг изображения, но в вашем коде вы предоставляете 100% как для высоты, так и для ширины, которые будут принимать высоту и ширину изображения в соответствии с его родительским элементом. Итак, граница применена к изображению, но изображение занимает столько же места, сколько и родительское. Вы можете проверить изображение, чтобы увидеть высоту и ширину, взятые родителем и изображением.

Abhishek Kumar 27.09.2018 07:10

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

kojow7 27.09.2018 07:16

@ kojow7 приветствуется, если ответ в какой-то степени полезен. См. Обновленное решение, которое я добавил, управляя частью html и настраивая для этого css.

Abhishek Kumar 27.09.2018 08:09

К сожалению, в данном конкретном случае это работает, но не работает для изображения с большей шириной. т.е. он работает для 350x800, но не работает для 800x350.

kojow7 27.09.2018 08:14

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

Abhishek Kumar 27.09.2018 08:48

Да, ни один из них мне не подходит. Мне нужно полное изображение без прокрутки.

kojow7 27.09.2018 16:45

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

Abhishek Kumar 27.09.2018 19:50

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

kojow7 27.09.2018 22:14

@ kojow7 см. обновленный ответ, если он полезен, или мне нужно больше вникнуть в этот вопрос.

Abhishek Kumar 28.09.2018 06:07

Да, сейчас намного лучше. Он по-прежнему не увеличивает изображения меньшего размера, но является шагом в правильном направлении.

kojow7 28.09.2018 06:41

@ kojow7 дает размер, который вы ищете, это почти полный ответ, так как я тестировал такое количество измерений в скрипке, и он дает ожидаемый результат. На данный момент он поддерживает соотношение сторон, центрирует изображение, имеет границу вокруг изображения, а не на родительском. Теперь вы заходите слишком глубоко, чтобы искать случаи с особыми случаями, поскольку в большинстве случаев это рабочее решение. Посмотрите ответ в режиме full page и попробуйте этот код в какой-нибудь скрипке, чтобы увидеть результаты.

Abhishek Kumar 28.09.2018 07:13

Хотите только с высотой 100%? Если высота не 100% зависит от свойства изображения, вы можете использовать object-fit: fill; и высота: авто;

<!DOCTYPE html>
    <html>
    <style>
    html, body { width: 100%; height: 100% }
    #outer {
    	width: 100%; 
    	height: 100%;
    	display: flex;
    	background-color: green;
    	flex-direction: column
    }
    #top, #bottom {
    	flex: 1;
    	display: flex;
    	border: solid black 1px;	
    }
    #first, #third {
    	flex: 1;
    	background-color: blue;
    }
    #second {
    	flex: 3;
    	background-color: yellow;
    }
    #second img {
    	border: solid black 5px;
    	object-fit: contain;
    	width: 100%;
    	height: auto;
      box-sizing: border-box;
    }
    </style>
    
    <body>
    <div id = "outer">
    	<div id = "top">
    		<div id = "first">First</div>
    		<div id = "second">
    			<img src = "https://picsum.photos/800/800">
    		</div>
    		<div id = "third">Third</div>		
    	</div>
    	<div id = "bottom">
    		Bottom
    	</div>
    </div>
    </body>
    </html>

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

kojow7 27.09.2018 07:11

Да, извините, я отредактировал фрагмент кода. "Высота: авто;" будет окаймлять само изображение.

NayDwe 27.09.2018 07:51

Но изображение все еще выходит за пределы родительского div. Он должен отображаться только в желтом месте. Скорее всего, вы должны увидеть часть желтого родительского элемента вокруг него, так как большинство изображений не будут иметь точного соотношения родительского div.

kojow7 27.09.2018 08:09

ты имел в виду что-то подобное?

изменения, переместите width: 100% и height: 100% в родительский, добавьте max-height: 100% в img и добавьте text-align: center в родительский

Обновить:
- добавить еще один div внутри # second
- сделать # второй display: flex; flex-direction: column; justify-content: center
- добавить max-width: 100% в img - добавить max-height: 100%; max-width: 100%; height: fit-content; в добавленный div

html, body { width: 100%; height: 100% }
    #outer {
    	width: 100%; 
    	height: 100%;
    	display: flex;
    	background-color: green;
    	flex-direction: column
    }
    #top, #bottom {
    	flex: 1;
    	display: flex;
    	border: solid black 1px;	
    }
    #first, #third {
    	flex: 1;
    	background-color: blue;
    }
    #second {
    	flex: 3;
    	background-color: yellow;
    	width: 100%;
    	height: 100%;
      text-align:center;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
    #second img {
    	border: solid black 5px;
      box-sizing: border-box;
      max-height: 100%;
      max-width: 100%;
    }
    #vcenter{
      max-height: 100%;
      max-width: 100%;
      height: fit-content;
    }
<!DOCTYPE html>
    <html>
    <body>
    <div id = "outer">
    	<div id = "top">
    		<div id = "first">First</div>
    		<div id = "second">
          <div id = "vcenter">
    			<img src = "https://via.placeholder.com/350x800/faa">
          </div>
    		</div>
    		<div id = "third">Third</div>		
    	</div>
    	<div id = "bottom">
    		Bottom
    	</div>
    </div>
    </body>
    </html>

тот же код для пейзажных изображений

html, body { width: 100%; height: 100% }
    #outer {
    	width: 100%; 
    	height: 100%;
    	display: flex;
    	background-color: green;
    	flex-direction: column
    }
    #top, #bottom {
    	flex: 1;
    	display: flex;
    	border: solid black 1px;	
    }
    #first, #third {
    	flex: 1;
    	background-color: blue;
    }
    #second {
    	flex: 3;
    	background-color: yellow;
    	width: 100%;
    	height: 100%;
      text-align:center;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
    #second img {
    	border: solid black 5px;
      box-sizing: border-box;
      max-height: 100%;
      max-width: 100%;
    }
    #vcenter{
      max-height: 100%;
      max-width: 100%;
      height: fit-content;
    }
<!DOCTYPE html>
    <html>
    <body>
    <div id = "outer">
    	<div id = "top">
    		<div id = "first">First</div>
    		<div id = "second">
          <div id = "vcenter">
    			<img src = "https://via.placeholder.com/1350x200/faa">
          </div>
    		</div>
    		<div id = "third">Third</div>		
    	</div>
    	<div id = "bottom">
    		Bottom
    	</div>
    </div>
    </body>
    </html>

Это близко, но это не сработает, например, для изображения 1200 x 50. Он больше не содержится в родительском div.

kojow7 28.09.2018 06:33

обновил ответ, но мне нужно добавить еще один div для вертикального центрирования, если это приемлемо

am05mhz 28.09.2018 07:07

Другие вопросы по теме

Неверно выровненный «контур» с нечетным количеством div
Применить функцию onclick function к $ (document) .ready
Является ли использование пользовательского CSS в классах начальной загрузки плохой привычкой?
Не удается заставить навигационную панель перестать показывать горизонтальную полосу прокрутки
Как сделать так, чтобы пользовательские сообщения появлялись в разделе консоли, когда люди открывают инструменты разработчика на моем сайте?
Делает ли css text-transform capitalize другие буквы строчными?
Как создать адаптивную карусель Bootstrap со статическим текстом заголовка героя, содержащимся в элементе контейнера?
Повернуть и разместить элемент заподлицо с краем родительского элемента, независимо от длины содержимого
Глобальная переменная не обнаруживается при использовании jquery, но ошибки нет
Почему мой div, расположенный (абсолютный) над изображением, скользит вверх, когда я уменьшаю ширину экрана?