简体   繁体   English

CSS列布局问题

[英]css column layout issue

I have a dynamic-ish layout with columns, where the number of columns depends on the window width. 我有一个带有列的动态图像布局,其中列数取决于窗口宽度。

Using the image as an example, I have content boxes, which the user can collapse. 以图像为例,我有一个内容框,用户可以折叠它。 If the screen was wide enough there would be 3 columns. 如果屏幕足够宽,将有3列。

Now having a smaller window there's only 2 columns, but when the top left box is collapsed, the box beneath doesn't follow upwards. 现在有一个较小的窗口,只有2列,但是当左上方的框被折叠时,下面的框不会向上移动。

I've tried using the column-count CSS propery, but can't make it work. 我尝试使用列数CSS属性,但无法使其正常工作。 In the specific examples if I have column count 2 it puts 2 boxes in the right column instead of the left. 在特定示例中,如果我的列数为2,则将2个框放在右列而不是左边。

My example CSS: 我的示例CSS:

#content{
width:100%;;
height:100%;
display:inline-block;
}
#content div{
     border-color:black;
    border-style:solid;
    border-width:2px;
    display:inline-block;
    width:300px;

    vertical-align:top;
}
#box1{
   height:50px; 
}
#box2{
   height:100px;
}
#box3{
   height:30px;
}

Here's a simple jsfiddle of how I'm trying to do it. 这是我尝试执行此操作的简单方法。

http://jsfiddle.net/5cn6ya75/ http://jsfiddle.net/5cn6ya75/

在此处输入图片说明

Are there any CSS properties of html element structures that makes this possible. 是否有html元素结构的CSS属性使之成为可能。 So far the only solutions i can find either needs me to have a fixed number of columns, or a fixed height on content boxes. 到目前为止,我能找到的唯一解决方案要么需要我具有固定数量的列,要么需要内容框上的高度固定。

EDIT: In my search for an answer i've come across shapeshifter, which seems to be able to fix my issue, but by using absolute position and then calculate the offset to other element. 编辑:在寻找答案的过程中,我遇到了shapeshifter,它似乎能够解决我的问题,但是使用绝对位置,然后计算到其他元素的偏移量。 I'm still very interested in a cleaner css way of creating a dynamic x-column layout, with variable content-box-sizes(collapsable), where elements align topside to the closest element in their column. 我仍然对创建具有可变content-box-sizes(collapsable)的动态x列布局的更简洁的CSS方式感兴趣,该方式中元素的顶部对齐到其列中最接近的元素。

If I've understood your problem correctly, you can absolutely do this without javascript, provided you're targeting modern browsers. 如果我正确理解了您的问题,那么只要您将现代浏览器作为目标,就可以完全不用JavaScript就能做到。 As with most complex layouts, the appropriate tool for the job is flexbox . 与大多数复杂的布局一样,适合该工作的工具是flexbox

So here's what I think you're trying to do: 所以这就是我想您要尝试做的:

  • if the viewport is sufficiently wide, lay out all boxes in columns 如果视口足够宽,则将所有方框放在列中
  • if the viewport is not sufficiently wide, lay out boxes vertically, wrapping to as many columns as necessary 如果视口足够宽,布局垂直盒,包装纸,以尽可能多列

If that's correct, the crux of what you need is 如果这是正确的,那么您需要的关键是

@media any and (max-width:[width]) {
  #content {
    display:flex;
    flex-direction: column;
    flex-wrap:wrap;
  }
}

You won't necessarily need rules on the child boxes, but you can manipulate the order in which they appear when "collapsing" other boxes: for example, the following moves #div1 to the end 您不一定需要子框上的规则,但是您可以操纵“折叠”其他框时它们出现的顺序:例如,以下代码将#div1移到末尾

#content div {
  order:0;
}
#div1 {
  order:1 !important;
}

I've updated your fiddle with the display:flex declaration on #content and some explicit sizes on the children; 我用#content上的display:flex声明和子级上的一些显式尺寸更新了您的小提琴 if you play with those sizes you should be able to get a feel for how it works. 如果您使用这些尺寸,则应该能够感觉到它的工作原理。

You may need some further tweaks to control whether the child div s expand to fill all available space, and how the columns are spaced. 您可能需要做一些进一步的调整,以控制子div是否扩展为填充所有可用空间以及列的间距。

