Force div sizing, чтобы вести себя как img - PullRequest
2 голосов
/ 25 марта 2020

Моя цель - создать элемент div, размер которого соответствует размеру img во всех ситуациях.

Размеры изображения мне известны: 300 * 200 пикселей.

Имитация масштабирования img, когда ширина img равна 100% : WORKS

img {
  display: block;
  max-width: 100%;
  width: 100%;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div style="width:200px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

<div style="width:400px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

Имитировать масштабирование img, когда img width is auto : FAILS

Fails: второй синий прямоугольник должен не быть шириной 100%. .image-placeholder должно иметь style="max-width:300px;", чтобы решить эту проблему.

img {
  display: block;
  max-width: 100%;
  width: auto;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div style="width:200px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

<div style="width:400px;" class="simulate-container">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>

  <div class="image-placeholder" style="max-width:300px;">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

Другое решение для поддержки ширины: авто и ширина: 100% - это flexbox.

.flex {
  display: flex;
  flex-flow: column;
  align-items: flex-start;
}

img {
  display: block;
  max-width: 100%;
  width: 100%;
  /* width: auto; It does not matter in this example */
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div class="flex simulate-container" style="width:200px;">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

<div class="flex simulate-container" style="width:400px; background: yellow;">

  <div class="image-wrapper">
    <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
  </div>

  <div class="image-placeholder">

    <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
      <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
    </div>
  </div>
</div>

Может показаться, что размер div ведет себя как img, но это не так. Если мы поместим этот div в сетку или во флекс, размер будет другим.

При Flexbox : FAILS Fails: первая синяя рамка не уменьшается.

.flex {
  display: flex;
  flex-wrap: wrap;

  justify-content: flex-start;
}

img {
  display: block;
  max-width: 100%;
  width: 100%;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div class="simulate-container" style="width:200px;">
    <div class="flex">
      <div class="flex-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="flex-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

<div class="simulate-container" style="width:400px; background: yellow;">
    <div class="flex">
      <div class="flex-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="flex-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

С Сетка : FAILS Fails: синее поле и изображение имеют одинаковый начальный размер. Пока изображение уменьшается, синее поле все еще отображается как заполненное. Они должны иметь одинаковый размер по всем трем тестам.

.grid {
  display: grid;
  grid-template-columns: auto auto 1fr;
}

img {
  display: block;
  max-width: 100%;
  width: 100%;
}

.image-placeholder {
  display: flex;
  max-width: 100%;
  background: blue;
}

.image-placeholder-inner {
  flex: 1 1 auto;
  position: relative;
}

.image-placeholder-inner img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
<div class="simulate-container" style="width:200px;">
    <div class="grid">
      <div class="grid-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="grid-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

<div class="simulate-container" style="width:400px; background: yellow;">
    <div class="grid">
      <div class="grid-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="grid-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

<div class="simulate-container" style="width:800px; background: yellow;">
    <div class="grid">
      <div class="grid-item">

        <div class="image-wrapper">
          <img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />
        </div>
      </div>
      <div class="grid-item">

        <div class="image-placeholder">

          <div class="image-placeholder-inner" style="width: 300px; padding-bottom:calc(200 / 300 * 100%);">
            <!--<img src="https://www.calliaweb.co.uk/wp-content/uploads/2015/10/300x200.jpg" />-->
          </div>
        </div>
      </div>
  </div>
</div>

Эта проблема как-то связана с тем фактом, что div width:300px имеет другое значение по сравнению с img width:300px. Я хочу имитировать поведение c, но я все еще пытаюсь. Это невозможно или есть другой способ преодолеть эту ситуацию?

Моя другая идея состояла бы в том, чтобы использовать SVG так, как он ведет себя, как образ, но было бы лучше решить это простым div.

1 Ответ

1 голос
/ 25 марта 2020

Вы пробовали холст?

Другой вариант - использовать javascript в сочетании с событиями изменения DOM и css свойствами "px" ширины / высоты или свойствами смещения (offsetWidth и offsetHeight) для его эмуляции. ... но это будет тяжелый вариант, я использую js только для более экстремальных случаев.

...