Выравнивание высоты изображения по ряду - PullRequest
8 голосов
/ 22 октября 2019

Борьба за то, чтобы заставить себя вести себя.

У меня есть динамический список изображений на адаптивном сайте. Макет создается там, где изображения могут находиться в строках / столбцах или строках столбцов.

Этот пример близок, но парные изображения не выравниваются снизу, так как браузер изменяет размеры ...

<div style="width:100%;">
    <div style="width:60%; display: flex;  margin-left: auto;  margin-right: auto;">
        <div id="outterrow" style="width:100%;  float:left; display: flex; padding-bottom: 1.15%; ">
            <div id="column" style="float: left;overflow: hidden;background-color: inherit;width: 49.35%;">
                <div id="row" style=" padding-right: 2.330294%; "><img title="2.jpeg" src="https://i.postimg.cc/Xv5YsYv7/2.jpg" sizes="100vw" width="100%"> 
                </div>
            </div>
            <div id="column" style="float: left;overflow: hidden;background-color: inherit;width: 50.65%;">
                <div id="row" style=" "><img title="1.jpg" src="https://i.postimg.cc/B6cQG7Dr/1.jpg" sizes="100vw" width="100%"> </div>
            </div>
        </div>
    </div>

    <div style="width:60%; display: flex;  margin-left: auto;  margin-right: auto;">

        <div id="outterrow" style="width:100%;  float:left; display: flex; padding-bottom: 1.15%; ">
            <div id="column" style="float: left;overflow: hidden;background-color: inherit;width: 100%;">
                <div id="row" style=" "><img title="3.jpg" src="https://i.postimg.cc/ZnbYYPxC/3.jpg"  sizes="100vw" width="100%"> </div>
            </div>
        </div>
    </div>
    
    <div style="width:60%; display: flex;  margin-left: auto;  margin-right: auto;">

        <div id="outterrow" style="width:100%;  float:left; display: flex; padding-bottom: 1.15%; ">
            <div id="column" style="float: left;overflow: hidden;background-color: inherit;width: 43.55%;">
                <div id="row" style=" padding-right: 2.640643%; "><img title="5.jpg" src="https://i.postimg.cc/bwsJ2Tcn/5.jpg"  sizes="100vw"  width="100%"> </div>
            </div>
            <div id="column" style="float: left;overflow: hidden;background-color: inherit;width: 56.45%;">
                <div id="row" style=" "><img title="4.jpg" src="https://i.postimg.cc/XJ07m6ZK/4.jpg" sizes="100vw" width="100%"> </div>
            </div>
        </div>
    </div>
    
</div>

Я экспериментировал с подгонкой объекта, но Safari, похоже, разваливается.

РЕДАКТИРОВАТЬ: для справки приведен пример проблемы.

enter image description here

Ответы [ 4 ]

3 голосов
/ 29 октября 2019

Конечно, вы можете использовать фоновые изображения вместо HTML-тега img. Если вы можете получить доступ к высоте изображения, я бы порекомендовал заполнить ее динамически с помощью JavaScript или PHP (или любых других настроек). Я поместил разделительный элемент внутри упаковочного контейнера, который можно использовать для этой цели.

#wrap_all {
  width:100%;
}

#inner {
  max-width:1210px;
  padding:0 50px;
  margin:0 auto;
}

.flexrow {
  display:flex;
  justify-content: space-between;
  background:#f5f5f5;
  flex-wrap:wrap;
}


.flexcol {
  flex:0 0 49%;
  background-repeat: no-repeat;
  background-size: cover;
  background-position:top center;
  margin-bottom: 2%;
}

.spacer.height-80vh {
  height:80vh;
}

.flexcol.fullwidth {
  flex:0 0 100%;
}
<div id="wrap_all">
    
  <div id="inner">
    
    <div class="flexrow">
      
      <div class="flexcol" style="background-image: url('https://i.postimg.cc/Xv5YsYv7/2.jpg')">
        <div class="spacer height-80vh"></div>
      </div>
      
      <div class="flexcol" style="background-image: url('https://i.postimg.cc/B6cQG7Dr/1.jpg')">
        <div class="spacer height-80vh"></div>
      </div>
      
      <div class="flexcol fullwidth" style="background-image: url('https://i.postimg.cc/ZnbYYPxC/3.jpg')">
        <div class="spacer height-80vh"></div>
      </div>
      
      <div class="flexcol" style="background-image: url('https://i.postimg.cc/bwsJ2Tcn/5.jpg')">
        <div class="spacer height-80vh"></div>
      </div>
      
      <div class="flexcol" style="background-image: url('https://i.postimg.cc/XJ07m6ZK/4.jpg')">
        <div class="spacer height-80vh"></div>
      </div>
      
    </div>
    
  </div>  
  
</div>
2 голосов
/ 30 октября 2019

Это называется округлением пикселей или проблемой подпикселей, и это основная математическая проблема:

У вас есть два контейнера с относительной шириной ~ 50%, которые находятся внутри отзывчивого родителя. Что должно произойти, если ширина родительского элемента является нечетным числом? Скажите 211 пикселей. 50% из 211px - это 105.5px. НО, нет такой вещи, как .5px - Ваш экран просто не может включить только половину той маленькой лампочки, которая физически определяет пиксель. Браузер округляет его до большего или меньшего числа.

Если вы посмотрите внимательно, компоновка состоит из:

  • Столбцы с десятичными значениями% для ширины (49,35%)
  • Десятичный% для интервала (заполнение: 2.330294%)
  • Изображения со случайной шириной и высотой
  • Не определена высота ни для одного из столбцов.
  • Все перенесеноотзывчивый элемент div, что означает отсутствие абсолютной ширины или высоты в любом месте.

Просто не существует решения для вставки изображений с различными размерами в элементы Div с различными размерами внутри%-ориентированного макета. Это просто слишком много пикселей округления для учета. Если вы посмотрите внимательно, этот макет будет « сломан » в 100% случаев ... он либо оставляет пустые пиксели, либо сжимает / искажает изображения внутри.

Какой бы взлом ни был у кого-либо,сгенерируйте этот маленький пустой пиксель, исказите изображения (опять же, они не имеют одинаковую высоту или ширину) или тайно спрячьте пиксели от изображения где-либо.

Теперь быстрый взлом для конкретного сниппета, который выпредставлено:

  • использовать абсолютный px для отступа влево
  • добавить пустую прокладку в нижнее заполнение с помощью: после

img {
  vertical-align: bottom;
}

.column {
  position: relative;
}

.column:after {
  content: '';
  display: block;
  position: absolute;
  bottom: 0;
  width: 100%;
  background: #fff;
  height: 6px; /* this will fake padding bottom */
}

.row {
  padding-left: 6px;
}
<div style="width:100%;">
  <div style="width:60%; display: flex;  margin-left: auto;  margin-right: auto;">
    <div id="outterrow" style="width:100%;  float:left; display: flex;">
      <div class="column" style="float: left;overflow: hidden;background-color: inherit;width: 49.35%;">
        <div class="row" ><img title="2.jpeg" src="https://i.postimg.cc/Xv5YsYv7/2.jpg" sizes="100vw" width="100%">
        </div>
      </div>
      <div class="column" style="float: left;overflow: hidden;background-color: inherit;width: 50.65%;">
        <div class="row" style=" "><img title="1.jpg" src="https://i.postimg.cc/B6cQG7Dr/1.jpg" sizes="100vw" width="100%"> </div>
      </div>
    </div>
  </div>

  <div style="width:60%; display: flex;  margin-left: auto;  margin-right: auto;">

    <div id="outterrow" style="width:100%;  float:left; display: flex;">
      <div class="column" style="float: left;overflow: hidden;background-color: inherit;width: 100%;">
        <div class="row" style=" "><img title="3.jpg" src="https://i.postimg.cc/ZnbYYPxC/3.jpg" sizes="100vw" width="100%"> </div>
      </div>
    </div>
  </div>

  <div style="width:60%; display: flex;  margin-left: auto;  margin-right: auto;">

    <div id="outterrow" style="width:100%;  float:left; display: flex; ">
      <div class="column" style="float: left;overflow: hidden;background-color: inherit;width: 43.55%;">
        <div class="row"><img title="5.jpg" src="https://i.postimg.cc/bwsJ2Tcn/5.jpg" sizes="100vw" width="100%"> </div>
      </div>
      <div class="column" style="float: left;overflow: hidden;background-color: inherit;width: 56.45%;">
        <div class="row" style=" "><img title="4.jpg" src="https://i.postimg.cc/XJ07m6ZK/4.jpg" sizes="100vw" width="100%"> </div>
      </div>
    </div>
  </div>

</div>

Опять же, в этих условиях «решения» не существует, только хаки с недостатками.

* Чтобы быть честными с браузерами, они делаютнастолько хорошая обработка пикселей, что большинство разработчиков даже не осознают, что это проблема.

0 голосов
/ 31 октября 2019

Когда CSS терпит неудачу, я иду ванилью:

document.addEventListener('DOMContentLoaded', function() {
  [...document.querySelectorAll('.flex-fill')].forEach(div => {
    [...div.querySelectorAll('img')].forEach(img => {
      img.addEventListener('load', () => {
        const box = document.createElement('div');
        const basis = img.height ? img.width * 100 / img.height : 0;
        box.style.background = `url('${img.src}') center /cover no-repeat`;
        box.style.flexBasis = `${basis}%`;
        box.setAttribute('data-basis', basis);
        div.insertBefore(box, img);
        box.appendChild(img);
      })
    })
  });
  const resizeFlexFills = _.throttle(() => {
    [...document.querySelectorAll('.flex-fill')].forEach(div => {
      const gutter = (div.currentStyle || window.getComputedStyle(div))
        .marginBottom.match(/\d+/)[0] || 0;
      const children = [...div.querySelectorAll('div')];
      const basisSum = children.map(e => e.dataset.basis)
        .reduce((a, b) => Number(a) + Number(b));
      div.style.height = `${(div.offsetWidth - ((children.length - 1) * gutter)) * 100 / basisSum}px`;
      [...div.querySelectorAll('div:not(:last-child)')].forEach(div => {
        div.style.marginRight = `${gutter}px`
      })
    })
  }, 100, {
    leading: true,
    trailing: true
  });
  window.addEventListener('load', resizeFlexFills);
  window.addEventListener('resize', resizeFlexFills);
});
.flex-fill {
  width: 100%;
  display: flex;
  height: 0;
  transition: height .3s cubic-bezier(.4, 0, .2, 1);
  /* gutter size (remove if you don't want any space between them) */
  margin-bottom: 8px;
}