I would recommend you to use Masonry . 我建议您使用砖石
Its a JavaScript library for cascading grid style layouts like yourse. 它是一个JavaScript库,用于层叠像yourse这样的网格样式布局。 I'm using it as jQuery Plugin , but you can use it standalone as well. 我将其用作jQuery Plugin ,但您也可以独立使用它。

If you resize the masonary homepage you can see how it works. 如果您调整砖石主页的大小,则可以看到它的工作方式。 In addition you have a lot of Options to customize it. 此外,您还有很多自定义选项


About Shapeshift : 关于Shapeshift

I did't know about shapeshift, but it seems like it would do your Job as well. 我不知道变形,但似乎它也可以完成您的工作。 I think it has a bit too much overhead , because of the Drag&Drop etc. functions you don't Need (And if youre not using JQuery anyway that comes on top) 我认为这有点过多的开销 ,因为您不需要使用Drag&Drop等功能(并且如果您不使用JQuery,那将是最重要的)


"Simple" CSS: “简单” CSS:
Callums Statements are right. 卡勒姆声明是正确的。 The is no automatic way in CSS3. CSS3中没有自动方法。 You could use CSS media querys to set some Breakpoints , but it would be really hard work to find the right Breakpoints & Values (I don't think ist worth the time). 您可以使用CSS媒体查询来设置一些Breakpoints ,但是要找到正确的Breakpoints和Values确实很困难(我认为不值得)。


As I said (and the other guys before too) there is no clean and "good" CSS Solution and no CSS Grid System yet aswell. 正如我说过的(以及之前的其他人一样),还没有干净且“好”的CSS解决方案,也没有CSS网格系统。 The best way is to use a JavaScript libary (with or without JQuery). 最好的方法是使用JavaScript库(带有或不带有JQuery)。

 $( function() { $('#container').masonry({ itemSelector: '.item', columnWidth: 70 }); }); 
 .content{ width:100%;; height:100%; display:inline-block; } .content div{ border-color:black; border-style:solid; border-width:2px; display:inline-block; width:300px; vertical-align:top; float: left; margin: 5px; } #box1{ height:50px; } #box2{ height:100px; } #box3{ height:30px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="http://masonry.desandro.com/masonry.pkgd.min.js"></script> <div id="container" class='content'> <div class='item' id="box1"></div> <div class='item' id="box2"></div> <div class='item' id="box3"></div> </div> 

try it. 试试吧。 Live Demo , Demo2 现场演示DEMO2

Html HTML

<div id="container" class='content'>
    <div class='item' id="box1"></div>
    <div class='item' id="box2"></div>
    <div class='item' id="box3"></div>
</div>

css 的CSS

.content{
width:100%;;
height:100%;
display:inline-block;
}
.content div{
     border-color:black;
    border-style:solid;
    border-width:2px;
    display:inline-block;
    width:300px;
    vertical-align:top;
    float: left;
    margin: 5px;
}
#box1{
   height:50px; 
}
#box2{
   height:100px;
}
#box3{
   height:30px;
}

js js

$( function() {

    $('#container').masonry({
        itemSelector: '.item',
        columnWidth: 70
    });

});

and add 并添加

js in head 头中的js

http://masonry.desandro.com/masonry.pkgd.min.js http://masonry.desandro.com/masonry.pkgd.min.js

Your problem here is that display:inline-block turns each element in the 'row' into a block with the same height as the largest in the row. 您在这里的问题是display:inline-block将“行”中的每个元素转换为与行中最大元素具有相同高度的块。

Your best options here are to either set a max-height on #content div so that they all appear equal, or to use media queries to display a different grid depending on screen size. 最好的选择是在#content div上设置最大高度,以使它们看起来都相等,或者使用媒体查询根据屏幕尺寸显示不同的网格。

I don't really understand exactly what you are after but if you do set the column width fixed anyway you might try media queries like so (provided you float your divs): 我不太清楚您到底要做什么,但是如果您还是将列宽设置为固定的话,则可以尝试这样的媒体查询(只要您使div浮动):

@media(max-width:927px){
#content{
    width: 608px;
}
#content #box2{
    float:right;
}
}

http://jsfiddle.net/5cn6ya75/8/ http://jsfiddle.net/5cn6ya75/8/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM