Размер фона / положение - покрыть шириной и минимальным смещением от вершины - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть контейнер с фоновым изображением. Я хотел бы это:

  1. Заполните ширину контейнера постоянно
  2. если высота контейнера увеличивается, изображение должно прилипать к нижней части и увеличивать зазор в верхней части
  3. если высота контейнера короче, чем изображение, он должен поддерживать зазор в 20 пикселей вверху, скрывая нижнюю часть изображения (при переполнении)
  4. Я не знаю высоту / ширину изображения в моем CSS
  5. Изображение не должно искажаться (соотношение сторон должно сохраняться)

Похоже, мне нужно 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 &amp; Wider</strong>
<div class="taller wider" style="background-image: url('https://picsum.photos/200/300');"></div>

<strong>Taller &amp; Narrower</strong>
<div class="taller narrower" style="background-image: url('https://picsum.photos/200/300');"></div>

<strong>Shorter &amp; Wider</strong>
<div class="shorter wider" style="background-image: url('https://picsum.photos/200/300');"></div>

<strong>Shorter &amp; Narrower</strong>
<div class="shorter narrower" style="background-image: url('https://picsum.photos/200/300');"></div>

Ответы [ 3 ]

0 голосов
/ 01 мая 2018

Это возможно, используя только 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 родительского элемента допускает вертикальное перемещение 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>
0 голосов
/ 01 мая 2018

Если контейнер выше, img будет растягиваться, если он шире, он будет растягиваться. добавление 20px сверху снизит 20px снизу.

background-size:100% 100%;
background-repeat:no-repeat;
0 голосов
/ 30 апреля 2018

Не видя, какая у вас разметка, я создал этот пример, к которому вы можете обратиться. Главное, чтобы 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>
...