I have a container div with a floating left-hand navigation pane and a content pane to the right:
<div id="header"></div>
<div id="container">
<div id="leftnav"></div>
<div id="content"></div>
<div class="clearfix"></div>
</div>
<div id="footer"></div>
CSS:
body
{
text-align: center; /* IE center div fix */
}
#container
{
width: 800px; /* site width */
background-color: red; /* so I can see it */
text-align: left; /* undo text-align: center; */
margin: 0 auto; /* standards-compliant centering */
}
#leftnav
{
float: left;
width: 200px;
}
#content
{
height: 100%;
width: 600px;
margin-left: 200px;
background-color: green; /* so I can see it */
}
.clearfix { clear: both; }
The #container div stretches to the full height of the floating #leftnav div, but the contained #content div does not stretch to 100% of the height. I've read elsewhere that this is due to the parent #container not having a specified height (defaults to auto) and therefore the 100% is not based on that container; however, I can't specify the height because the left navigation pane height isn't constant.
How can I get the #content div to be 100% of the height of the #container div when the #container div's height is defined by the floating #leftnav?
This is similar to the 3 column liquid "holy grail" CSS layout that has been plaguing people for years (though has been solved in the past couple years, though many of the solutions required browser hacks or Javascript to function).
I'd highly suggest you not reinvent the wheel here as it is difficult to get CSS to perform exactly as you're describing. Here is a good resource for this layout and many other similar liquid layouts:
http://matthewjamestaylor.com/blog/perfect-2-column-left-menu.htm
The easy way would be to use JS to set the height of #content to the height of #leftnav. You can use faux columns on #container and make a slice/gif of the green background and repeat it vertically on #container along with the red however you have it but I'm not sure if it fits your needs.
try this CSS
body
{
text-align: center; /* IE center div fix */
}
#container
{
width: 800px; /* site width */
background-color: red; /* so I can see it */
text-align: left; /* undo text-align: center; */
margin: 0 auto; /* standards-compliant centering */
}
#leftnav
{
float: left;
width: 200px;
}
#content
{
height: 100%;
width: 600px;
background-color: green; /* so I can see it */
float:right;
}
.clearfix { clear: both; }
I would also suggest using a line break with a clear both rather than a div.
Related
I asked a question today about good and bad practises in CSS/HTML/jQuery and when it is appropriate to use jQuery to set container dimensions. I got some good answers
So, understanding that jQuery is not the best option, I decided to ask maybe some of you can give some input about this "problem"
So, I have a page put together with php. I have one header for all of my pages and content is being changed with php (I am saying this only to let you guys know that wrapping header and div in one container is not an option):
include ("header.php");
include ("$lang/$section.php");
include ("footer.php");
I have a header with fixed hight (100px + 100px margin-bottom) and after that I have a div which on screens smaller than 768px(height) I want to be no longer than the remaining space. If the screen is larger, I want my div to be
max-height: 420px;
with
padding: 100px 0;
Inside of this div I have 3 floated columns. I need them to fill the space in the parent div.
What I would usually do is- use jQuery and calculate screen height and subtract header height and all the margins and paddings. But as I've learned today, that is not a good practise.
So, to wrap it up: I NEED THE DIV TO FILL THE SPACE BETWEEN HEADER AND BOTTOM OF THE SCREEN FOR VIEWPORT HEIGHT SMALLER THAN 768px. MAX-HEIGHT FOR THIS DIV IS 420px. With jQuery it is super easy but I can't figure out the clean css way.
Maybe some of you have an idea?
Here is my fiddle, so you guys don't have to type out all of the code.
Thank you in advance!
You can use calc() and vh (viewport height).
calc() browser support: http://caniuse.com/#search=calc
vh browser support: http://caniuse.com/#search=vh
So we use calc(100vh - 200px) being 100vh the height of the viewport and 200px the height of the header.
Also, we add a media query so that when the screen is bigger than 768px height we limit the height to 420px.
Try this:
header { height: 100px; background: #ccc; margin-bottom: 100px; box-sizing: border-box; }
section { width: 100%; height: calc(100vh - 200px); padding: 50px 0; background: yellow; box-sizing: border-box; }
.col1, .col2, .col3 { float: left; width: 33%; }
.colPadding { padding: 25px; background: blue; }
.cb { width: 100%; height: 1px; clear: both; }
body {
margin: 0;
}
#media screen and (min-height: 768px) {
section {
max-height: 420px;
}
}
<header>
This is my header with 100px bottom margin
</header>
<section>
<div class="col1">
<div class="colPadding">
section with padding: 50px 0; and max-height: 420px;
</div>
</div>
<div class="col2">
<div class="colPadding">
Column 2
</div>
</div>
<div class="col3">
<div class="colPadding">
Column 3
</div>
</div>
<div class="cb"></div>
</section>
Gave it a shot with CSS3 flex-box model and screen media queries. Here is my fiddle.
I used 300px instead of 764px for the fiddle. (you can change it if you want, I just used 300px so that it's easier to test)
Applied CSS
* { box-sizing: border-box; } /* force sizing based on border */
body {
display: flex; /* flex for body since wrapping header and section is not allowed */
flex-flow: column wrap;
}
header {
height: 100px;
background: #ccc;
margin-bottom: 100px;
flex: 0 0 auto; /* make header size fixed */
}
section {
width: 100%;
max-height: 420px;
padding: 50px 0;
background: yellow;
/* to occupy remaining space */
flex: 1 1 auto;
/* for columns inside to occupy full width */
display: flex;
flex-flow: row wrap;
/* for immediate children to stretch to max height possible */
align-items: stretch;
}
.col1, .col2, .col3 {
float: left;
/* to occupy remaining width */
flex: 1 0 auto;
}
.colPadding {
padding: 25px;
background: blue;
}
.cb {
width: 100%;
height: 1px;
clear: both;
}
/* Custom CSS */
/* style to apply when the screen is less than or equal to 300px (you can change this to 768px) */
#media screen and ( max-height: 300px ){
body {
height: 100vh; /* for body to have a size of the full screen */
}
header {
margin: 0px; /* remove margin bottom */
}
section {
padding: 0px; /* remove margin bottom and top/bottom padding */
margin: 0px;
}
}
More on CSS3 flex-box here.
I have a layout involving a div.left on the left with a set width of 40px, and a div.right on the right with a width of 100% to fill the remaining parent-container space.
HTML:
<div class="parent">
<div class="left">
L
</div>
<div class="right">
R
</div>
</div>
CSS:
.parent {
background: maroon;
max-width: 500px;
}
.left {
float: left;
background: green;
width: 40px;
opacity: 0.7;
}
.right {
width: 100%;
padding-left: 50px;
background: blue;
}
Jsfiddle
Is it possible to achieve this layout (one element with fixed width next to another that fills the remaining space) without resorting to the padding method I'm currently using? My problem is that I'd like to use a transparent background on the left-floated element, so the padding hidden beneath those elements would be visible. Also, my current approach doesn't downsize fluidly.
For that you need to float: left; the other element as well..
.right {
width: calc(100% - 40px);
background: blue;
float: left;
}
Demo
Also, am using calc() here, to deduct the fixed width sidebar which is 40px from 100% right bar.
As #Krimson commented that you want some space between the element as well, than use margin
.right {
width: calc(100% - 80px);
background: blue;
float: left;
margin-left: 40px;
}
Demo
Note: In the demo, am using overflow: hidden; as a quick fix for clearing floats, but better use clear: both; for that, for more information on clearing floats, you can read my answer here.
Inspected Elements
What if u change your .right to this:
.right {
/* width: 100%; remove width */
margin-left: 50px; /* Margin instead of Padding */
background: blue;
}
JSFiddle Demo
I have 2 divs, and I need both of them to have a minimum size of about 300px.
I need the left div to stretch out to the available space, however if the window size is too small, then the right div needs to drop below. This is what I have currently, but Im not sure what to change.
<style>
.bbleft {
min-height: 237px;
overflow:hidden;
}
.bbright {
float: right;
width: 300px;
min-height: 237px;
margin-left: 10px;
}
</style>
This is what you need
http://jsfiddle.net/fxWg7/790/
HTML
<div class="container">
<div class="left">
content fixed width
</div>
<div class="right">
content flexible width
</div>
</div>
CSS
.container {
height: auto;
overflow: hidden;
}
.left {
width: 300px;
float: left;
background: #aafed6;
}
.right {
float: none; /* not needed, just for clarification */
background: #e8f6fe;
/* the next props are meant to keep this block independent from the other floated one */
min-width:300px;
width: auto;
max-width:500px; /* not neccessary */
overflow: hidden;
}
fiddle
A css3 approach..
Flexible left div.
Right div drops when page too small.
Left div fills up the rest of the space.
HTML
<div class="left"></div>
<div class="right"></div>
CSS
body{
width:100%;
}
body div{
min-width:300px;
float:left;
}
.left{
width: calc( 100% - 310px );
}
simple use this
.bbleft {
min-height: 237px;
overflow:hidden;
float:left;width:100%;
}
I've been having trouble finding this one.
I have a div that is centered in the body margin: 0 auto;.
It contains multiple divs. I want it to expand to the width of it's widest child width: auto;
The problem is I want to have one of the child div's aligned on the right, however this expands my parent to 100%. How would I accomplish this without a fixed width for the parent?
You could do what you are after by setting the wrapper div to inline-block, and setting text-align: center on its parent (instead of using margin: 0 auto;). Here is an example: http://jsfiddle.net/joshnh/6Ake5/
Here is the HTML:
<div class="wrapper">
<div class="foo"></div>
<div></div>
<div></div>
</div>
And the CSS:
body {
text-align: center;
}
div {
border: 1px solid red; /* To see what is going on */
}
.wrapper {
display: inline-block;
text-align: left; /* Resetting the text alignment */
vertical-align: top; /* Making sure inline-block element align to the top */
/* Inline-block fix for IE7 and below */
zoom: 1;
*display: inline;
}
.wrapper div {
float: left;
height: 200px; /* To see what is going on */
margin: 10px; /* To see what is going on */
width: 200px; /* To see what is going on */
}
.foo {
border-color: blue; /* To see what is going on */
float: right;
}
I created a tumblr theme, where everything is centered and 660px wide.
However, I also post large imagery that is 940px wide, and have been centering that by giving it a negative margin of -140px (940-660/2), but this is not ideal because I then have to post all images as this dimension, or they are just aligned way left.
Scroll to the bottom of my site to see the images that are not aligned properly: http://seans.ws
The css:
section {display: block; clear: both; margin: 0 auto;width: 660px;}
article img {clear: both; max-width: 940px; margin-left: -140px;}
Thanks for any help!
You can choose between these two solutions:
Markup:
<div id="content">
<div class="a"><div class="b">
<img src="http://placekitten.com/100/100">
</div></div>
<div class="a"><div class="b">
<img src="http://placekitten.com/2000/100">
</div></div>
Common css:
#content {
width: 300px;
margin: 0 auto;
border: 1px solid blue;
}
.a {
/* extend image area */
margin-left :-9999px;
margin-right:-9999px;
/* but without scrollbars */
position: relative;
left: -9999px;
}
.a .b {
/* undo scrollbar-removing positioning */
position: relative;
left: 9999px;
}
The display: table way:
http://jsfiddle.net/ZhEku/3/
.a .b {
display: table; /* shrink-wrap to content (= the image) */
width: 300px; /* content width, acts as min-width when display:table */
margin: 0 auto; /* center inside the (2*9999+300)px area */
}
The display: inline-block way:
http://jsfiddle.net/ZhEku/4/
.a {
/* center content (= the image wrapped into .b) */
text-align: center;
}
.a .b {
display: inline-block; /* shrink-wrap to content (= the image) */
min-width: 300px; /* content width */
text-align: left; /* if image is smaller than the content */
}
Enjoy :)
Here's the infinite scroll js: http://static.tumblr.com/q0etgkr/ytzm5f1ke/infinitescrolling.js
Here is my margin-left script for images larger than the default width of containers:
<!--Dynamicaly center big images-->
<script>
$(window).load(function() {
$(function() {
$('img').css('marginLeft', function(index, value){
if($(this).width() > 660) {
return -($(this).width() - 660)/2;
}
return value;
});
});
});
</script>
The only thing I need to figure out is how to do this same function on images that dynamically load because I have infinite scroll (like the bottom images are not loaded until you go down the page.