Вопрос по изображениям

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

Что делать, если необходимо расположить рядом несколько изображений разных размеров (например, одно горизонтальное, другое вертикальное, разные по длине и ширине) таким образом, чтобы их общая ширина была равна ширине блока, в котором они находятся, но высота изображений была одна, без потери соотношения их сторон? Возможно ли такое с использованием Bootstrap? При этом, нужно сохранять их адаптивность (т.е. уменьшать при уменьшении размеров экрана). Пробовал класс img-responsive, но он, как я понял, просто вписывает изображение в ширину блока…



   Вопросы 0    70 0

Комментарии (9)

  1. Сергей # 0
    Может вам sapegin.github.io/jquery.mosaicflow/ поможет. На itchief.ru и урок по этому есть itchief.ru/lessons/bootstrap-3/bootstrap-3-create-image-galleries
    1. Tracktor # 0
      Видел этот урок. Уже думал по поводу подобных галерей, но всё равно немного не то, что нужно… В примере по ссылке высота изображений разная, а я хочу получить одну высоту всех изображений в блоке и выстроить их ровненько в ряд по ширине блока.
    2. Tracktor # 0
      Спасибо. Попробовал, но всё равно получается немного не то. Наверное, я не точно сформулировал задачу.
      Изображения необходимо будет добавлять статьи на сайте, а скрипт поместить например перед закрытием на постоянной основе, чтобы он, видя обозначенный блок (в моём примере это div.main), совершал в нём все эти рассчёты с изображениями… Плюс, хочется видеть изображения в их полном, «необрезанном» виде. Высота контейнера при этом неважна, главная задача ровно расположить изображения по всей ширине контейнера без изменения их пропорций…
      1. Tracktor # 0
        Александр, спасибо за ответ. Но похоже, мне всё-таки нужен будет вариант с 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, не хватает мозгов, чтобы допилить данный скрипт…
        Если у вас найдётся время и желание помочь с этим делом, был бы очень признателен :)
        1. Александр Мальцев # +1
          Можно конечно и этот доработать…
          Чтобы он работал адаптивно необходимо рассчитывать тогда не высоту, а ширину и устанавливать её в процентах от ширины контейнера.
          <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 даже на основании этого скрипта было бы более простым…
          1. Tracktor # 0
            Громадное спасибо!
            Пара вопросов:
            1. Можно ли сразу добавить в скрипт несколько контейнеров, в которых будут ресайзиться изображения? например,
            resizePictures('#main-1',90,'3px','4px');
            resizePictures('#main-2',90,'3px','4px');
            resizePictures('#main-3',90,'3px','4px');
            
            Идея в том, чтобы подключить скрипт перед </боди> и больше к нему не возвращаться, а в статьях просто прописывать нужные классы блокам (вряд ли больше трёх будет в статье)…
            2. Правильно ли я сделал, заменив «id» на «className» во всём скрипте, если хочу идентифицировать блок с изображениями по классу, а не по ид? Вроде, работает.
            1. Александр Мальцев # 0
              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 и имя класса.
          2. Александр Мальцев # +1
            Можно конечно и так сделать, но тут необходимо будет всё вычислять.
            С помощью 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;
            }
            
          3. Александр Мальцев # 0
            Добрый день. Без 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;
            }
            

            Вы должны авторизоваться, чтобы оставлять комментарии.