没有预定义宽度的响应式砌体布局

Posted

技术标签:

【中文标题】没有预定义宽度的响应式砌体布局【英文标题】:Responsive Masonry layout without predefined widths 【发布时间】:2015-01-08 02:36:59 【问题描述】:

我正在使用不同尺寸的图像创建一个 2 列砌体布局。图像可以是任意大小,只要它们具有最大公约数(根据 Masonry 插件的要求)。

为了使布局具有响应性,我将砌体项目的宽度转换为百分比(或者我可以使用 min-width 和 width 100%)。

更新:我注意到许多回答的人都将两列都设为 50% 作为解决方案。这行得通,但不是目标。图像必须保留其原始图像大小。它们可以缩小但保持相同的比例。

$(function ()     
    var container = $('#container');

    // Convert .box width from pixels to percent
    $('.box').find('img').each(function () 
        var percent = ($(this).width()) / container.width() * 100 //convert to percent;
        $(this).closest('.box').css('max-width', percent + '%');
    );

    // Trigger masonry
    container.masonry(
        itemSelector: '.box',
        columnWidth: 1 //widths dividable by 1
    );
);

jsfiffle:http://jsfiddle.net/AMLqg/278/

这似乎有效。当您调整窗口大小时,这些项目是流动的。但是,如果您在较小的窗口大小(小于 2 列宽)中加载脚本,则项目会折叠。即使窗口较小,如何让砖石项目在窗口加载时保持响应?

更新:这里有更多信息以便更好地理解。无论窗口大小如何,我都试图保留 2 个响应列。列不能具有相等的宽度,因为图像具有不同的宽度。出于这个原因,我使用columnWidth: 1,因为所有宽度都可以被 1 整除。

请参阅下面的图片以获取示例。

问题:当您在小窗口中打开页面时,元素被折叠。当您将窗口大小调整为更大时,元素将保持折叠状态,直到窗口宽度大于两个元素的宽度。

目标:我试图在加载时将元素保留在 2 个响应列中,如下图所示。目前,如果在加载时窗口很大并且您将其调整为更小,但当窗口在加载时较小并且您将其变大时,它们仍会保持响应。

【问题讨论】:

将您的代码放入$(window).load(function() ,然后重试。看看这是否有效。图像没有width / height,直到它们被加载。 $(document).ready 在加载图像之前触发。 很抱歉,我在您的 JSFiddle 中没有看到问题。当窗口较小时,您不希望图像堆叠? @Godisgood 是的,我不希望它们堆叠在一起。尝试使窗口小于容器宽度并再次运行脚本。您会看到它们堆叠在一起。我试图避免这种情况。 如果你想要两个响应式列,你甚至不需要砌体布局。这可能是你的问题,你不需要砖石布局。 我将砌体留在了编辑后的响应中,但如果这是所需的输出,那就没有意义了。 【参考方案1】:

你可以试试溢出:隐藏在周围的盒子上。

【讨论】:

你的意思是#container?不幸的是,这不起作用。 @Cyber​​Junkie:我也有这个问题。也许有点不同,买你正在做某事。错误的。也许你可以在这里试试我的解决方案:***.com/questions/7971258/…。另请阅读 creator.BTW 的评论。你试过包装吗?它似乎解决了很多问题,但它不能免费用于商业用途。【参考方案2】:

使用 imagesloaded.js 和使用 css 设置的列宽,如下所示:

jsFiddle

<div id="container">
<div class="grid-sizer"></div>
<div class="box">
    <img src="http://images.huffingtonpost.com/2007-11-01-ice.jpg" />
</div>
<div class="box">
    <img src="http://www.wwalls.ru/mini/201211/57608.jpg" />
</div>
<div class="box">
    <img src="http://artistsandwriters.com/site/wp-content/uploads/2014/09/IMG_7303LR-390x150-1412284267.jpg" />
</div>
</div>

脚本

$(document).ready(function () 
 var container = $('#container');

 $('.box').find('img').each(function () 
     var percent = $(this).width() / container.width() * 50;
     $(this).closest('.box').css('max-width', percent + '%');
 );

 // Trigger masonry
 container.imagesLoaded(function () 
     container.masonry(
         itemSelector: '.box',
         columnWidth: '.grid-sizer'
     );
 );
 );

CSS

#container 
max-width:580px;

.box 
float: left;
margin-bottom: 5px;

.box img 
 width: 100%;

.grid-sizer 
 width: 50%;
 

【讨论】:

【参考方案3】:

你在寻找这样的东西吗?

Fiddle

所以,我们在这里所做的只是摆脱您的百分比计算(我真的不明白其中的必要性),并在 .box 类上设置 min-width。就像这样:

.box 
    float: left;
    min-width: 100px;

我能够重现您的问题。对于那些好奇的人来说,这就是它的样子:

问题在于 CSS 中的 float: left 规则,当 Masonry 在添加图像后进行定位计算时,它会折叠框。如果你真的需要保持那个笨重的百分比计算,你可以做一个简单的清除修复来保持这个,就像这样:

.container:after 
   content: '';
   display: table;
   clear: both;

希望有帮助!

编辑 - 基于您的 cmets:

好的,如果您总是希望有两列,这是一个更简单的更改:

摆脱这个 Javascript

// Convert .box width from pixels to percent
$('.box').find('img').each(function () 
    var percent = $(this).width() / container.width() * 100;
    $(this).closest('.box').css('max-width', percent + '%');
);

添加此 CSS

.box 
   max-width: 50%;

我认为相当简单。

Here's a fiddle, just for giggles

【讨论】:

谢谢,但这不是问题所在。当您调整窗口大小或在窗口很小时加载它时,我不希望图像在彼此下方折叠。基本上,无论窗口大小如何,我都想保留 2 列。我不知道该怎么做。 那你不能删除Masonry吗?似乎对我有用。 我必须使用砖石 我不认为没有 js 砌体元素会堆叠。我也不能使用 html 表格。 @Cyber​​Junkie – 他们肯定会堆叠起来,而且你不需要任何桌子来做这个。检查编辑,鉴于两列约束,您需要做的额外工作很少。【参考方案4】:

编辑

查看http://jsfiddle.net/gk3t009j/2/

CSS

#wrapper

    background-color: red;
    margin: 0 auto; max-width:580px;


#container,

       overflow: hidden; 
       width: 100%;

.box
       
    max-width: 290px!important; width: 50%;     


.box imgwidth: 100%;

JS

$( window ).load( function()

    var wc=$( '#container').width();
    wc=parseInt(wc);
    if( wc % 2) 
    
        var wb=$('.box').width();
        wb--;
        $('.box').width(wb)
     


    $( '#container').masonry(
    
        itemSelector: '.box',
        columnWidth: function( containerWidth ) 
            return parseInt(containerWidth / 2);
          

    );
);

HTML

<div id="wrapper">
    <div id="container">
        <div class="box">
            <img src="http://images.huffingtonpost.com/2007-11-01-ice.jpg" />
        </div>



        <div class="box">
                <img src="http://www.wwalls.ru/mini/201211/57608.jpg" />
            </div>
            <div class="box">
                <img src="http://artistsandwriters.com/site/wp-content/uploads/2014/09/IMG_7303LR-390x150-1412284267.jpg" />
            </div>
    </div>
</div>

【讨论】:

谢谢,但我无法使用该代码,因为您正在更改图像的原始宽度。 我更改了上面的代码。当容器的宽度是奇数时,我注意到砖石构成一列。【参考方案5】:

我删除了 JS 代码和一些 HTML 标记并更新了样式:

#container 
    width: 100%;

img 
    display: inline;
    vertical-align: top;
    float: left;
    min-width: 50%;
    width: 50%;

http://jsfiddle.net/org6nsr8/8/ 我同意 Josh Burgess 的观点,即不需要 Masonry 来实现这一点,看看这是否是你所追求的。

如果有不清楚的地方或您想解释什么,我很乐意详细说明。

【讨论】:

感谢您的帮助。我不能为每列使用 50% 并更改原始图像大小。目标是使用不同宽度的图像。【参考方案6】:

您不需要 javascript;只需将 .box 的 css 更改为:

.box 
    float: left;
    max-width: 50%;

【讨论】:

【参考方案7】:

我不确定这是否是您需要的。如果我正确理解了问题,您可能需要使用 max-width 而不是 width。

这是小提琴示例: http://jsfiddle.net/AMLqg/304/

我的 JS 代码:

        $(function () 

            var container = $('#container');
            var maxWidth = container.css("maxWidth");
            maxWidth = parseInt(maxWidth.substring(0,maxWidth.indexOf("px")));
            // Convert .box width from pixels to percent
            $('.box').find('img').each(function () 
                var percent = ($(this).width()) / maxWidth * 100;
                console.log(percent);
                $(this).closest('.box').css('max-width', percent + '%');
            );

            // Trigger masonry
            container.masonry(
                itemSelector: '.box',
                columnWidth: 1 //widths dividable by 1
            );
        );

【讨论】:

【参考方案8】:

在尝试了几个库做砌体布局后,我更喜欢salvattor.js

非常易于使用。您可以配置 css 的列的大小。

@media screen and (max-width: 480px)
    #grid[data-columns]::before 
        content: '1 .column.size-1of1';
    

【讨论】:

【参考方案9】:

据我所知,您希望在所有屏幕尺寸上保持 Layout 2 Column with Images 的纵横比,

检查

http://jsfiddle.net/tasaeed/k40cgfye/

CSS

#container 
  max-width: 580px;


.box 
  float: left;
  width:50%;


.box img 
  width: 100%;
  height:auto;

脚本

$(function () 

    var container = $('#container');

    // Trigger masonry
    container.masonry(
        itemSelector: '.box',
    );
);

【讨论】:

以上是关于没有预定义宽度的响应式砌体布局的主要内容,如果未能解决你的问题,请参考以下文章

第九十五节,移动流体布局和响应式布局总结

Media Query-响应式布局

Bootstrap 栅格布局的使用

响应式布局二

[JavaWeb-Bootstrap]Bootstrap响应式布局

响应式设计