How do you align dynamically generated divs to right and left side of the parent without losing the margin between them? - css

Lets say I have a website where, on every page, there is a large picture of a kitten. This picture is exactly the same on every page. Below it are smaller divs, containing pictures of related kittens, which are dynamically generated... the number also varies, on some pages there may be five, on others there could be 30. I've drawn a crude picture of the layout here:
Here's what I'm looking to do... I need to:
Make sure the smaller pictures both align left and align right with the larger picture above it.
Give the divs a small percentage of space between each other.
Allow the divs to stack when the screen gets smaller.
When aligning smaller divs in a row with a larger one above it, my usual approach is to do something like this:
.little_divs {
margin-left:2%;
}
.little_divs:first-child {
margin-left: 0px;
}
That would easily allow me to have both the left and right sides match up with the div above it. My problem is that this technique will not work for the next rows, if there are more than three.
My next idea was to contain each group of three in their own div, and apply the first child rule there... however, that brings up a problem of when it collapses down to the smaller screen sizes. If I group them in three and apply the rule, once they are two across, it will no longer work.
I could make a complicated solution involving JavaScript, but I was hoping for a pure CSS/HTML solution.
Let me know if you have any questions on this.

You can change .little_divs:first-child to ...
.little_divs:nth-child(3n+1) {
margin-left: 0px;
}
... or ...
.little_divs:nth-of-type(3n+1) {
margin-left: 0px;
}
... to select the first item on each row where there are 3 items on each row. Adjust the count for the amount of columns e.g. 4n+1 for 4 columns, etc.
This takes every 3rd natural number and offsets it by 1 (next item) which matches 1, 4, 7, etc.
Edit:
If you want this to work with a different amount of columns, you'll need to add the selectors inside mediaqueries as follows:
#media only screen and (min-width:1025px){
.little_divs:nth-child(3n+1) {
margin-left: 0px;
}
}
#media only screen and (max-width:1024px){
.little_divs:nth-child(2n+1) {
margin-left: 0px;
}
}
... or similar for each break point.

My preferred method is to add a container to the small ones, and make the width of that the width of the container plus the width of one of your margins, and give it a negative margin.
.container {
margin: 0 auto;
width: 300px;
}
.main {
background: #0f0;
height: 100px;
width: 300px;
}
.small-container {
margin-left: -15px;
width: 315px;
}
.small {
background: #f0f;
float: left;
height: 100px;
margin-left: 15px;
margin-top: 15px;
width: 90px;
}
<div class="container">
<div class="main"></div>
<div class="small-container">
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
</div>
</div>
With this, it lines up and you don't have to mess with first-child at all or anything.

Related

How to create an easy responsive grid with one column and two boxes?

I want to create a CSS grid (without using any external library) where I have two columns. The first column contains one box. The second column contains two boxes.
The box in the first/left column shall have the height of the two boxes (respecting margin bottom accordingly). Have a look at the following graphic - the red box represents the unwanted behaviour, the green the wanted one.
First of all: Is this possible without using any JavaScript (like calculating the sum of the two right boxes and dynamically setting height of left box)?
And if yes, how can I most effectively realize this using CSS? And how can I assure that this also works on mobile devices like tablets and smartphones? I want to avoid using a table.
I always get confused with position, display and float when trying to achieve this. But this is what I have tried so far but the problem is that I set the height of the left box statically.
The display: inline-block; width: 40%; min-width: 420px is my try to keep it responsive.
CSS
.box-layout {
display: inline-block;
width: 40%;
float: left;
outline: 1px solid #C3C3C3;
padding: 10px 20px;
margin: 0 10px;
background-color: #FAFAFA;
min-width: 420px;
}
.left-box {
min-height: 440px;
}
HTML
<div class="box-layout left-box">
<h1>Left large box</h1>
</div>
<div class="box-layout right-box right-box-first">
<h1>Right first box</h1>
</div>
<div class="box-layout right-box right-box-second">
<h1>Right second box</h1>
</div>
Here is a jsFiddle.
If you want to achieve this with only using CSS, I'd recommend to use a parent container
.container{
width:1024px;
margin:0 auto;
height:440px;
}
Here is a sample JSFiddle
At this point, you need to decide the height of these boxes. And if you want height dynamic, as far as I know you should use JS, like this;
$(document).ready(function(){
var height = $(window).height();
var leftBoxHeight = height;
var rightBoxHeight = height / 2 - 20;
$('.left-box').css('height', leftBoxHeight + 'px');
$('.right-box').css('height', rightBoxHeight + 'px');
});
And here is my second JSFiddle
Hope this helps.

