Fixed width but variable background with CSS3 - html

Sometimes, I need to restrict section of a page to a fixed width. But the background should extend all the available space.
With CSS2 I used to do something like this (jsfiddle: http://jsfiddle.net/fniwes/wwVp4/)
css:
#container { background-color: #ddd; }
#content { width: 300px; margin: 0 auto; }
html:
<div id="container">
<div id="content">All the content inside container should be limited to 300px but the background should cover all the screen width</div>
</div>
The content here is just a plain text, but it is usually something more complex.
Is there a better way to accomplish the same result without the extra #content tag? I don't mind using CSS3 or something that is only supported by Chrome or Firefox.
Just for clarification. I want to remove #content tag. I want the markup to be
<div id="container">
All the content bla bla
</div>
(and I want to style no tag other than #container.. maybe it is not possible, but maybe there is something new in CSS3 or other proposal that I don't know)

There is the calc() function in css3, you can use that like this:
#container { background-color: #ddd; padding-left: calc(50% - 150px); padding-right:calc(50% - 150px);}

is there any specific reason you are against using a container div? You could do:
#content { background-color: #ddd; width: 100%; margin: 0; padding: 0 50%; }
But I wouldn't reccomend it and the best solution is still to use containers

Related

Percent vs. pixels in fluid layout

I would like to build a fluid layout and would like to achieve something like
width:100%-200px;
i.e. have a div with content, call it div id="content" with a fixed margin on either side. I have tried to use the trick of putting the div id="content" into another div container with a margin, but I don't know how to fill out the background of div id="content". Is there a way of telling the div id="content" to use 100% of the available space as background, such that the width of the content plus the width of the margin does not exceed 100% of the browser window size?
Having the DIV set to be 100% with a margin of XXX on either side won't work as that will exceed the size of the browser window.
You could try the following:
body {
padding:0 2%;
}
#content {
width:96%;
}
http://jsfiddle.net/YYhvT/
Use position absolute...
#content {
position: absolute;
left: 0;
right: 200px;
}
See my Fiddle.
PS Advantage is that you don't need values on other elements.
You can put a container around the content and give it 200px left/right padding. This should do the trick (at least, from what I understand of what you are trying to accomplish). Also see this code example:
<!doctype html>
<html>
<head>
<style type="text/css">
body { margin: 0 50px; }
#container { padding: 0 200px; background: #FF0000; }
#content { width: 100%; background: #00FF00; }
</style>
</head>
<body>
<div id="container">
<div id="content">
Here goes my content
</div>
</div>
</body>
</html>
Note that the body margin is just for illustrating purposes, to let you see the background differences.
(I would post a jsFiddle, however I am not able to use it since I can only use IE7 at this point.)
here is my solution,
html:
<div id="content" class="content">
My Content
</div>​
css:
.content {
position: absolute;
right: 100px;
left: 100px;
background-color:#A5112C;
}​
and link to it: http://jsfiddle.net/MPYHs/
also if you want to put sort of image as a background I suggest you use small pattern like https://ssl.gstatic.com/android/market_images/web/background_stripes.gif
hope it helps,
regards

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 size a div's height to its container height, using CSS?

