margin-top isn't calculated as expected - html

I try to center a div on my page. It should use just relative values, so its size depends just on the window size.
I found a solution and it centers the box, but it seems that the margin isn't calculated correctly. Instead the size of the body gets bigger then the window. In the following example firebug tells me that the box #container has size 1265x335 on my screen. When inspecting #content its size is 506x134 and 2px boarder on each side, which matches my calculation. But the top margin is 316.
Have I got something wrong?
The margin should be 25% of 335, right?
How can I fix this?
Here's the HTML:
<body>
<div id="container">
<div id="content">
nothing...
</div>
</div>
</body>
And here the CSS:
html {
height: 100%;
}
body {
height: 100%;
margin: 0em 0em 0em 0em;
}
#container {
height: 100%;
}
#content {
text-align: center;
width: 40%;
height: 40%;
margin-top: 25%;
margin-left: auto;
margin-right: auto;
margin-bottom: auto;
border: 2px solid black;
}

From http://www.w3.org/TR/CSS2/box.html:
The percentage is calculated with respect to the width of the generated box's containing block. Note that this is true for 'margin-top' and 'margin-bottom' as well.
So you get 25% of 1265 which explains the behavior you are seeing. Unfortunately, I don't have any solutions to offer.
Edit: CSS3 makes this statement dependent on whether the containing block is horizontal (you would want it to be vertical). I don't think that any browsers implement the required block-progression property however (it might have unintended side-effects anyway).

Related

100% height not working - Height only height of browser window, not content

I like to think I'm pretty good with CSS, but this issue is driving me crazy.
I'm trying to get 3 columns to be 100% height. The first two columns are floated left, the third is not floated, just margined over. There is a wrapper around all 3 columns that clears the floats. The HTML/BODY tag have 100% height on them. As far as I know, if all parent containers have 100% height, it should work. The wrapper should be as tall as the tallest content block (third column), so the first two columns should be that tall too, using 100% height.
Problem is, the wrapper, and thus the body tag, have a height equal to that of the browser window. For some reason it won't read the middle columns content height. There is probably a super stupid simple explanation for this and I'm just missing it.
Don't want an overflow hack. Cannot do faux columns. I don't see why this can't work using the CSS spec for height.
If I put a pixel amount on the wrapper div, like a 2000px height, the first two columns fill the height just like I want them to. Why isn't this working??
HTML:
<body>
<div class="wrapper clearfix">
<section class="sidebar-news clearfix"></section>
<section class="black-bar-vertical"></section>
<section class="section-main-content event-detail"></section>
</div>
</body>
CSS:
html {
height: 100%;
}
body {
background-color: #333;
height: 100%;
* {
box-sizing: border-box;
}
}
.wrapper {
height: 100%;
position: relative;
margin: 0 auto;
}
.sidebar-news {
float: left;
width: 300px;
height: 100%;
min-height: 100%;
background-color: #site-color-yellow;
margin-right: -25px;
padding: 76px 40px 20px 20px;
}
.black-bar-vertical {
position: relative;
float: left;
width: 116px;
background: url("#{img-path}/black-bar-vertical.png") repeat-y top center;
min-height: 100%;
height: 100%;
text-align: center;
margin-right: -25px;
padding-top: 81px;
z-index: 50;
}
.section-main-content {
width: 580px;
background-color: #FFF;
padding-top: 55px;
padding-left: 10px;
margin-left: 360px;
}
SCREENSHOTS:
Top & Bottom of page
The height of the two columns in dev tools
EDIT:
Found this article, which is basically the same problem.
html body is smaller than its contents
If I change the height property to min-height on the body, the wrapper becomes the full height of the content, yay! But then the 100% heights on the first two columns don't work at all.
Like I originally thought... if 100% height is set on an element, it bubbles up the dom, and inherits the height of it's parent container. If that parent container has 100% height, it inherits the height of the parent's parent, etc. That works as expected. But when it hits the body tag, with 100% height, it's reading that as 100% height of the browser window. That's the default behavior, which doesn't make sense to me. If you take off the height on the body, it encompasses all content, but then the wrapper div looks up to the body for it's height definition and get's nothing because there is no height set on the body.
It's seeming like this specific scenario isn't really possible without using flexbox, table layout, javascript, or absolutely positioned elements.
Flexbox fo-sho!
.wrapper {
min-height: 100vh;
width: 100vw;
display: flex;
align-items: stretch;
}
.sidebar-news {
min-height: 100vh;
flex-grow: 1;
}
.black-bar-vertical {
min-height: 100vh;
flex-grow: 1;
}
.section-main-content {
min-height: 100vh;
flex-grow: 1;
}
Check this out for ref- Flexbox CSS Tricks
I've decided to do a combination of faux columns to get the first and third columns background colors, and then an absolute positioned second column that I can stretch full height using top: 0, bottom: 0.
If anyone can still solve this problem, I'd love to hear how it's done!

