Я хотел бы разместить фотографию под некоторым текстом. Я хочу, чтобы фотография была горизонтально по центру и уменьшалась по мере необходимости, чтобы вписаться в оставшееся прямоугольное пространство между концом текста и нижним краем окна браузера. Она не должна увеличиваться более чем на 100% от своего оригинального размера, если место предоставляет больше чем достаточно. Появление полос прокрутки никогда не должно быть необходимо.
Вот демонстрация. Основные моменты:
- html, как оформлено, всегда равно пространству внутри окна. Это пространство, которое я не хочу превышать.
- Я установил отступы body в ноль, чтобы он накладывался на пространство html (в противном случае, стандартный отступ сместил бы body вниз и вправо, выходя за пределы области html и активируя полосы прокрутки).
- Я определяю div (.outer-div) внутри и накладываю его на body. Это дает мне контейнер, который гарантированно не будет иметь какого-либо пользовательского агентского стиля. Я восстанавливаю отступ для левой и правой стороны, делая его симметричным внутри body. Я определяю его с display: flex и flex-flow: column, потому что кто-то так сказал 🙂
- Я создаю элемент flex, .inner-fixed-div, чтобы разместить текст в верхней части страницы.
- Я создаю еще один элемент flex, .inner-remaining-div, чтобы занять неиспользуемое прямоугольное пространство под текстом. Это контейнер, в который должно помещаться изображение. Он установлен на flex-grow: 1, в соответствии с решением flex, которое я пытался применить.
- Я создаю контейнер для изображения, .picture-div. display: inline-block заставляет его реагировать на text-align: center своего контейнера.
- Наконец, img оформляется с width: 100% и height: auto, что, как я понял, будет масштабировать изображение, чтобы оно поместилось в своем контейнере, сохраняя соотношение сторон.
Большинство дублирующихся вопросов, предложенных Мастером, касались чрезмерного белого пространства внизу страницы. Этот ответ полагался на магические числа; т.е. пиксельные размеры различных компонентов страницы. Я не хочу решение, которое должно знать абсолютный размер чего-либо – должен быть самоподдерживающийся способ это сделать.
Обратите внимание, что использование изображения 600×400 пикселей в демонстрации является произвольным. Фактическое изображение, выбрано CGI-скриптом, который пишет html, будет варьироваться в размерах от меньшего, чем доступное пространство (в этом случае оно не должно увеличиваться), до большего, чем доступное пространство (в этом случае оно должно быть уменьшено, чтобы плотно вписаться в доступное пространство).
/* Все контуры - это "внутренние контуры": их отрицательный отступ делает
их *внешние* края следуют за контейнером. Это сделано потому,
что в противном случае контур самого внешнего контейнера, HTML, не
был бы виден на северной и западной сторонах окна */
html {
height: 100%;
width: 100%;
/* Контур показывает, что "html" всегда идеально подходит под окно */
outline: 6px dashed black;
outline-offset: -6px;
}
body {
margin: 0;
/* предотвратить смещение body в юго-восточном направлении */
height: 100%;
/* body должен идеально накладываться на html */
width: 100%;
outline: 4px dashed red;
outline-offset: -4px;
}
.outer-div {
display: flex;
flex-flow: column;
height: 100%;
/* Теперь создаем отступы слева/справа */
margin: 0 0.5em;
}
.inner-fixed-div {
outline: 4px dotted blue;
outline-offset: -2px;
}
.inner-remaining-div {
text-align: center;
flex-grow: 1;
}
.picture-div {
outline: 4px dashed fuchsia;
outline-offset: -4px;
/* Позволяет реагировать на text-align родителя */
display: inline-block;
}
.picture-div-img {
outline: 4px dashed purple;
outline-offset: -4px;
width: 100%;
height: auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="outer-div">
<div class="inner-fixed-div">
<h1>Статическая часть</h1>
<p>
Lorem ipsum odor amet, consectetuer adipiscing elit. Per dignissim arcu imperdiet accumsan suscipit. Nisl donec ultrices dui fames dapibus neque sollicitudin vitae. Ut parturient elementum cursus sodales sem sed praesent parturient. Rutrum ultricies erat
finibus taciti ante feugiat dictumst dictum. Imperdiet lobortis penatibus non imperdiet ridiculus ac gravida. Platea lobortis tempor tempus lacus dui felis.
</p>
<h2>Оставшееся пространство будет содержать фотографию, уменьшенную по мере необходимости
</h2>
<p>
Оставшееся пространство должно быть точно ограничено контейнером HTML (толстый пунктирный черный контур). Фотография должна быть по центру, она должна динамически изменять размер, сохраняя пропорции, по мере изменения размеров окна. <i>Не должно быть необходимости в полосах прокрутки.</i>
</p>
</div>
<div class="inner-remaining-div">
<div class="picture-div">
<img src="https://placehold.co/600x400?text=600+x+400\npx" class="picture-div-img">
</div>
</div>
</div>
</body>
</html>
Я не знаю, решит ли мой ответ вашу проблему идеально, но я рекомендую это…
Используйте изображение как фоновое изображение css div
вместо того, чтобы использовать элемент img
.
Тогда вы можете ограничить ширину и высоту вашего inner-remaining-div
с помощью свойств CSS background-position
и background-size
следующим образом:
.inner-remaining-div
{
width: 100%;
height: auto;
background-image: url('https://placehold.co/600x400?text=600+x+400\npx');
background-repeat: no-repeat;
background-position: top center;
background-size: min(100%, 600px) max(auto, 400px);
}
Выровненная фоновая картинка к bottom
сделает нижнюю часть вашего изображения и нижнюю часть вашего div
идеально соединенными. Но если ваше изображение превышает max-height
, верхняя часть вашего изображения будет потеряна/скрыта.
Выровненная фоновая картинка к top
сделает верхнюю часть вашего изображения и верхнюю часть вашего div
идеально соединенными. Но если ваше фоновое изображение превышает max-height
, нижняя часть вашего изображения будет потеряна/скрыта.
Я также рекомендую вам прочитать ссылки ниже для более подробной информации:
https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat
https://developer.mozilla.org/en-US/docs/Web/CSS/background-position
https://developer.mozilla.org/en-US/docs/Web/CSS/background-size
Там есть хорошие примеры и площадка для тестирования…
Вы также можете обойтись элементом img
, но вам придется работать с большим количеством JavaScript и использовать свойство CSS overflow:hidden
в ваших элементах div
… (Я не знаю ни одного более простого способа добиться этого с элементом img
)
Ниже я просто отредактировал ваш пример, исправив его определенным образом.
/* Все контуры - это "внутренние контуры": их отрицательный отступ делает
их *внешние* края следуют за контейнером. Это сделано потому,
что в противном случае контур самого внешнего контейнера, HTML, не
был бы виден на северной и западной сторонах окна */
html {
height: 100%;
width: 100%;
/* Контур показывает, что "html" всегда идеально подходит под окно */
outline: 4px double black;
outline-offset: -4px;
}
body {
margin: 0;
/* предотвратить смещение body в юго-восточном направлении */
height: 100%;
/* body должен идеально накладываться на html */
width: 100%;
outline: 4px dashed;
outline-color: rgba( 255 0 0 / 1);
outline-offset: -4px;
}
.outer-div {
display: flex;
flex-flow: column;
height: 100%;
/* Теперь создаем отступы слева/справа */
margin: 0 0.5em;
}
.inner-fixed-div {
outline: 4px dotted blue;
outline-offset: -2px;
}
.inner-remaining-div {
text-align: center;
flex-grow: 1;
outline: 4px dashed lime;
outline-offset: -4px;
width: 100%;
height: auto;
background-image: url('https://placehold.co/600x400?text=600+x+400\npx');
background-repeat: no-repeat;
background-position: top center;
/* вы можете исправить это любым способом, который лучше для вас */
background-size: min(100%, 600px) min(100%, 400px);
}
/*
.picture-div {
outline: 4px dashed fuchsia;
outline-offset: -4px;
/ * Позволяет реагировать на text-align родителя * /
display: inline-block;
width: min(100%, 600px);
height: max(auto, 600px);
}
.picture-div-img {
outline: 4px dashed purple;
outline-offset: -4px;
width: 100%;
height: auto;
}
*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="outer-div">
<div class="inner-fixed-div">
<h1>Статическая часть</h1>
<p>
Lorem ipsum odor amet, consectetuer adipiscing elit. Per dignissim arcu imperdiet accumsan suscipit. Nisl donec ultrices dui fames dapibus neque sollicitudin vitae. Ut parturient elementum cursus sodales sem sed praesent parturient. Rutrum ultricies erat
finibus taciti ante feugiat dictumst dictum. Imperdiet lobortis penatibus non imperdiet ridiculus ac gravida. Platea lobortis tempor tempus lacus dui felis.
</p>
<h2>Оставшееся пространство будет содержать фотографию, уменьшенную по мере необходимости
</h2>
<p>
Оставшееся пространство должно быть точно ограничено контейнером HTML (толстый пунктирный черный контур). Фотография должна быть по центру, должна динамически изменяться, сохраняя пропорции, по мере изменения размеров окна. <i>Не должно быть необходимости в
полосах прокрутки.</i>
</p>
</div>
<div class="inner-remaining-div">
<!--
<div class="picture-div">
"https://placehold.co/600x400?text=600+x+400\npx"
</div>
-->
</div>
</div>
</body>
</html>
Ответ
Чтобы сделать изображение, которое расположено под текстом на веб-странице, и чтобы оно центрировалось по горизонтали, а также изменяло размер в зависимости от оставшегося прямоугольного пространства между концом текста и нижней границей окна браузера (без необходимости появления полос прокрутки), можно использовать следующий подход с помощью CSS Flexbox. Вот полное решение:
HTML
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Центрированное изображение</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="outer-div">
<div class="inner-fixed-div">
<h1>Статическая часть</h1>
<p>
Некоторые текстовые данные здесь. Этот текст занимает верхнюю часть страницы.
</p>
<h2>Оставшееся пространство будет содержать фото, масштабируемое при необходимости</h2>
<p>
Это пространство должно быть четко ограничено контейнером HTML. Фото должно быть центрировано и масштабироваться динамически, сохраняя аспект при изменении размеров окна.
</p>
</div>
<div class="inner-remaining-div">
<div class="picture-div">
<img src="https://placehold.co/600x400?text=600+x+400" class="picture-div-img" alt="Пример изображения">
</div>
</div>
</div>
</body>
</html>
CSS (styles.css)
/* Обеспечиваем, чтобы html занимал всю высоту и ширину окна */
html {
height: 100%;
width: 100%;
outline: 6px dashed black; /* Демонстрация границ контейнера */
outline-offset: -6px;
}
body {
margin: 0; /* Убираем отступы у body */
height: 100%; /* Адаптируем под html */
width: 100%;
}
.outer-div {
display: flex;
flex-direction: column;
height: 100%;
margin: 0 0.5em; /* Устанавливаем симметричные отступы */
}
.inner-fixed-div {
outline: 4px dotted blue; /* Граница для визуализации статического контейнера */
}
.inner-remaining-div {
flex-grow: 1; /* Заполняем оставшееся пространство */
text-align: center; /* Центрируем содержимое */
}
.picture-div {
display: inline-block; /* Чтобы изображение реагировало на центровку */
}
.picture-div-img {
max-width: 100%; /* Ограничиваем ширину изображения */
height: auto; /* Сохраняем соотношение сторон */
}
/* Для более продвинутого управления можно также добавить дополнительные стили для изображения */
Описание
- html и body: Устанавливаются 100% высоты и ширины, чтобы они заполняли всю вместимость окна без прокруток.
- flexbox: Используется для вертикальной компоновки блоков (
inner-fixed-div
иinner-remaining-div
). - Изображение: Устанавливается с
max-width: 100%
иheight: auto
, чтобы сохранить его пропорции и подстраиваться под доступное пространство.
Когда вы открываете эту страницу, изображение будет находиться точно внизу оставшегося пространства и автоматически изменять размер, чтобы адаптироваться к размеру окна, сохраняя при этом пропорции. Не будет необходимости в полосах прокрутки, и изображение не будет увеличиваться больше своего оригинального размера.