How to size a div's height to its container height, using CSS ?
<div class='container'><br>
<div style='display: block; height: 500px'>left</div><br>
<div id='to-be-sized' >right</div><br>
</div>
You can either:
use the incomplete but philosophically correct path of pure CSS and face every kind of incompatibility between browsers
or
write 3 lines of dirty semantically incorrect and devil made table and have it work perfectly everywhere
Your pick :)
There's a way to do this IF you happen to be using jQuery. As you asked for CSS this might not be an option available to you, but if you can utilise it it will do exactly what you want.
$(divToResize).css('height',$(container).innerHeight());
$(divToResize) is the selector for the DIV you wish to match the height of it's container and $(container) is logically the container whose height you want to get.
This will work regardless of if the container's height is specified in CSS or not.
I know this was answered forever ago, but when I run into this issue nowadays, I use Flex Box. It's awesome. See A Complete Guide to Flexbox by Chris Coyier
.parent {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
width: 100%;
}
.child {
flex-grow: 1;
}
.child1 {
min-height: 200px;
background-color: #fee;
}
.child2 {
background-color:#eef;
}
<div class="parent">
<div class="child child1">Child 1</div>
<div class="child child2">Child 2</div>
</div>
The Flexbox Layout (Flexible Box) module aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word "flex").
The main idea behind the flex layout is to give the container the ability to alter its items' width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.
Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).
If my understanding is correct and the default height of a div where no height is specified is auto then this is not possible without setting an explicit height on the containing div. If an explicit height is set on the containing div then height:100% on the contained div will mean that it grows to the height of the container.
It seems like you are trying to get equal height columns. You could use the fauxcolumns method where a background image is used to fake the equal height. There are other methods out there.
You can tell the container div to display as table and have the inner div to display as a table cell.
The HTML
<body>
<div id="wrap">
<div id="header">
<h1>
My Header</h1>
</div>
<div id="main">
<ul id="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div id="primaryContent">
</div>
</div>
<div id="footer">
<h1>
My Footer</h1>
</div>
</div>
The CSS
#wrap
{
width: 800px;
margin: auto;
}
#header
{
background: red;
}
#main
{
display: table;
}
#nav
{
background: gray;
width: 150px;
display: table-cell;
}
#primaryContent
{
background: yellow;
padding: 0 .5em;
display: table-cell;
}
Fixes for IE
#wrap
{
width: 800px;
margin: auto;
}
#header, #footer
{
background: red;
}
#main
{
background: url(../bg.png) repeat-y;
}
#nav
{
background: gray;
width: 150px;
float: left;
}
#primaryContent
{
background: yellow;
margin-left: 150px;
padding: 0 .5em;
}
It's a tricky thing to do--there's no clear-cut best approach, but there are a few common ones.
If we assume that what you REALLY need is for the height of the right column to be (or appear to be) equivalent to the height of the left column, you can use any of the techniques frequently used to get equal height columns. This piece contains a few tricks to get the right look and behavior. I recommend reading it to see if it solves your problem.
The other approach uses Javascript to determine the height of the container, and setting your right-hand column to that. That technique has been discussed on SO here. As long as your container's size is not the only thing determining the size of your outer container, that should be a valid approach (if that's not the case, you'll have a chicken-egg problem that could cause weird behavior).
Sample code, you need to start from the html element so you can make use of the flexible height in the containers.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>100% Test</title>
<style type="text/css">
html, body, #inner { height: 100% }
#inner { border: 4px blue solid }
#container { height: 200px; border: 4px red solid }
</style>
</head>
<body>
<div id="container">
<div id="inner">
lorem ipsum
</div>
</div>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<style type="text/css">
.container{
position:relative;
background-color:#999;
}
#to-be-sized{
position:absolute;
top:0;
height:100%;
background-color:#ddd;
}
</style>
<body>
<div class='container'>
<br>
<div style='display: block; height: 500px'>left</div>
<br>
<div id='to-be-sized' >right</div><br>
</div>
</body>
</html>
CSS files use the 'padding' function to determine the height and depth of containers. To change the height of the container field simple insert of adjust the padding fields for the specified containers.
The code excerpt below is an example of the CSS used for a container class (you'd find this as in the html file.
.container{padding-top:100px;padding-bottom:50px}header
i use the overflow:hidden it work properly.
.bu {
overflow: hidden;
background-color:blue;
}
<div class="bu">
<button>english</button>
</div>
try adding this to the div to be resized
.layout-fill {
margin: 0;
width: 100%;
min-height: 100%;
height: 100%;
}
I did something similar to KyokoHunter:
$('div.row').each(function(){
var rowHeight = $(this).innerHeight();
$(this).children('div.column').css('height',rowHeight);
});
This goes through every row in a div "table" and makes the heights all match, as long as the divs are classed accordingly.

CSS two divs next to each other

I want to put two <div>s next to each other. The right <div> is about 200px; and the left <div> must fill up the rest of the screen width? How can I do this?
You can use flexbox to lay out your items:
#parent {
display: flex;
}
#narrow {
width: 200px;
background: lightblue;
/* Just so it's visible */
}
#wide {
flex: 1;
/* Grow to rest of container */
background: lightgreen;
/* Just so it's visible */
}
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
This is basically just scraping the surface of flexbox. Flexbox can do pretty amazing things.
For older browser support, you can use CSS float and a width properties to solve it.
#narrow {
float: right;
width: 200px;
background: lightblue;
}
#wide {
float: left;
width: calc(100% - 200px);
background: lightgreen;
}
<div id="parent">
<div id="wide">Wide (rest of width)</div>
<div id="narrow">Narrow (200px)</div>
</div>
I don't know if this is still a current issue or not but I just encountered the same problem and used the CSS display: inline-block; tag.
Wrapping these in a div so that they can be positioned appropriately.
<div>
<div style="display: inline-block;">Content1</div>
<div style="display: inline-block;">Content2</div>
</div>
Note that the use of the inline style attribute was only used for the succinctness of this example of course these used be moved to an external CSS file.
Unfortunately, this is not a trivial thing to solve for the general case. The easiest thing would be to add a css-style property "float: right;" to your 200px div, however, this would also cause your "main"-div to actually be full width and any text in there would float around the edge of the 200px-div, which often looks weird, depending on the content (pretty much in all cases except if it's a floating image).
EDIT:
As suggested by Dom, the wrapping problem could of course be solved with a margin. Silly me.
The method suggested by #roe and #MohitNanda work, but if the right div is set as float:right;, then it must come first in the HTML source. This breaks the left-to-right read order, which could be confusing if the page is displayed with styles turned off. If that's the case, it might be better to use a wrapper div and absolute positioning:
<div id="wrap" style="position:relative;">
<div id="left" style="margin-right:201px;border:1px solid red;">left</div>
<div id="right" style="position:absolute;width:200px;right:0;top:0;border:1px solid blue;">right</div>
</div>
Demonstrated:
left
right
Edit: Hmm, interesting. The preview window shows the correctly formatted divs, but the rendered post item does not. Sorry then, you'll have to try it for yourself.
I ran into this problem today. Based on the solutions above, this worked for me:
<div style="width:100%;">
<div style="float:left;">Content left div</div>
<div style="float:right;">Content right div</div>
</div>
Simply make the parent div span the full width and float the divs contained within.
UPDATE
If you need to place elements in a row, you can use Flex Layout. Here you have another Flex tutorial. It's a great CSS tool and even though it is not 100% compatible, each day its support is getting better. This works as simple as:
HTML
<div class="container">
<div class="contentA"></div>
<div class="contentB"></div>
</div>
CSS
.container {
display: flex;
width: 100%;
height: 200px;
}
.contentA {
flex: 1;
}
.contentB {
flex: 3;
}
And what you get here is a container with a total size of 4 units, that share the space with its children in a relation of 1/4 and 3/4.
I have done an example in CodePen that solves your problem. I hope it helps.
http://codepen.io/timbergus/pen/aOoQLR?editors=110
VERY OLD
Maybe this is just a nonsense, but have you tried with a table? It not use directly CSS for positioning the divs, but it works fine.
You can create a 1x2 table and put your divs inside, and then formatting the table with CSS to put them as you want:
<table>
<tr>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
</tr>
</table>
Note
If you want to avoid using the table, as said before, you can use float: left; and float: right;and in the following element, don't forget to add a clear: left;, clear: right; or clear: both; in order to have the position cleaned.
div1 {
float: right;
}
div2 {
float: left;
}
This will work OK as long as you set clear: both for the element that separates this two column block.
I ran into the same problem and Mohits version works. If you want to keep your left-right order in the html, just try this. In my case, the left div is adjusting the size, the right div stays at width 260px.
HTML
<div class="box">
<div class="left">Hello</div>
<div class="right">World</div>
</div>
CSS
.box {
height: 200px;
padding-right: 260px;
}
.box .left {
float: left;
height: 200px;
width: 100%;
}
.box .right {
height: 200px;
width: 260px;
margin-right: -260px;
}
The trick is to use a right padding on the main box but use that space again by placing the right box again with margin-right.
I use a mixture of float and overflow-x:hidden. Minimal code, always works.
https://jsfiddle.net/9934sc4d/4/ - PLUS you don't need to clear your float!
.left-half{
width:200px;
float:left;
}
.right-half{
overflow-x:hidden;
}
As everyone has pointed out, you'll do this by setting a float:right; on the RHS content and a negative margin on the LHS.
However.. if you don't use a float: left; on the LHS (as Mohit does) then you'll get a stepping effect because the LHS div is still going to consume the margin'd space in layout.
However.. the LHS float will shrink-wrap the content, so you'll need to insert a defined width childnode if that's not acceptable, at which point you may as well have defined the width on the parent.
However.. as David points out you can change the read-order of the markup to avoid the LHS float requirement, but that's has readability and possibly accessibility issues.
However.. this problem can be solved with floats given some additional markup
(caveat: I don't approve of the .clearing div at that example, see here for details)
All things considered, I think most of us wish there was a non-greedy width:remaining in CSS3...
This won't be the answer for everyone, since it is not supported in IE7-, but you could use it and then use an alternate answer for IE7-. It is display: table, display: table-row and display: table-cell. Note that this is not using tables for layout, but styling divs so that things line up nicely with out all the hassle from above. Mine is an html5 app, so it works great.
This article shows an example: http://www.sitepoint.com/table-based-layout-is-the-next-big-thing/
Here is what your stylesheet will look like:
.container {
display: table;
width:100%;
}
.left-column {
display: table-cell;
}
.right-column {
display: table-cell;
width: 200px;
}
To paraphrase one of my websites that does something similar:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style TYPE="text/css"><!--
.section {
_float: right;
margin-right: 210px;
_margin-right: 10px;
_width: expression( (document.body.clientWidth - 250) + "px");
}
.navbar {
margin: 10px 0;
float: right;
width: 200px;
padding: 9pt 0;
}
--></style>
</head>
<body>
<div class="navbar">
This will take up the right hand side
</div>
<div class="section">
This will fill go to the left of the "navbar" div
</div>
</body>
</html>
just use a z-index and everything will sit nice. make sure to have positions marked as fixed or absolute. then nothing will move around like with a float tag.

Center a block of content when you don't know its width in advance

After lots of attempts and search I have never found a satisfactory way to do it with CSS2.
A simple way to accomplish it is to wrap it into a handy <table> as shown in the sample below. Do you know how to do it avoiding table layouts and also avoiding quirky tricks?
table {
margin: 0 auto;
}
<table>
<tr>
<td>test<br/>test</td>
</tr>
</table>
What I want to know is how to do it without a fixed width and also being a block.
#Jason, yep, <center> works. Good times. I'll propose the following, though:
body {
text-align: center;
}
.my-centered-content {
margin: 0 auto; /* Centering */
display: inline;
}
<div class="my-centered-content">
<p>test</p>
<p>test</p>
</div>
EDIT #Santi, a block-level element will fill the width of the parent container, so it will effectively be width:100% and the text will flow on the left, leaving you with useless markup and an uncentered element. You might want to try display: inline-block;. Firefox might complain, but it's right. Also, try adding a border: solid red 1px; to the CSS of the .my-centered-content DIV to see what's happening as you try these things out.
This is going to be the lamest answer, but it works:
Use the deprecated <center> tag.
:P
I told you it would be lame. But, like I said, it works!
*shudder*
I think that your example would work just as well if you used a <div> instead of a <table>. The only difference is that the text in the <table> is also centered. If you want that too, just add the text-align: center; rule.
Another thing to keep in mind is that the <div> will by default fill up all the available horizontal space. Put a border on it if you aren't sure where it starts and ends.
The following works well enough. note the position, and the use of auto
<div style="border: 1px solid black;
width: 300px;
height: 300px;">
<div style="width: 150px;
height: 150px;
background-color: blue;
position: relative;
left: auto;
right: auto;
margin-right: auto;
margin-left: auto;">
</div>
</div>
NOTE: not sure if it works in IE.
In FF3, you can:
<div style="display: table; margin: 0px auto 0 auto;">test<br>test</div>
This has the advantage of using whatever element makes most semantic sense (replace the div with something better, if appropriate), but the disadvantage that it fails in IE (grr...)
Other than that, without setting the width, your best bet is to use javascript to precisely position the left-hand edge. I'm not sure if you'd class that as a 'quirky trick', though.
It really depends on what you want to do, of course. Given your simple test case, a div with text-align: center would have exactly the same effect.
#wrapper {
width: 100%;
border: 1px solid #333;
}
#content {
width: 200px;
background: #0f0;
}
<div id="wrapper" align="center">
<div id="content" align="left"> Content Here </div>
</div>