Make div 100% width with equal margins on both sides of content area

Here's what I'm wanting to do. When the site gets down to medium and small sizes, I want 100% width with margin: 20px all around. I'm trying to not define specific pixels for the width, so that it's consistent across all devices as much as possible. I figured that my CSS would apply the 20px margin to the right side as well as the left, but it's only applying to the left and the right is going outside the window.
Here's my HTML:
<div class="swipe-content">
<div id="your-accounts">
<h1>Your Accounts</h1>
<p>
Your accounts data will go here.
</p>
</div>
</div>
And here's my CSS:
.swipe-content {
clear: both;
width: 100%;
padding: 20px;
background-color: #fff;
margin-top: 20px;
}
Sorry to waste anyone's time with this, but it's late and I'm probably missing something really simple. I'm coming back to coding after a couple of years and any help would be appreciated.
In CSS when you specify a width, it usually means the inner-width not the outer-width.
outer-width = inner-width + margin + padding + border
In your case, your div is becoming 100% + 20px (left padding) + 20 px (right padding)
When you add display: block, the div will automatically try to take up as much width as possible.
Sure, in CSS 3 you could take advantage of the box-sizing property as focorner suggested. But to be compatible i would suggest removing width: 100% and adding display: block.
For this to work, you would need an outer div which has 100% width and is display:block
TL;DR
{
display: block;
// width: 100%; remove this
padding: 20px
}
One simple option would be to use:
.swipe-content {
box-sizing: border-box;
...
}
One way you could do this is by creating an outer div that fills the entire page and setting it to have a left and right padding of both 20px.
You could then put a div on the inside that fits 100% of the outer div.
#outer {
padding: 20px;
background-color: blue;
}
#inner {
width: 100%;
height: 500px;
background-color: grey;
}
Here it is in action: https://jsfiddle.net/SplashHero/cb1xs67u/
you can do like this
.swipe-content {
clear: both;
width: 100%;
padding: 20px;
background-color: #fff;
margin : 20px 20px 20px 20px;
}

Responsive Layout with a Fixed Width Child Element

I want to implement the following responsive layout in a webpage (HTML5 & CSS3):
All three div tags are wrapped inside a div with max-width of 960px;
I want to keep the width of "Navigation" div fixed therefore the following styles are being applied on it:
width:90px; float:left; padding:5px;
How can I make the "Contents" div occupy all remaining space without specifying its width, while keeping the layout responsive at the same time?
Thank you.
#content{
margin: 0 0 0 90px;
padding: 10px 30px;
}
Just put everything in a wrapper div and specify it's width to 960px
It depends on the browser support you want (need), with only 3 DIVs in a IE6+ way is hard (I think it's actually impossible). You're best bet is with the CSS calc method on the Content's DIV
width: calc(100% - 90px); The CSS calc method has IE9+ support so you would need to take that into account, in IE8- you would still need to use percentages.
If you are wondering how to separate the IE9+ code, then simply use #media i.e. something like this:
#media all {
#navigator {
width: 90px;
}
#content {
width: calc(100% - 90px);
}
}
#media is IE9+ compadible and because IE8- do not can't make heads or tails of it it will not affect them. So it is safe to place the IE9+ code in it.
If you can modify the HTML a bit I would advice the following:
<html>
<head>
<style type="text/css">
#h {
background: #f00;
}
#n {
background: #0f0;
width: 90px;
float: left;
}
#c_container {
background: #005;
width: 100%;
float: right;
margin: 0 0 0 -90px;
padding-left: 90px;
box-sizing: border-box;
}
#c {
background: #00f;
height: 50px;
}
#container {
max-width: 940px;
margin: 0 auto 0 auto;
}
</style>
</head>
<body>
<div id="container">
<div id="h">head</div><div id="c_container"><div id="c">cont</div></div><div id="n">nav</div>
</div>
</body>
Note how the content has a separate container, with is floated one way and the navigator is floated the other way, this is to make sure that they are not on the same plane.
the #c_container has a margin-left: -90px to bring it to the same row as the navigator and a padding-left: 90px; to make sure that #c (the new content DIV) is now visible. The #c_container also has the #c_container DIV. Without it you would need another container DIV so the width would not be affected by the padding, but that is easy enough to add, so I'll leave it up to you.
If you would use another container DIV for the content, then that solution would be IE6+ compatible, while the one I gave you is IE8+ compatible.