How do I make two columns--one flexible--that wrap when necessary?

I need two columns, basically blocks side-by-side, that wrap when necessary for a responsive design.
The issue that I'm running into is that the first column/block is statically sized, but the second column/block needs to fill the remaining width. However, they should still wrap when necessary.
Say the left-most block has a static width of 200px, while the right-most fills the remaining width, BUT with a min-width of 300px. That way it should wrap (the second block placed below the first block instead of on the right side) when necessary.
I've tried a variety of methods to no avail--floating the left block, using absolute position, etc., but I can't get the results I'm looking for.
Hopefully it's possibly using CSS alone, and not using a CSS3 media query to show/hide two different versions. Or resorting to JS... :P
Did you want something like this
HTML
<div class="outer">
<div class="leftBar">Test</div>
<div class="rightCnt"></div>
</div>
CSS
* {margin: 0}
.leftBar {
width: 200px;
min-height: 600px;
float: left;
background: red;
}
.rightCnt {
margin-left: 200px;
min-height: 600px;
background: yellow;
}
#media (max-width : 500px) {
.leftBar {
float: none;
width: auto;
min-height: 200px;
}
.rightCnt {
margin-left: 0;
}
}

3-Column Layout -- Without Columns

How do you code a three-column layout in CSS when the source order jumps around from column to column?
The page has seven sections -- this fiddle shows how the required source order compares to the layout. The number is for its position in the source order and the text is where it should appear on the page.
http://jsfiddle.net/hpr2b/4/
As you can see, there are essentially three columns and three rows, but the elements in the second row shouldn't top-align and the second row shouldn't clear the first row. Each section should be flush with the bottom of the section that is located above it.
Notes:
The source order matches the order that the elements need to appear on mobile devices and unfortunately cannot be changed
I also don't have the option of duplicating sections in the markup and then showing/hiding them based on viewport width
Absolute positioning is unfortunately not an option because the layout must adapt to any viewport width 320px and up
I've tried a number of well-known CSS layout techniques and the above fiddle shows the most successful attempt -- here is the code used for the "top row":
.top-center {
float: left;
width: 55%;
margin-left: 25%;
}
.top-left {
float: left;
width: 25%;
margin-left: -80%;
}
.top-right {
float: right;
width: 20%;
}
Here are the problems I'm encountering:
IE 9/10 is a complete mess (see below)
In Chrome, the "Middle Right" div always clears the "Top Left" div, preventing it from being positioned beneath "Top Right". Also, if the "Top Right" div becomes too tall, it overlaps "Middle Right".
In Firefox, the second "row" top aligns, overlapping the left and right sections of the first row.
Here is what it looks like in IE10:
And here it is in Firefox:
If the positioning is that important and you cannot control the (order of the) HTML code (I assume so from reading your question), I would rather go for having a somewhat usable absolute positioning using CSS, and refine it (onDomReady) using javascript (which gives you a lot more freedom to choose the best algorithm for the layout you need, but still a usable yet not perfect layout for those few anti-javascript-guys out there).
However, it is hard to tell without seeing the actual markup and requirements.
If absolute positioning is absolutely not an option, you'll need to calculate the height of elements prior to the page generating and put each block into the correct column based on heights. Trust me, absolute positioning is much easier!
You'll probably want something like Masonry. It sets up the columns for you as you require. It does rely on absolute positioning, but that's just about your only easy option. You'll need to tinker with the code a little to make it responsive, I did it on an in-development site here but I can't entirely remember what I did, sorry. Feel free to look through the source code though.
Masonry is pretty quick; below is the basic setup, here are more details.
HTML
<div id="container">
<div class="item">...</div>
<div class="item w2">...</div>
<div class="item">...</div>
...
</div>
JavaScript
var container = document.querySelector('#container');
var msnry = new Masonry( container, {
// options
columnWidth: 200,
itemSelector: '.item'
});
I managed to make the following layout with CSS only: http://jsfiddle.net/hpr2b/7/
.top-center {
width: 55%;
float: left;
margin: 10px 0 10px 25%;
}
.top-left {
float: right;
width: 25%;
margin: 10px 75% 40px -100%;
}
.top-right {
float: right;
width: 20%;
margin: 10px 0 40px 0;
}
.mid-center {
margin: 10px 20% 10px 25%;
clear: left;
}
.mid-left {
float: left;
clear: right;
width: 25%;
margin-top: -20px;
}
.mid-right {
float: right;
clear: right;
width: 20%;
margin-top: -20px;
}
.bottom-center {
margin: 0 20% 10px 25%;
}