.flex-fill img {
  display: none;
}

@media(max-width: 600px) {
  .flex-fill {
    height: auto !important;
    display: block;
  }
  .flex-fill img {
    display: block;
    width: 100%;
   /* needs to be same as gutter size, above */
    margin-bottom: 8px;
  }
  .flex-fill div {
    margin-right: 0 !important;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

<div class="flex-fill">
  <img title="1.jpg" src="https://i.postimg.cc/B6cQG7Dr/1.jpg">
  <img title="5.jpg" src="https://i.postimg.cc/bwsJ2Tcn/5.jpg">
  <img title="4.jpg" src="https://i.postimg.cc/XJ07m6ZK/4.jpg">
  <img title="2.jpeg" src="https://i.postimg.cc/Xv5YsYv7/2.jpg">
  <img title="3.jpg" src="https://i.postimg.cc/ZnbYYPxC/3.jpg">
</div>
<div class="flex-fill">
  <img title="2.jpeg" src="https://i.postimg.cc/Xv5YsYv7/2.jpg">
  <img title="1.jpg" src="https://i.postimg.cc/B6cQG7Dr/1.jpg">
</div>
<div class="flex-fill">
  <img title="3.jpg" src="https://i.postimg.cc/ZnbYYPxC/3.jpg">
</div>
<div class="flex-fill">
  <img title="5.jpg" src="https://i.postimg.cc/bwsJ2Tcn/5.jpg">
  <img title="4.jpg" src="https://i.postimg.cc/XJ07m6ZK/4.jpg">
</div>

Примечания:

  • что особенного в том, что сохраняются соотношения изображений с желобами или без них, и,как вы можете видеть, это идеальный пиксель
  • для этого, однако, resizeFlexFills() необходимо привязать к load и resize для обновления высоты
  • , поэтому я использовал lodashthrottle, чтобы разрешить запуск только через каждые 100ms;
  • желоб устанавливается через CSS и работает только с px. Это может быть сделано умнее, но разбор CSS-единиц в пиксели является выходом за рамки этого вопроса (ИМХО).
  • transition полностью исключен
  • это не так "отзывчивый ", но это легко сделать. чтобы это произошло, я бы оставил <img> s, отобразив их как блоки под желаемой шириной устройства, при этом изменив flex-direction на column.
    на самом деле, я сделал его отзывчивым. Если вы не хотите этого, удалите код запроса @media.
0 голосов
/ 24 октября 2019

Чтобы изображение соответствовало элементу div, необходимо добавить height: 100% в стиле img и указать высоту div в родительском элементе div изображения.

Пожалуйста, смотрите ниже код:

<div style="width:100%;height: 100%;">
  <div style="width: 100%;padding-bottom: 1.15%; ">
    <div style="width:60%; margin-left: auto;  margin-right: auto;display: flex;height: 250px;">
      <div class="row" style=" padding-right: 2.330294%;width: 50%;">
        <img title="2.jpeg" src="https://i.postimg.cc/Xv5YsYv7/2.jpg"  width="100%" height="100%"> 
      </div>
      <div class="row" style=" width: 50%;">
        <img title="1.jpg" src="https://i.postimg.cc/B6cQG7Dr/1.jpg"  width="100%"  height="100%">
      </div>
    </div>
  </div>
    
  <div style="width: 100%; padding-bottom: 1.15%; ">
    <div style="width:60%;margin-left: auto;  margin-right: auto;display: flex;">
      <div class="row" style=" ">
        <img title="3.jpg" src="https://i.postimg.cc/ZnbYYPxC/3.jpg"   width="100%">
      </div>
    </div>
  </div>
        
  <div style="width: 100%;">
    <div style="width:60%;margin-left: auto;  margin-right: auto;display: flex;height: 200px;">
      <div class="row" style=" padding-right: 2.640643%; width: 50%;">
        <img title="5.jpg" src="https://i.postimg.cc/bwsJ2Tcn/5.jpg" height="100%" width="100%"> 
      </div>
      <div class="row" style=" width: 50%;">
        <img title="4.jpg" src="https://i.postimg.cc/XJ07m6ZK/4.jpg" height="100%" width="100%"> 
      </div>
    </div>
  </div>        
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...