Website layout advice

I'm working on a website that fits perfectly in the browser window. Below is a basic blueprint of the website layout:
So far, the Red area is just display:block. The Green area is also display:block with margin-right:200px. The Blue areas(nested in a div) is float:right.
So I've got the width sorted. It's the height I need advice on. The Red and Dark Blue areas are a set height, but I need the Green and Light Blue areas to fit the height of the browser window view.
I'm trying to use box-sizing, but it exceeds the height of the window view because it's extending to the max height of the window. Sorry for my poor explanation. Any advice if would be excellent. Thank you!
For green div set height: calc(100%-{red-div-height}); and for the light blue div set height: calc(100%-{dark-blue-div-height}-{red-div-height});
This is kinda the legacy version of C-Link's answer.
jsFiddle and fullscreen
This has the limitation of any content falling below one page-full falling outside of its container (you can see if you scroll down in the fiddle, but not on the fullscreen).
Make sure our page stretches to its full height.
body, html { height: 100%; width: 100%; margin: 0; padding: 0;}
Set a static-height header.
header {
height: 101px;
background: red;
}
Create a box for everything under the header. You were on the right track with the box-sizing. We can add padding to it, in the same amount as our header. Then percentages inside it work nicely.
.content {
position: absolute;
box-sizing: border-box;
padding-top: 111px;
padding-bottom: 10px;
top: 0; left: 0;
height: 100%; width: 100%;
}
We float our aside (may or may not be the correct element, depending on contents) and set some styles on it.
aside {
float: right;
width: 20%;
height: 100%;
padding-bottom: 111px;
box-sizing: border-box;
}
.top {
height: 100px;
background: blue;
}
.bottom {
margin-top: 10px;
height: 100%;
background: skyblue;
}
This is our main, large, content area, which we float to the left. The width could be specified exactly if we wanted exact padding at the cost of additional HTML.
[role="main"] {
width: 78%;
background: limegreen;
height: 100%;
float: left;
box-sizing: border-box;
}
You can also set overflow-y: auto on our main or aside elements, to have them scroll when they run out of space. There should also be mobile styles for this page that remove the floating, absolute positioning, absolute styling, and widths should be nearly 100%.
you can always set the green box height to the window height minus the red box height.
accordingly the light box height to the window height minus the (red box height + the dark blue box height)
Edit 1: I haven't mentioned that has to be done with javascript.
Edit 2: Consider any paddings and margins too.
Could you not just give the divs a max or min height depending on their purpose?
I use a main container or wrapper div that the others would be contained in, that div is then my effective page or screen area.
<div id="wrapper">
<div id="content">
<div id="sidebar">
</div>
</div>
</div>
#wrapper{
min-height: Whatever value you want here;
max-height: Whatever value you want here;
}
It might be a good idea to set up your page using main container divs, hot only for the content but for the header and footer as well.
As an example, I have a main wrapper that is the whole page, within that is the header div, the content div, the nav div and the footer div. These are the main ones. Everything else can then be contained within them.
So, you can set the layout out using percentages so you have a fluid design that'll react to each browser size. The other elements will then 'fit' inside the main divs and be constrained to them. You may need to look into positioning etc but this is certainly the direction you should head towards.
<div id="wrapper">
<div id="header">Header Here including any divs to be contained within this space</div>
<div id="content">All content etc here</div>
<div id="nav">This is your sidebar</div>
<div id="footer">Footer, as per header</div>
</div>
Then use the css to re deisgn the above layout focusing only on those main divs. Use % instead of px to maintain fluidity.
#wrapper{
width: 100%;
height: 100%
}
#header{
width: 100%;
height: 20%
}
#content{
width: 70%;
height: 60%;
float:left;
}
#nav{
width: 30%;
height: 60%;
float:left;
}
#footer{
width: 100%;
height: 20%
}
A pretty common trick is to give the green (and light blue) box absolute positioning, a padding AND a negative margin. Because 100% width is relative to the containing box (could be a parent div, or just the window itself) this is not suitable. When the header was a relative height, say 10%, it would've been easy. The padding makes sure the content will not disappear behind the header, the negative margin puts the box back in place. Don't forget the z-index (otherwise the content (green part) will overlap the header).
The css looks like this:
.header { position: absolute; width: 100%; height: 100px; background: red; z-index: 1; }
.content { position: absolute; width: 100%; height: 100%; padding: 100px 0 0; margin-top: -100px; background: green; z-index: 0; }
The fiddle looks like this: http://jsfiddle.net/2L7VU/

