• CSS
  • Bootstrap

Как разместить несколько картинок рядом на сайте?

Здравствуйте. Вопрос по изображениям.

Что делать, если необходимо на сайте расположить рядом несколько изображений разных размеров. Например, одно горизонтальное, другое вертикальное, разные по длине и ширине. Таким образом, чтобы их общая ширина была равна ширине блока, в котором они находятся, но высота изображений была одна, без потери соотношения их сторон?

Возможно ли такое с использованием Bootstrap? При этом, нужно сохранять их адаптивность. То есть уменьшать их при уменьшении размеров экрана. Пробовал класс img-responsive, но он, как я понял, просто вписывает изображение в ширину блока...

Комментарии: 9

Сергей
Сергей
Может вам sapegin.github.io/jquery.mosaicflow/ поможет. На itchief.ru и урок по этому есть itchief.ru/lessons/bootstrap-3/bootstrap-3-create-image-galleries
Tracktor
Tracktor
Видел этот урок. Уже думал по поводу подобных галерей, но всё равно немного не то, что нужно… В примере по ссылке высота изображений разная, а я хочу получить одну высоту всех изображений в блоке и выстроить их ровненько в ряд по ширине блока.
Tracktor
Tracktor
Спасибо. Попробовал, но всё равно получается немного не то. Наверное, я не точно сформулировал задачу.
Изображения необходимо будет добавлять статьи на сайте, а скрипт поместить например перед закрытием на постоянной основе, чтобы он, видя обозначенный блок (в моём примере это div.main), совершал в нём все эти рассчёты с изображениями… Плюс, хочется видеть изображения в их полном, «необрезанном» виде. Высота контейнера при этом неважна, главная задача ровно расположить изображения по всей ширине контейнера без изменения их пропорций…
Tracktor
Tracktor
Александр, спасибо за ответ. Но похоже, мне всё-таки нужен будет вариант с Javascript. В данном способе, как я понял, изображения подключаются через css свойство background, а в моём случае изображения будут добавляться динамически (то есть, придётся к каждой статье на сайте менять это свойство для картинок). Плюс, картинок может быть не две, а больше.

На одном из форумов подсказали интересное решение на JS:

HTML:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="main" style="width: 800px; border: 1px solid black; margin: 0 auto;">
  <img src="http://nemalo.net/uploads/posts/2015-08/1440496077_java.jpg"><img src="https://trashbox.ru/ifiles/533976_72c4c8_screenshot_08/html-css-php-js-book-1.2.4-9.png">
</div>
JS:
function imgSize(href){
  var img = new Image();
  img.src = href;
  img.onload = function() {
    sum += img.width / img.height;
	loaded++;
	if (loaded == count) $('.main img').height($('.main').width() / sum);
  };
}

var sum = 0;
var count = $('.main img').length;
var loaded = 0;
$('.main img').each(function() {
  imgSize($(this).attr('src'));
});
Код работает, но есть три минуса:
1. Изображения нужно добавлять вплотную друг к другу, таким образом смотрится не очень красиво без отступов.
2. Размеры изображений вычисляются в пикселях, что приводит к потере адаптивности. Если ширину блока main задавать в процентах — размеры картинок всё равно остаются в пикселях, и при изменении размеров экрана вёрстка рушится.
3. Если нужно создать на странице, например, два таких блока по два изображения в каждом, всё равно скрипт будет считать их общие размеры, и результат получится не тот, что нужен.

К сожалению, с моим незнанием языка Javascript, не хватает мозгов, чтобы допилить данный скрипт…
Если у вас найдётся время и желание помочь с этим делом, был бы очень признателен :)
Александр Мальцев
Александр Мальцев
Можно конечно и так сделать, но тут необходимо будет всё вычислять.
С помощью JavaScript можно не только изображения, но и целые блоки добавлять.
Например, в HTML создать только контейнер:
<div id="images" class="container"></div>
Скрипт JavaScript (с использованием jQuery) для динамического вывода изображений:
<script>
$(function(){
  var images = {
    'rows': 2,
    'landscape': ['img/l1.jpg','img/l2.jpg'],
    'portrait': ['img/p1.jpg','img/p2.jpg']
  }
  var container = $('#images');
  for (var i=0; i<images['rows'];i++) {
    container.append('<div class="rowflex" style="height: 200px;">'+
      '<div id="landscape-image'+i+'" class="colflex-xs-12 colflex-md-8"></div>'+
      '<div id="portrait-image'+i+'" class="colflex-xs-12 colflex-md-4"></div>'+
      '</div>');
    $('#landscape-image'+i).css({
      'background':'url('+images['landscape'][i]+')',
      'background-size':'cover'
    });
    $('#portrait-image'+i).css({
      'background':'url('+images['portrait'][i]+')',
      'background-size':'cover'  
    });  
  }
});
</script>
Т.е. создаём объект images и записываем туда, сколько необходимо вывести количество блоков (например, 2) и также пути к изображениям для каждого блока.

