Размер фона / положение - покрыть шириной и минимальным смещением от вершины
У меня есть контейнер с фоновым изображением. Я хотел бы это:
- заполнить ширину контейнера все время
- если высота контейнера становится больше, изображение должно прилипать к дну и увеличивать зазор в верхней части
- если высота контейнера короче, чем изображение, он должен поддерживать зазор в 20 пикселей сверху, скрывая нижнюю часть изображения (так как оно переполняется)
- Я не знаю высоту / ширину изображения в моем CSS
- Изображение не должно искажаться (соотношение сторон должно сохраняться)
Кажется, что мне нужно contain
по ширине, но не по высоте, но тогда я не уверен, как сделать минимальное смещение от вершины.
Смотрите мои попытки здесь:
background-size: 100% auto;
background-position: left 20px;
/* works when the height is shorter than the image
------------------
| |
| |
|................|
|. .|
|. .|
|. .|
|. .bg .|
|. .|
|. .|
|. .|
------------------
. . <- this is clipped off, that is fine.
................
*/
/*
does not work when the height is larger than the image
------------------
| |
| |
|................|
|. .|
|. .|
|. .|
|. .bg .|
|. .|
|. .|
|. .|
|. .|
|. .|
|................| <- I want this to be stuck to the bottom
| |
| |
------------------
*/
background-size: 100% auto;
background-position: left bottom;
/* works when the height is taller than the image
------------------
| |
| |
| |
|................|
|. .|
|. .|
|. .|
|. .bg .|
|. .|
|. .|
|. .|
|. .|
|................| <- stuck to the bottom, good!
------------------
*/
/*
does not work when the height is shorter than the image
................
. .
. .
. .
. .bg .
. . <- This is clipped off
------------------
|. .|
|. .|
|. .|
|................|
------------------
*/
background-size: cover;
background-position: left 20px;
/* works when the width is wider than the image (scales it up)
------------------
| |
| |
|................|
|. .|
|. .|
|. .|
|. .bg .|
|. .|
|. .|
|. .|
------------------
. . <- this is clipped off, that is fine.
................
*/
/*
does not work when the width is narrower than the image, and the height is taller
------------------
| |
| |
|................|.....
|. | . <- I do not want the width to overflow
|. | .
|. | .
|. .bg | .
|. | .
|. | .
|. | .
|. | .
|. | .
|................|.....
------------------
*/
Что я хочу:
/* if the container is shorter than the image
------------------
| |
| |
|................| <- 20px offset from the top, full width of the container
|. .|
|. .|
|. .|
|. .bg .|
|. .|
|. .|
|. .|
------------------
. . <- this is clipped off, that is fine.
................
*/
/*
if the container is larger than the image
------------------
| |
| |
| |
| |
|................| <- full width of the container
|. .|
|. .|
|. .|
|. .bg .|
|. .|
|. .|
|. .|
|. .|
|. .|
|................| <- stuck to the bottom
------------------
*/
Фрагмент для тестирования:
/* width/heights are for illustrative purposes - actual width-heights are unknown */
div {
background-size: cover;
background-position: left 20px;
background-repeat: no-repeat;
margin-bottom: 50px;
border: 1px solid red;
width: 200px;
height: 300px;
}
.taller {
height: 500px;
}
.shorter {
height: 100px;
}
.wider {
width: 400px;
}
.narrower {
width: 200px;
}
<!-- this image size and the container size are variable depending on author input - these are included as test cases, but I do not know the sizes -->
<strong>Same Size</strong>
<div style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Taller</strong>
<div class="taller" style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Wider</strong>
<div class="wider" style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Narrower</strong>
<div class="narrower" style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Shorter</strong>
<div class="shorter" style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Taller & Wider</strong>
<div class="taller wider" style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Taller & Narrower</strong>
<div class="taller narrower" style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Shorter & Wider</strong>
<div class="shorter wider" style="background-image: url('https://picsum.photos/200/300');"></div>
<strong>Shorter & Narrower</strong>
<div class="shorter narrower" style="background-image: url('https://picsum.photos/200/300');"></div>
3 ответа
Это возможно, используя только CSS, но вам нужно немного изменить свою разметку, добавив контейнер div. Я сделал контейнер изменяемого размера, чтобы упростить тестирование этого решения.
.container {
resize: both;
overflow: auto;
position: relative;
width: 200px;
height: 200px;
padding-top: 20px;
display: flex;
justify-content: flex-end;
}
.image {
margin-top: auto;
width: 100%;
height: 0;
padding-top: 150%;
background-size: contain;
background-repeat: no-repeat;
}
<div class="container">
<div class="image" style="background-image: url('https://picsum.photos/200/300');"></div>
</div>
Как это устроено:
.container
имеет:
display: flex
важно, чтобы "магия маржи" работала,justify-content: flex-end
сдвинуть div с изображением вниз;padding-top: 20px
всегда держать пустое место, которое вы хотели
.image
имеет:
width: 100%
заполнить пространство горизонтально,height: 0
а такжеpadding-top: 150%
сохранить пропорции изображения,background-repeat: no-repeat
так что изображение используется только один раз, и сcontain
заполнить div горизонтальноmargin-top: auto
сdisplay: flex
of parent допускает вертикальное перемещение div, но ограничено родительским отступом,
РЕДАКТИРОВАТЬ в ответ на комментарий OP
Кажется, что вы все еще можете использовать этот метод, даже если вы не знаете ширину и высоту изображения, и, следовательно, не можете рассчитать соотношение - если вы немного измените его. Это на самом деле делает это еще проще
.container {
resize: both;
overflow: auto;
position: relative;
width: 200px;
height: 200px;
padding-top: 20px;
display: flex;
justify-content: flex-end;
}
.image {
margin-top: auto;
width: 100%;
height: auto;
}
<div class="container">
<img class="image" src='https://picsum.photos/200/300'></div>
</div>
Если контейнер выше, img будет растягиваться, если он шире, он будет растягиваться. добавление 20px сверху снизит 20px снизу.
background-size:100% 100%;
background-repeat:no-repeat;
Не видя, какая у вас разметка, я создал этот пример, к которому вы можете обратиться. Ключ в том, чтобы div располагался сверху вниз, чтобы он никогда не закрывал верхнее пространство.
Вы можете увидеть, как он изменяет размер, используя полный фрагмент страницы или https://jsfiddle.net/xen6hszn/
body{
width: 100%;
height: 100vh;
background: grey;
margin: 0;
padding: 0;
}
div {
background: url(https://wallpaperbrowse.com/media/images/_89716241_thinkstockphotos-523060154.jpg) left bottom no-repeat;
background-size: contain;
height: 80vh;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
z-index: -1;
}
<div>
</div>