Responsive 50% 2 column html/css - html

I suspect that what I want to achieve might not be possible with plain HTML/CSS, but here goes anyway. I would like a 2 column layout which wraps nicely on mobile devices. Each column to take up 50% of the container width if there is room, but 100% of the container width if they wrap.
Here is some example markup:
<!doctype html>
<html xml:lang="en-gb" lang="en-gb" >
<head>
<title>Responsive 2 col</title>
<style type="text/css">
.colcontainer
{
width: auto;
overflow:hidden;
border: solid 1px red;
}
.leftcol
{
width: 49%;
float: left;
margin-right:10px;
border: solid 1px blue;
}
.rightcol
{
width: 49%;
float: left;
border: solid 1px green;
}
</style>
</head>
<body>
<div class="colcontainer">
<div class="leftcol">
Here is a paragraph which has enough text to cause it to take up a fair amount of width if left to its own devices.
</div>
<div class="rightcol">
A smaller paragraph.
</div>
</div>
</body>
This looks OK but when you squash the browser width to make the divs wrap, they still only take up 50% of the container width each. By removing the width:49%, it wraps nicely and fills the available width but the columns are no longer evenly split when not wrapped. Is there any way of making them fill the available width when wrapped, but take up 50% of the available width when not wrapped?

You will need multiple things here, first of all you are making a responsive grid, so whenever you make responsive things, make sure you use the CSS snippet below
* {
margin: 0;
padding: 0;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
This will change the box model behavior and will count the padding and border inside the box instead of outside..
Secondly, if you want to wrap the elements, you can declare break points using #media queries, this way they won't be squished.
Demo (Resize the window and see the effect)

Related

CSS column layout - DIV with dynamic width and same height as sibling

I've really hit the wall on this one and need some help. I'm trying to create a two column layout with both widths and heights adjusted to the contents of the left column. It seems to be a rather basic layout, but I'm starting to think it can't be done (without resorting to JS).
This fiddle describes what I'm trying to do. It's a container DIV with two DIVs inside, aligned horizontally. The left inner DIV should adjust its size (both width and height) to its content. The right inner DIV (which contains a Google Map) should have the same height as the left one while filling up the remaining width of the container.
<div id="container">
<div id="left">
This DIV should adjust<br/>
both its width and height<br/>
to its content, not taking up<br/>
more space than needed!<br/>
<br/><br/><br/>
More content here...
</div>
<div id="right">
Google Map here.
</div>
</div>
I've tried everything I know and all tricks I've found, but no success!
#container {
background-color: #EEE;
overflow: hidden;
}
#container div {
border: 1px solid black;
padding: 5px;
}
#left {
background-color: lightblue;
display: inline-block;
float: left;
}
#right {
background-color: lightgreen;
height: 100%; /* THIS IS WHAT I WANT, BUT IT WON'T WORK, OF COURSE */
overflow: hidden;
}
I've found many similar questions, but in all those cases the left DIV/column had a fixed width, which makes it a whole lot easier.
Any input is much appreciated, especially if it works in IE9+ (and modern browsers)!
Edit
Some clarification. The purpose of the right column is to hold a Google map and consequently the map is supposed to fill up the entire DIV. Try setting a fixed height (e.g. 100px) for #right in the fiddle that I link to above and you will see the map showing up.
jsfiddle demo
css :
.container {
overflow: hidden;
background-color: #EEE;
}
.column {
float: left;
background-color: grey;
padding-bottom: 1000px;
margin-bottom: -1000px;
}
p {
padding: 10px;
margin-top: 10px;
width: 50%;
}
html
<script src="//maps.googleapis.com/maps/api/js?sensor=false"></script>
<div class="container">
<div class="column">
This DIV should adjust<br/>
both its width and height<br/>
to its content, not taking up<br/>
more space than needed!<br/>
<br/><br/><br/>
More content here...
</div>
<div class="column">
<div id="map"></div>
</div>
</div>
<p>
The right DIV (which contains a Google Map)
should be the same height as the left DIV,
while filling up the remaining width.
</p>
<p>How to do that?</p>
Here what I came up with -> link
When you remove the overflow property of your #right div it stretches as expected. However in this case you won't be able to hide the overflowed content.
CSS
#right {
background-color: lightgreen;
height: 100%; /* THIS WON'T WORK */ // height works as expected
}

Why is this div dropping down to the next line on window zoom out?

