没有预定义宽度的响应式砌体布局
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
?不幸的是,这不起作用。
@CyberJunkie:我也有这个问题。也许有点不同,买你正在做某事。错误的。也许你可以在这里试试我的解决方案:***.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 表格。
@CyberJunkie – 他们肯定会堆叠起来,而且你不需要任何桌子来做这个。检查编辑,鉴于两列约束,您需要做的额外工作很少。【参考方案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',
);
);
【讨论】:
以上是关于没有预定义宽度的响应式砌体布局的主要内容,如果未能解决你的问题,请参考以下文章