Positioning two elements beside each other, floating will make img disappear

I'm new to design and I need to place the two imgs beside each other, with some space between.
This is what currently my site looks: Dont worry about the cut off, it is suppose to be like that. I need to prepare this to allow me to later on add responsive elements on to it so I cannot use absolute positions or anything that will lock the image into place.
Both Images are the same height at 125 px. When I float both the pictures left or right, the pictures appear 95% cut off at the edges of my webpage. I dont understand why it's being place underneath each other, there seems to be plenty of room for the second image to be on the same level.
Heres what I have so far: "navi" is my container or wrapper... mainlogo and slidertop i used to experiment and currently have no code under each.
<div id="navi">
<div id="mainlogo"><header></header></div>
<div id="slidertop"><header id="topad"></header></div>
<div style="clear:both"></div>
</div>
#navi{
height: 130px;
}
#mainlogo{
}
#slidertop{
}
This is how Im calling my images:
header{
background: url(../Images/logo1.gif) no-repeat 15% 0px;
border: none;
height: 125px;
top:100px;
}
header#topad{
background: url(../Images/TopAd.gif) no-repeat 80% 0px;
border: none;
height: 125px;
vertical-align: middle;
}
In the original code you posted, I think the divs are all 100% of the available width, and they will appear on top of each other on the page. You can see this for yourself if you temporarily add a coloured border around each div so you can see where they are.
If you want them side by side, you have to add styles to accomplish this. For example, you could float them and specify the widths:
header { width: 45%; float: left; }
header#topad { float: right;}
E.g.: http://codepen.io/anon/pen/ynuoa
Have you tried floating the divs?
#mainlogo{
float: left;
}
#slidertop{
float: left;
}

2 Side by side DIVs (1line) stretching to right

I'm trying to build the liquid layout shown below in CSS.
The left column should stretch to all available space, and if it's possible, on same line.The column on right should became with the same width.
I have already achieved a result very close to what I want. Take a look at http://jsfiddle.net/tcWCC/34/embedded/result/
But there are two problems. The height of both aligned DIVs should be equal. The first or second DIV should grow to be the same height as the other.
The second question is that when the width is not sufficient for 2 DIVs, I want the first (NomeEvento) div to be on top. and not the second div (DataEvento).
I am not sure I understood your question correctly. Is the following layout something similar to what you want? http://jsfiddle.net/5sjgf/
Here's more CSS to try out. If you wanted a margin on that left side. I added background colors to help differentiate.
div.NomeEvento {
text-align: left;
float: left;
width: 75%;
background-color: #eee;
}
div.DataEvento {
text-align: left;
margin-left: 5%;
width: 20%;
float:left;
background-color: #ccc;
}
It seems like a lot of extraneous CSS to me. But maybe the other stuff is in there for a reason. This works fine as the sum-total of your CSS though:
div.Evento {
overflow: hidden;
margin-top: 10px;
}
div.NomeEvento {
background: #eee;
padding-right: 20%; /* the same as the right column width */
}
div.DataEvento {
float:right;
background: #ddd;
}
...BUT, if you're right-floating an element, place it first in the layout - here it's element class DataEvento:
<div class="Evento">
<div class="DataEvento">#evento.Data</div>
<div class="NomeEvento">#evento.Nome</div>
</div>​
Check it: http://jsfiddle.net/J89Hp/
Cheers
I acomplished what I want using display table, table row and table cell in my divs.
Take a look. It's exactily what I want.
http://jsfiddle.net/tcWCC/47/embedded/result/

Resources