JSFIDDLE
I have a wrapper with 4 divs inside it that are all floated to the left and are in one line. When I zoom out, the 4th div drops to the bottom. The only possible problem I can think of is the width of the wrapper decreasing, thus causing it to not be able to contain the 4th one, but the wrapper has a fixed width so I'm sure thats not the problem.
Here's the html:
<div id="wrapper">
<div id="panel">
<div id="panel1" class="panelcell"></div>
<div id="panel2" class="panelcell"></div>
<div id="panel3" class="panelcell"></div>
<div id="panel4" class="panelcell"></div>
<div class="spacer" style="clear: both;"></div>
</div>
</div>
and here's the css:
#wrapper{
width: 1280px;
}
#panel{
width:100%;
}
#panel .panelcell{
width: 318.75px;
height: 213px;
float: left;
border-right: 1px solid white;
}
.panelcell {
background-color: gray;
}
#panel1{
border-right: 1px solid white;
}
I think the root of the problem is how the browser renders your widths of "318.75px" as you zoom out (since, well, you can't render 0.75px to the screen). Depending on how it's rounded as the elements scale with your zooming out, the elements' widths could end up adding to larger than that of the parent element, resulting in the last floated element being pushed to a new line.
The way (that I could think of) to solve this is using percentage widths, rather than decimal pixel widths. Changing your definition of #panel .panelcell to this should give you what you're looking for:
#panel .panelcell{
width: 25%;
height: 213px;
float: left;
border-right: 1px solid white;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
The box-sizing: border-box ensures that the 1px border is also taken into account when determining the 25% width of the element. Here's an updated JSFiddle to show what this achieves. (The fourth element should not break to a new line as you zoom out.) If this isn't what you were looking for, let me know and I'll be happy to help further!
Did not test it, but I think your guess about the wrapper not being able to contain the <div>'s is correct: 4*(318,75px+2px) = 1283px > 1280 px.
Just increase the width of your wrapper and it should be fine.
It seems to be a problem with your border-right 1px solid which is increasing the width over 1280

What is the modern way of vertically centering a form inside a floated div of a varying height without using javascript?

What I'm trying to do:
Vertically center the form in the left div. The height of that div should be dependent on the height of the right div which can change depending on the text contained therein.
What I want:
A modern solution that doesn't resort to using JavaScript. There are many JavaScript-free approaches but as soon as you factor in floated divs and dynamic heights that list dramatically shrinks. I haven't found a working solution yet, yet alone a modern one.
Here's the jsfiddle (but I suggest using the raw code):
pshpV
Here's the raw code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style type="text/css">
body
{
margin: 10px;
padding: 10px;
background: #293134;
color: #E0E2E4;
border: 1px solid #93C763;
}
#container
{
overflow: hidden;
width: 800px;
margin: 0 auto;
padding: 10px;
border: 1px solid #678CB1;
}
#left
{
float: left;
width: 568px;
padding: 10px;
border: 1px solid #FFCD22;
}
#right
{
float: left;
width: 200px;
margin-left: 10px;
padding: 10px;
border: 1px solid #EC7600;
}
#container, #left, #right
{
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
</style>
</head>
<body>
<div id="container">
<div id="left">
<form>
<input type="text" name="keyword" required placeholder="keyword" />
<input type="submit" value="search" />
</form>
</div>
<div id="right">
<h1>foo</h1>
<h2>bar</h2>
<h3>baz</h3>
</div>
</div>
</body>
</html>
Hindsights:
As far as I know, the only way the table approach works is by removing the floats. It also appears that I apparently don't even need the floats. Regardless, I would still like to discover the answer my question.
Not quite sure exactly how you want everything but you could try fiddling about with the display:table / table-cell and then vertical-align. However, IE has issues with these properties. <= IE7 I think
Edit: I would go out on a limb here and say that what your asking is impossible. The trouble comes from the two requirements you are asking for combined - floating and dynamic heights.Floating an element means that the parent element won't recognize its height, even if you float the parent element as well, it will stretch to the height of floating children but still won't have a recognized height. Therefore, trying center-aligning tactics like positioning relatively with top:50% won't work because the height is not recognized.In all cases, the actual height of your elements in question will never be recognized because they are floating. You would have to specify heights to parent elements to get around that problem and this won't work in your case because that is another requirement of yours - dynamic heights.

What CSS properties govern how a webpage reacts to window resizing?

I just wonder because I know that my page goes haywire if you try to make it too small. Facebook, StackOverflow and almost any other well programmed site calmly adjusts the page format until they run out of 'breathing room' at which point the page is just 'eaten' by the browser's borders. How do these well programmed sites format themselves so nicely as to cope with window resizing? Are there CSS properties specifically made to help with this?
You can center your site by using a main "wrapper" div.
<div id="wrapper">
//all you content here
</div>
Then in you css your set the "wrapper" as follows
#wrapper{
width:900px //or whatever
margin: 0 auto; }
This gives it a width and a flexible margin. When the window is resized too small, it just "eats" it, as you say.
The key here is a flexible layout, either make the margin flexible (as I outlined above) or make the content flexible.
Another way to do this is to make almost everything flexible, something like this..
#wrapper{
border:1px solid red;
width:50%;
min-width:300px;
margin:0 25%;
height:50px; //for display only
}
http://jsfiddle.net/jasongennaro/6FCjZ/1/
You should look into "Fluid" CSS designs. These are CSS rules that are designed to manage a pages width.
A common way of doing this is to use max-width and min-width to manage the over all width of the website.
For example:
Click here to see a live example.
<html>
<head>
<title>Width Test</title>
<style>
#main-content {
background-color: #EEF;
border: 1px solid #003;
max-width: 45em;
min-width: 20em;
padding: 1em;
margin: 0 auto; /* center */
}
.box {
border: 1px solid #000;
background: #363;
color: #fff;
padding: .25em;
}
.left {
float: left;
margin: .5em 1em .5em 0;
}
.right {
float: right;
margin: .5em 0 .5em 1em;
}
</style>
</head>
<body>
<div id="main-content">
<p>Resize Me...</p>
<span class="box left">left</span>
<span class="box right">right</span>
<p>Fluid Layout</p>
</div>
</body>
</html>
The key element here is the styling on #main-content. The rest of that is so you can see it in action.
Both those websites are a fixed width but with expanding header backgrounds. There's nothing special going on.
The header (blue/grey bar) has a 100% width with a fixed width container inside that is centered.
Defining a width of pixels to a div usually gives it a fixed layout, while using percentage gives a fluid layout.
For kicks, check out the 960.gs, which uses a fixed layout, and is great for avoiding cross-browser issues:
http://960.gs/
There's also the fluid version of the 960.gs:
http://www.designinfluences.com/fluid960gs/