Aligning div to center and its content to the left

I'd like to have a div that is centered on the document. The div should take all the space it can to display the content and the content itself should be aligned to the left.
What I want to create is image gallery with rows and columns that are center and when you add a new thumb it will be aligned to the left.
Code:
<div id="out">
<div id="inside">
<img src="http://www.babybedding.com/fabric/solid-royal-blue-fabric.jpg"/>
<img src="http://www.babybedding.com/fabric/solid-royal-blue-fabric.jpg"/>
<img src="http://www.babybedding.com/fabric/solid-royal-blue-fabric.jpg"/>
<img src="http://www.babybedding.com/fabric/solid-royal-blue-fabric.jpg"/>
<img src="http://www.babybedding.com/fabric/solid-royal-blue-fabric.jpg"/>
</div>
</div>
and the CSS:
img {
height: 110px;
width: 110px;
margin: 5px;
}
#out {
width: 100%;
}
#inside {
display: inline-block;
margin-left: auto;
margin-right: auto;
text-align: left;
background: #e2e2f2;
}
Live version here: http://jsfiddle.net/anPF2/10/
As you will notice, on right side of "#inside" there is space that I want to remove, so this block will be displayed until the last square and all of it will be centered aligned.
EDIT:
Please view this photo: https://www.dropbox.com/s/qy6trnmdks73hy5/css.jpg
It explains better what I'm trying to get.
EDIT 2:
I've uloaded another photo to show how it should adjust on lower resolution screens. notice the margins on the left and right. This is what I'm trying to get (unsuccessfully so far :\ )
https://www.dropbox.com/s/22zp0otfnp3buke/css2.jpg
EDIT 3 / ANSWER
well, thank you everybody for trying solve my problem. I solved this problem using JS, with a function that listens to a screen resize event. The functions checks the size of the right margin and add padding to the left so all the content is centered. I didn't find a solution using CSS. If you have one, I'd very much like to know it.
Thanks eveyone!
Specify a width for #inside to center it. I used width: 120px. Fiddle: http://jsfiddle.net/anPF2/7/
Additionally, CSS should be used for the height and width of images, not attributes such as height="300". The fiddle reflects this change.
use of display:inline-block takes extra margins. To remove those set font-size:0px to the #out container. See the demo
This is what you want to achieve? demo
img {
height: 110px;
width: 110px;
margin: 5px;
display: inline-block;
}
#out {
width: 100%;
margin: 0 auto;
position: relative;
border: 1px solid red;
}
#inside {
position: relative;
background: #e2e2f2;
}
You shouldn't use Pixels when laying out your css, it makes it very rigid and causes possible problems for people with high resolution screens and low resolution screens. Its best to declare it as a % or em (% is still probably slightly better when working with widths, but em for height is perfect)
First, the "outer" div must be declared to be smaller than what it is inside. For instance if "outer" is inside body:
#outer{
width: 100%;
}
#inside{
width: 80%;
margin-left: auto;
margin-right: auto;
}
#inside img{
height: 110px;
width: 110px;
margin-left: 1%;
margin-right: 1%;
margin-top: 0.5em;
float: left;
}
Okay so, since "inside" is 80% of "outer"'s width, the margin-left:auto, margin-right: auto together make the "inside" div center within the "outer".
Setting the float property to left moves all the imgs of inside to always try to move left while it can.
EDIT: I fixed this after looking at your picture you provided.
I haven't tested this but I believe it should work, let me know if you are having more problems.
To make the boxes not go the entire width of the page, try setting the width less than 100% on #out and add margin:auto; to center it.
#out {
width: 90%;
margin:auto;
}
http://jsfiddle.net/anPF2/36/