Тогда эти стили можно удалить из CSS:
#landscape-image {
  background: url(img/image_1.jpg);
  background-size: cover;
}
#portrait-image {
  background: url(img/image_2.jpg);
  background-size: cover;
}
Александр Мальцев
Александр Мальцев
Можно конечно и этот доработать…
Чтобы он работал адаптивно необходимо рассчитывать тогда не высоту, а ширину и устанавливать её в процентах от ширины контейнера.
<script>
$(function () {
  // id - идентификатор блока, содержащий изображения
  // width - ширина всех изображений % от ширины контейнера
  // img-margin - отступы
  // img-radius - скруления углов
  var resizePictures = function(id,totalwidth,img_margin,img_radius){
    var sum = 0;
    var count = $(id).find('img').length;
    var loaded = 0;
    function imgSize(href){
      var img = new Image();
      img.src = href;
      img.onload = function() {
        sum += img.width / img.height;                                         
	  loaded++;
	  if (loaded == count) {
            $(id).find('img').each(function(){
            $(this).css({
              'width': ((($(this).width() / $(this).height()) / sum)*totalwidth)+'%',
              'margin': img_margin,
              'border-radius':img_radius
            });
          });
        };
      };
    };	  
    $(id).find('img').each(function() {
      imgSize($(this).attr('src'));
    });
  };
  resizePictures('#main',90,'3px','4px');
});
</script>
Добавление отступов в вышепредставленном скрипте осуществляется посредством margin, и указывать их лучше в пикселях. Иначе изображения получатся немного разные, т.к. они имеют не одинаковую ширину.
Если необходимо установить несколько таких блоков, то необходимо просто вызвать ещё раз функцию resizePictures и передать ей в качестве параметра нужный идентификатор блока.
resizePictures('#main',90,'3px','4px');
Но, решение на свойстве background даже на основании этого скрипта было бы более простым…
Tracktor
Tracktor
Громадное спасибо!
Пара вопросов:
1. Можно ли сразу добавить в скрипт несколько контейнеров, в которых будут ресайзиться изображения? например,
resizePictures('#main-1',90,'3px','4px');
resizePictures('#main-2',90,'3px','4px');
resizePictures('#main-3',90,'3px','4px');
Идея в том, чтобы подключить скрипт перед </боди> и больше к нему не возвращаться, а в статьях просто прописывать нужные классы блокам (вряд ли больше трёх будет в статье)…
2. Правильно ли я сделал, заменив «id» на «className» во всём скрипте, если хочу идентифицировать блок с изображениями по классу, а не по ид? Вроде, работает.
Александр Мальцев
Александр Мальцев
1. Да, можно:
<div id="main-1" style="margin: 0 auto; text-align:center;">
  <img src="img/1.jpg"><img src="img/2.jpg"><img src="img/3.jpg">
</div>
<div id="main-2" style="margin: 0 auto; text-align:center;">
  <img src="img/4.jpg"><img src="img/5.jpg"><img src="img/6.jpg">
</div>
<div id="main-3" style="margin: 0 auto; text-align:center;">
  <img src="img/7.jpg"><img src="img/8.jpg"><img src="img/9.jpg">
</div>
2. Можно использовать вместо id и имя класса.
Александр Мальцев
Александр Мальцев
Добрый день. Без JavaScript это можно выполнить только на Flexbox. Только вам необходимо указать высоту контейнера с изображениями.
Код HTML:
<div class="container">
  <div class="rowflex" style="height: 200px;">
    <div id="landscape-image" class="colflex-xs-12 colflex-md-8"></div>
	<div id="portrait-image" class="colflex-xs-12 colflex-md-4"></div>
  </div>
</div>
Код CSS:
.rowflex {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}
@media (min-width: 768px) {
  .colflex-md-4 {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 33.333333%;
    -ms-flex: 0 0 33.333333%;
    flex: 0 0 33.333333%;
    max-width: 33.333333%;
  }
  .colflex-md-8 {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 66.666666%;
    -ms-flex: 0 0 66.666666%;
    flex: 0 0 66.666666%;
    max-width: 66.666666%;
  }
}
@media (max-width: 767px) {
  .colflex-xs-12 {
    -webkit-box-flex: 0;
    -webkit-flex: 0 0 100%;
    -ms-flex: 0 0 100%%;
    flex: 0 0 100%%;
    max-width: 100%%;
  }
}
#landscape-image {
  background: url(img/image_1.jpg);
  background-size: cover;
}
#portrait-image {
  background: url(img/image_2.jpg);
  background-size: cover;
}