This question already has an answer here:
Clearing floats dynamically with CSS
(1 answer)
Closed 8 years ago.
I am trying to create an efficient, clean layout for an e-commerce site. This site is being built in-house for my client, I am in charge only of the CSS and basic structure.
I would like to figure out the best STRUCTURAL way to clear every third box in a row. When the boxes are all the same size they float naturally in a grid, but when one of them changes size based on content (this will be common on the site) the boxes shift improperly and break the layout.
I considered/tried two options:
I can manually place a div container, with "clear" styles after every third box.
I can wrap the boxes in groups of 3, and use element:after to place a clear in this container, which would effectively clear the 3 boxes in the row.
Is one of these options better than the other? I know that the "clear" div is not preferable, but is creating a new container to wrap around the 3 boxes that much better? Either way I am still adding a new HTML element to the page.
Is there another option that I am missing? I know it's possible to do either of these options dynamically, but I want to make sure that I choose the more efficient option for this project. That is, I don't have to worry about how the code will be functionally written, I just need to figure out how the final structure will look.
I'm not experienced with this kind of layout and I don't know if there might be things that I haven't discovered yet, as for how to do this.
If I understand right, you want every third item to have clear: both;
Lets assume these items are div's. All of which are inside <div id="container"></div>.
Now, I would do the following:
#container div:nth-child(3n+1) {
clear: both;
}
You can use the :nth-child() CSS pseudo class to achieve this.
More info here: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child
Example:
div:nth-child(3n) {
clear:right;
}
Depending on the support that you need to provide, you could use the CSS3 nth-child selector.
div:nth-child(3n) {
clear: right;
}
Or something similar depending on how everything else is setup.
You can accomplish this by using the pseudo element :nth-child()
#element:nth-child(3n) {
clear:both;
}
Where n starts at 0 and goes up by one for each of that element type
Here's an overall look at :nth-child()
http://www.w3schools.com/cssref/sel_nth-child.asp
Assuming your top level wrapper has a fixed width in which you would like to fit the rows of 3 boxes each, the best solution is to put a row-container div with clear:both css styling as in the code below
<html>
<body>
<style>
#box_wrapper{
max-width:200px;
border: 2px blue solid;
}
.row_container{
clear:both;
border: 1px yellow solid;
}
.box{
width:50px;
height:50px;
float:left;
border: 1px red dotted;
}
</style>
<div id="box_wrapper" width="200" height="200">
<div class="row_container">
<div class="box" id="box_1"></div>
<div class="box" id="box_2"></div>
<div class="box" id="box_3"></div>
</div>
<div class="row_container">
<div class="box" id="box_4"></div>
<div class="box" id="box_5"></div>
<div class="box" id="box_6"></div>
</div>
<div class="row_container">
<div class="box" id="box_7"></div>
<div class="box" id="box_8"></div>
<div class="box" id="box_9"></div>
</div>
</div>
</body>
</html>
Related
I have more than 6 divs and I want to set it with float left and one after another with auto resize as per the content size using css
As per image below
here is my code:
<div class="main-container">
<div class="container">
<div class="title">test1</div>
<div class="content">Testing of css html Long Content</div>
</div>
<div class="container">
<div class="title">test2</div>
<div class="content">Testing of css html Long Content</div>
</div>
<div class="container">
<div class="title">test3</div>
<div class="content">Testing of css html Short Content</div>
</div> <!-- And so on ... -->
</div>
any help will be appriciate. Thanks
You should use JQuery plugins like wookmark or masonry for what is you expected output. Using CSS you can not fill upper space.
You can also try http://suprb.com/apps/gridalicious/ which is very good using JQuery.
From all I know, you cannot achieve that using CSS only. The following CSS solutions are possible, but each of them fails to meet all your requirements.
float: left; with clearing
This is all you can achieve using float:
For that to work, you have to clear the float every 4th element. Recommendation is to use
.container:nth-of-type(3n+1) { clear: both; }
display: flex;
What you can achieve using display: flex; is similar, but all .container in one "row" will have the same height which will be determined by the "highest" .container.
CSS columns
The only way I know of to create a type of layout like you showed is using css colums. This does have the massive drawback that your containers will be stacked first in vertical order, and only if a column is filled the next .container will be pushed to the next column. So 2 will be below 1, not right of it.
Javascript-based solutions
As mentioned in another answer, there's a load of solutions available based on Javascript.
Find the two mentioned before here:
http://masonry.desandro.com/
http://www.wookmark.com/jquery-plugin
Add this style:
<style>
.main-container{
border:solid green 1px;
width: 500px;
height:200px;
}
.container{
border:solid gray 1px;
width:50px;
height:auto;
float:left;
}
</style>
By using height /width = auto can make your div flexible to its content as per your hint
hope this help.
Okay, so this is going to be hard to explain, so please ask questions if I am not clear
In my html page, I have a main "container" div that has multiple divs within it, but each of the divs inside the container are placed into one of two columns (so if there is a div in the container, it is either in the left column or the right column)
<div id="container">
<div id="column1">
<div id="item1-1"></div>
<div id="item1-2"></div>
<div id="item1-3"></div>
</div column1>
<div id="column2">
<div id="item2-1"></div>
<div id="item2-2"></div>
<div id="item2-3"></div>
</div column2>
</div container>
[NOTE: I know the syntax is incorrect, I am just making it easier to read]
So, in other words, I want two columns of divs that can vary in size (so the page size can vary), and so that item1-2 appears below item1-1, etc. The problem here is I want the divs in the container to appear inside of it, so I cannot use absolute or relative positioning. Something is telling me I should be using a table, but I am not sure how to go about doing this.
So, my question is: using only html and css, is there any to do exactly what is above?
First: make </div column1> and </div column2> just say </div>
Second: CSS:
#container {
width: 100%;
}
#column1, #column2 {
float: left;
width: 50%;
}
To achieve the look you want you should use CSS float property. However, to avoid problems with parent container not displaying correctly, consider following one of the two possible solutions:
Adding a div after floating elements with
clear: both
or applying code below to your parent div
overflow: hidden
In my web application screens I have many areas which has the same width and different heights.
For eg. I have six divs:
<div style="height: 50px">1</div>
<div style="height:150px">2</div>
<div style="height:250px">3</div>
<div style="height:130px">4</div>
<div style="height:120px">5</div>
<div style="height: 30px">6</div>
and the css:
div{
border:1px solid red;
float:left;
width:100px;
}
browsers displays it like this:
If the browser window is changed to smaller width divs are automatically wrapped.
Wrapped divs are aligned according the top div which has maximum height. Needlessly
empty spaces appears on the screen:
Is there a way to arrange all wrapped divs to top?
Try this...
http://masonry.desandro.com//
It might be a little flashier than what you want/need. But there isn't a CSS option to fix this.
I don't know of any way to do this in CSS. The jQuery Masonry plugin should give you the ability to do this if you're not opposed to using JavaScript.
This jsfiddle example shows what I'm talking about, I gave the div in question a red border to show how it's displayed.
I'd expect the #searchwrapper_3 div to go inside the #col_st_cautare one, but for some reason that's not how it works. I've been staring at it for a while now and I got no idea why it's showing like that
I also have an example of it looking ok simply because i've added another element after the #searchwrapper div here.
Issue's fixed, TIL a div will collapse if it contains only floating elements.
You need to do a clear:both; - see the end of http://jsfiddle.net/wzYry/3/
<div style="border: 1px solid red;" id="col_st_cautare">
<div style="float: left;" id="searchwrapper_3">
.... code ....
</div>
<div style="clear:both;"></div>
</div>
On a side note, it may be easier to make clr class in your styles.
.clr{clear:both;}
This way you can use this anytime you need to clear
<div class='clr'></div>
If a div contains only floating elements, it height will collapse.
You can add a <div style="clear:both;"> or use some techniques from this article, for example overflow:hidden:
<div style="border: 1px solid red;overflow:hidden" id="col_st_cautare">
This is happening because the child elements inside are floated and parent lost track of the how to wrap them.
Probably the easiest fix for this
#col_st_cautare { overflow: hidden; }
Demo
Other than this, the stable solution would be to add <div style="clear:both;"></div> before the closing the element.
I'm working on designing up a table with 7 images in it that are all roughly the same size. Basically, I was wondering if there is a way (other then splitting each row into a different table) to change the HTML tendency to put everything in columns, and force it to lay it out based on rows.
Here is a jsfiddle of what it is. (I used Lorem Ipsum instead of the images) I would like the top and bottom row centered.
I know I can do this if I was to split it into three tables and set each one to have a width:xxxpx and margin: 0 auto, but would rather not do that.
Any suggestions are appreciated.
Why do you even bother creating multiple cells per row? Just put all your images that go in one row in the same cell, next to each other.
Yeah, it might be better to go with multiple divs for this issue. Is it possible to do something like the following:
HTML:
<div class="rows">
<div class="top">
<img></img>
<img></img>
</div>
<div class="middle">
<img></img>
<img></img>
<img></img>
</div>
<div class="bottom">
<img></img>
<img></img>
</div>
<div>
CSS:
.rows{
margin:10px;
}
.top, .bottom{
padding-left:85px;
padding-right:85px;
}
.top, .bottom, .middle
{
width:520px;
}
.rows img
{
margin: 10px;
width:150px;
}
Basically, let the normal flow of images control their positioning, and instead use margins and padding to equalize the spacing.
See the vertical-align property.