it-swarm.com.ru

Flexbox масштабирует изображение по высоте и сохраняет соотношение сторон

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

Я могу заставить изображение следовать ширине DIV, но не высоте. Поэтому портретные изображения выходят за границы DIV. 

Вот jsFiddle , чтобы продемонстрировать проблему.

html, body {
  height: 100%;
  margin: 0;
}
.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.box {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box img {
  width: auto;
  height: auto;
  max-width: 90%;
  max-height: 90%;
}
<div class="container">
  <div class="box"></div>
  <div class="box" style="background: pink;">
    <img src="//dummyimage.com/300" />
  </div>
  <div class="box"></div>
</div>

17
languitar

если вы можете перейти с flex на block:

https://jsfiddle.net/svArtist/ug6eoxfs/

как указал @janfoeh, использование object-fit: contains делает возможным:

body, html {
    height: 100%;
    margin: 0;
    padding: 0;
    overflow:hidden;
    position:relative;
}

.container {
    width: 100%;
    max-width: 100%;
    height: 100%;
    max-height: 100%;
}

.box {
    background: yellow;
    width: 100%;
    padding: 0 5%;
    box-sizing:border-box;
    max-width: 100%;
    height: 100%;
    max-height:100%;
    position:relative;
}

.box img {
    height:100%;
    max-height: 100%;
    width: auto;
    max-width: 100%;
    margin: auto;
    position:absolute;
    top:0%;
    bottom:0%;
    left:0%;
    right:0%;
    display:block;
    object-fit: contain;
}

Если нужен Flex Layout, в качестве последнего средства вы можете рассмотреть возможность использования background-image, что делает все это очень простым: https://jsfiddle.net/svArtist/e1c2tLme/

    background: url(http://placehold.it/300) no-repeat center center;
    background-size: contain;

Кроме этого, я не могу найти способ, который не включает в себя сценарии.

6
Ben Philipp

Когда вы указываете высоту в виде процентного значения, это процент по отношению к высоте родительского элемента. Это также верно для тега <img>.

В этом макете flexbox с неизвестной высотой вы можете использовать приемы position, чтобы изображение соответствовало ширине и высоте элемента flex, и использовать приемы transform для центрирования.

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.box {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}
.box:nth-child(2) {
  background: pink;
}
.box img {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
}
<div class="container">
  <div class="box"></div>
  <div class="box">
    <img src="//dummyimage.com/300" />
  </div>
  <div class="box"></div>
</div>

Вы также можете использовать background image, что может сделать это намного проще, ключом является использование значения contain. Смотрите упрощенную демонстрацию ниже.

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.box {
  flex: 1 1 auto;
}
.box:nth-child(2) {
  background: pink url(//dummyimage.com/300) no-repeat center center / contain;
}
<div class="container">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

5
Stickers

Использует flexbox! ( JSFiddle )

body, html {
    height: 100%;
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-flow: column;
    width: 100%;
    height: 100%;
}

.box {
    flex: 1 1 auto;
    background: yellow;
    display: flex;
    justify-content: center;
    align-items: stretch;
}

.box img {
    width: 100%;
    object-fit: contain;
}

Ключ заключается в том, чтобы использовать object-fit: contain; для поддержания соотношения сторон и align-items: stretch; для обеспечения того, чтобы изображение не обрезалось слева и справа (может ли это быть ошибкой?).

2
darrylyeo

Основано на ответе @darrylyeo.

.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;

  width: 100%;
  height: 100%;

  border-radius: 4px;
  background-color: hsl(0, 0%, 96%);
}

.box {
  border-radius: 4px;
  display: flex;
}

.box img {
  width: 100%;
  object-fit: contain;
  border-radius: 4px;
}
0
Ukr