How to make a stable two column layout in HTML/CSS

I want a container with two columns. Details:
The container
Width should adjust to 100% of its parent element (easily accomplished).
Height must adjust to contain both columns (i.e. its height should be exactly equal to the larger height of the two columns, so there is no overflow and scrollbars never show)
Should have a minimum size equal to double the width of the left column.
The columns in general
Should be of variable height, adjusting to the height of their content.
Should be side-by-side, such that their top edges are in line.
Should not break the layout or wrap under each other if even a single pixel of border, padding, or margin is applied to either one, because that would be extremely unstable and unfortunate.
The left column specifically
Must have a fixed, absolute width in pixel units.
The right column specifically
Width must fill the remaining space in the container. In other words...
Width must equal the container width minus the width of the left column, such that if I place a DIV block element inside this column, set its width to 100%, give it a height of something like 10px, and give it a background color, I will see a 10px high colored strip that goes from the right edge of the left column to the right edge of the container (i.e. it fills the right column's width).
Required stability
The container should be able to resize (by resizing the browser window) down to its minimum width (specified earlier) or to a much larger width without breaking the layout. "Breaking" would include the left column changing size at all (remember it's supposed to have a fixed pixel width), the right column wrapping under the left one, scrollbars appearing, block elements in the right column failing to take up the entire column width, and in general any of the aforementioned specifications failing to remain true.
Background
If floating elements are used, there should be no chance that the right column will wrap under the left one, that the container will fail to contain both columns (by clipping any part of the column or allowing any part of the columns to overflow its boundary), or that scrollbars will appear (so I'd be weary of suggesting the use of anything other than overflow:hidden to trigger floating-element containment). Applying borders to the columns should not break the layout. The content of the columns, especially of the right column, should not break the layout.
There seems to be a simple table-based solution to this, but under every circumstance it fails miserably. For example, in Safari, my fixed-width left column will shrink if the container gets too small, rather than maintaining the width I specified. It also seems to be the case that CSS width, when applied to a TD element refers to a minimum width, such that if something larger is placed inside it, it will expand. I've tried using table-layout:fixed; doesn't help. I've also seen the case where the TD element representing the right column will not expand to fill the remaining area, or it will appear to (for example a third column 1px wide will be pushed all the way to the right side), but putting a border around the right column will show that it's only as wide as its inline content, and block-level elements with their width set to 100% do not fill the width of the column, but rather match the width of the inline-content (i.e. the width of the TD seems to be completely dependent on the content).
One potential solution I have seen is too complex; the solution needs to work in IE8, Firefox 4, and Safari 5.
Here you go:
<html>
<head>
<title>Cols</title>
<style>
#left {
width: 200px;
float: left;
}
#right {
margin-left: 200px;
/* Change this to whatever the width of your left column is*/
}
.clear {
clear: both;
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
<div class="clear"></div>
</div>
</body>
</html>
See it in action here: http://jsfiddle.net/FVLMX/
Try this: Live Demo
display: table is surprisingly good. Once you don't care about IE7, you're free to use it. It doesn't really have any of the usual downsides of <table>.
CSS:
#container {
background: #ccc;
display: table
}
#left, #right {
display: table-cell
}
#left {
width: 150px;
background: #f0f;
border: 5px dotted blue;
}
#right {
background: #aaa;
border: 3px solid #000
}
Piece of cake.
Use 960Grids Go to the automatic layout builder and make a two column, fluid design. Build a left column to the width of grids that works....this is the only challenge using grids and it's very easy once you read a tutorial. In a nutshell, each column in a grid is a certain width, and you set the amount of columns you want to use. To get a column that's exactly a certain width, you have to adjust your math so that your column width is exact. Not too tough.
No chance of wrapping because others have already fought that battle for you. Compatibility back as far as you likely will ever need to go. Quick and easy....Now, download, customize and deploy.
Voila. Grids FTW.
Over 11 years later. Apply display:grid to the container and divide the available space by grid-template-columns: 100px 1fr. Where 1fr represents a fraction of 100% of the remaining space.
<html>
<head>
<title>Cols</title>
<style>
#container {
display: grid;
grid-template-columns: 100px 1fr;
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
</div>
</body>
</html>
As suggested by mtmurdock it is possible to remove the .clear rule and move it to the pseudo-element #container::after.
<html>
<head>
<title>Cols</title>
<style>
#left {
width: 200px;
float: left;
}
#right {
margin-left: 200px;
/* Change this to whatever the width of your left column is*/
}
#container::after {
clear : left;
display: block;
content: '';
}
</style>
</head>
<body>
<div id="container">
<div id="left">
Hello
</div>
<div id="right">
<div style="background-color: red; height: 10px;">Hello</div>
</div>
</div>
</body>
</html>
Another idea is to include the left div in the right div,
which in turn coincides with the line container:
[right][left] ... [/left] ..... [/right]
x { border: thick solid navy; padding: 2px; }
.lineContainer, .container > p {
padding-left: 100px;
margin: 0;
line-height: 1.5;
}
.left, em {
margin-left: -100px;
display:inline-block; box-sizing: border-box; width: 100px;
vertical-align: top;
}
.div-in-div {
display:inline-block; box-sizing: border-box; width: 100%;
vertical-align: top;
}
<h3>Layout: div-left is contained within the right-div / lineContainer</h3>
<pre>
[right][left] … [/left] … [/right]
</pre>
<div class="lineContainer" style="background:floralwhite; "><div class="left">Hello</div>Hello there</div>
<p>Using the above scheme,
we can make old-fashioned typewriter tab stops as shown here.</p>
<h3>The Capital Cities of the UK</h3>
<div class="container" style="background-color: floralwhite; ">
<p><em>England</em> - The capital is London.</p>
<p><em>Scotland</em> - The capital is Edinburgh.</p>
<p><em>Wales</em> - The capital is Cardiff.</p>
<p><em>Northern Ireland</em> - The capital is Belfast.</p>
<p><em>The capital of the UK is</em> - London.</p>
<p><em>Source</em>- Project Britain, capitals.</p>
</div>
<h3>Div in div</h3>
<div class="lineContainer" style="background:floralwhite; ">
<div class="left">Div in container</div><!--No white space here
--><p class="div-in-div" style="background: red; font-size: x-large; margin: auto 0; ">Hello there</p>
</div>