Why doesn't my code of collapsing margins work? - html

I wrote a simple html file to see how collapsing margins in css work, but I didn't get expected answer. First I'll show you my code:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>Collapsing Margins Testing</title>
<style type="text/css">
img {
width: 300px;
height: 300px;
}
.first {
margin-right: 10px;
}
.second {
margin-left: 20px;
}
</style>
</html>
<body>
<img src="http://cdn.shopify.com/s/files/1/0051/4802/products/mona-2_1024x1024.jpg?v=1447180277" alt="github cat" class="first">
<img src="http://cdn.shopify.com/s/files/1/0051/4802/products/mona-2_1024x1024.jpg?v=1447180277" alt="github cat" class="second">
</body>
I have set right margin of first image 10px and left margin of second image 20px respectively. I expect there to be 20px between the right of first image and left of second image as only bigger margin takes effect in collapsing margins. But when I inspect it in Google developer tools, the space between them are 30px(10px+20px). What's wrong with it? Or do I have a wrong understanding of collapsing margins?

Margin Collapsing works only on Block level elements.
Only top and bottom margins collapse, Right & Lefts don't.
An element's bottom margin and it's next elements top margins are collapsed.
It's very well explained here : https://css-tricks.com/what-you-should-know-about-collapsing-margins/
Just a tip : Google enough before posting questions!

Already pointed out by Sandip.
Margin collapsing works only on block level elements.
And also top and bottom margins collapse. Collapsing doesn't work for right and left margin.
Just for your clarity I edited your code snippet to replace img with block level elements and also replaced margin left and right with top and bottom so that you can see the margins collapse. The same will not happen for left and right margin.
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>Collapsing Margins Testing</title>
<style type="text/css">
.first, .second {
width: 300px;
height: 300px;
}
.first {
margin-bottom: 10px;
background: green;
}
.second {
margin-top: 20px;
background: yellow;
}
</style>
</html>
<body>
<div class="first">aaa</div>
<div class="second">bbb</div>
</body>

Related

CSS overflow:scroll causing an extra line break at the top of the text

I'm trying to create a div section with an image and text inside it, with scrolling overflow, but when I add the overflow: scroll, an extra line break is added at the top of the text, and I can't figure out how to get rid of it.
I know it isn't the padding or margin that's the problem, because the image is still positioned at the top. The text just has extra space. And removing just the overflow: scroll line gets rid of it, so I can't figure out why it's happening.
<!doctype html>
<html>
<head>
<style>
.scroll {
height: 160px;
overflow: scroll;
}
img.avatar {
height: 50px;
width: 50px;
padding: 0px 6px 1px 0px;
float: left;
}
</style>
</head>
<body>
<div class="scroll">
<img class="avatar" src="(link here)"><p>text here</p>
</div>
</body>
</html>
Any ideas?
It is indeed the margin of the p tag which is the problem here.
You may reproduce the behaviour you mentioned on other ways, e.g., using a border around the .scroll container.
The margin of the p tag is measured against the next element (in a minimal example, to the top of the page). If you set up a border or scrollbars, the margin is instead measured against the container itself, so it moves down.
To prohibit that behaviour, you could, for example, set a margin of 0 to the p tag.

setting the top margin of the h1 element in the header does not work as expected

I have made use of the html5 header tag and an h1 tag within it. After setting up the top margin property of the h1 element in my header to 0px, i manage to remove the top margin of the header, but i want the h1 element inside my header to have a top margin of around 15px.
Now when i try setting the top margin of the h1 element, it also creates a top margin for the header which i don't want.
Can someone help me out with this...?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="normalize.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
<title>Codename : ENT</title>
</head>
<body>
<header>
<h1>Site Title / LOGO</h1>
<p>Site Tagline / Slogan / One liner.</p>
<p></p>
<nav></nav>
</header>
<div id="content_wrapper"></div>
<footer>
</footer>
</body>
</html>
and CSS
header {
background-color:#ff0
}
header h1 {
margin-top:0;
margin-left:15px
}
header p {
margin-left:15px
}
Use padding-top for h1 or header or use overflow:hidden for header
The issue you are facing here is call collapsing margins
Here is an excerpt from this mozilla article:
Parent and first/last child
If there is no border, padding, inline content, or clearance to
separate the margin-top of a block with the margin-top of its first
child block, or no border, padding, inline content, height,
min-height, or max-height to separate the margin-bottom of a block
with the margin-bottom of its last child, then those margins collapse.
The collapsed margin ends up outside the parent.
So I could fix this by adding a border to the header element - DEMO
header {
border: 1px solid transparent;
}
or by clearence - DEMO
header {
overflow: hidden;
}
or by adding padding - DEMO
header {
padding: 1px;
}
... etc etc
As mentioned is every other answer, what you actually want is padding-top, not margin-top.
The difference between these two is pretty easy to understand, essentially padding is inside the element, and margin is outside the element, the last two examples from this tutorial show it fairly well
http://html.net/tutorials/css/lesson10.php
So with your code, the header element is the container, adding margin-top:15px will move the element down 15px, meaning the whole container, yellow background included, sits lower. Adding padding-top:15px with increase the height of the header element by 15px, by adding to the top of the element, and moving the content down, leaving a yellow gap of 15px at the top.
Add padding-top: 15px; to the properties of h1.
try this one
header h1 {
padding-top:15px;
margin-top:0;
margin-left:15px
}
Demo
css
header {
background-color:#ff0;
margin:0;
display: inline-block; /* add this to make it inline as <header> id block element by default */
width: 100%; /* for 100% width */
}
header h1 {
margin-top:15px;
margin-left:15px
}
header p {
margin-left:15px
}

Pack display: inline-block divs

I have a number of display: inline-block div elements of fixed width and variable height.
I want to print each div without wasting paper. I concatenated the divs to make a single HTML document which I would then print. Example document with empty divs:
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test page</title>
<style type="text/css">
div{
display:inline-block;
width: 13cm;
background-color: #999;
margin: 1mm;
}
</style>
<div style="height:10cm"></div>
<div style="height:20cm"></div>
<div style="height:14cm"></div>
<div style="height:20cm"></div>
<div style="height:15cm"></div>
<div style="height:30cm"></div>
<div style="height:20cm"></div>
<div style="height:27cm"></div>
The result was unsatisfying. Firefox aligned the divs in a kind of table with each div taking up the bottom part of a "cell". This wastes a lot of space if I have a big div on the same "row" as a smaller one. I've also tried adding float: left to the div styling, but this only made the divs take up the top part of the "cells" instead of the bottom part.
What's the least kludgy way to fix this?
Since all of your elements have the same width, you could use the columns property. However, the elements will be arranged from top to bottom rather than left to right:
http://tinker.io/f834a
body { /* or whatever is containing your elements */
columns: 13cm; /* width of your elements */
}
Prefixes may be necessary. http://caniuse.com/#feat=multicolumn
You could do something like this, it works great if you're fine with just 2 columns:
div:nth-child(odd)
{
float: left;
clear: left;
}
div:nth-child(even)
{
float: right;
clear: right;
}
jsFiddle

Create fixed height horizontal div with a fluid one

I'm trying to establish a layout with in the base three rows: A header, content and footer div.
The two outer most div's are of a fixed height; The center div has to be fluid and adapt itself to the height of the browser screen.
Could someone point me in the right direction how to tackle this with proper CSS? For now I'm not yet interested in a javascript solution. As CSS doesn't provide a clean answer, a javascript solution comes eminent!
This is how far I came:
<div id='header'>Header</div>
<div id='content'>
<div id='innerContent'>
This is the fluid part
</div>
</div>
<div id='footer'>footer</div>
css:
#header {
position:absolute;
top:0px;
left:0px;
height:100px;
z-index:5;
}
#content {
position:absolute;
top:0px;
left:0px;
height:100%;
z-index:2;
}
#innerContent {
margin-top:100px;
height:100%;
}
#footer {
height:400px;
}
EDIT:
I'm sorry, I feel embarassed. I made something similar about a year ago, but at first I didn't think it was possible to adjust it to this situation. Apparently it was.
As I think other's have already said, it is possible to put the footer div at the bottom by positioning it absolutely. The problem is to adjust it's position when the content div gets larger. Since the footer is absolutely positioned it won't follow the content div's flow, which makes it stay at the same place even though the content expands.
The trick is to wrap everything in an absolutely positioned div. It will expand if it's content gets larger, and the footer div will be positioned according to the wrapper's borders instead of the document's borders.
Here's the code. Try to put a bunch of <br /> tags within the content div and you'll see that everything adjusts.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Layout test</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#wrapper {
min-height: 100%;
min-width: 100%;
position: absolute;
}
#header {
height: 100px;
background-color: red;
}
#content {
background-color: gray;
margin-bottom: 50px;
}
#footer {
height: 400px;
min-width: 100%;
position: absolute;
bottom: 0px;
margin-bottom: -350px;
background-color: blue;
}
</style>
</head>
<body>
<div id="wrapper">
<div id='header'>Header</div>
<div id='content'>
Content
</div>
<div id='footer'>footer</div>
</div>
</body>
</html>
ORIGINAL:
Sadly, css lacks a clean way to do this. You don't know the viewport height (which you called h) and therefore can't calculate h-100-50 You have to build your website so that most people will see 50px of the footer div. The way to do that is to set a min-height for the content div.
The min-height value must be derived from some standard viewport height. Google Labs have published their data on viewport sizes for their visitors and made a great visualization of it here:
http://browsersize.googlelabs.com/
I design for my own viewport, which is 620px high (according to google ~80% have this viewport height). Therefore the min-height for the content div should be 620-100-50 = 470 px.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Layout test</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#header {
height: 100px;
background-color: red;
}
#content {
min-height: 470px;
background-color: gray;
}
#footer {
height: 400px;
background-color: blue;
}
</style>
</head>
<body>
<div id='header'>Header</div>
<div id='content'>
Content
</div>
<div id='footer'>footer</div>
</body>
</html>
If I understand your problem correctly I think this might lead you into the right direction.
http://jsfiddle.net/mikevoermans/r6Saq/1/
I'll take a poke at it. Not sure if I read your screenshot correctly but I set the content div to be 50-100px in height.
Here is my jsfiddle: http://jsfiddle.net/AX5Bh/
I am using the min-height and max-height CSS attributes to control the #innerContent div.
If you horizontally expand the result window you will see that some of the text is highlighted . I have set the content to be hidden if it is larger than the #innerContent div. You might want something different. I only highlighted the text with an <em> tag to demonstrate that max-height was working.
If you remove all the text but the first sentence you will see it is 50px in height.
Here is a link to browser support of min-height and max-height: http://caniuse.com/#search=max-height

CSS: Why do I get a vertical scrollbar with this simple HTML? (100% height div)

In Firefox 3.5.8 on Windows, I get a vertical scrollbar when I use this HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Haloooo1 - T3</title>
<style type="text/css">
html, body, div {height: 100%; margin: 0; padding: 0; }
#main {
width: 320px;
background:#7C7497;
height : 100%;
margin: 0 auto;
}
</style>
</head>
<body>
<div id='main'>
<p>Hello</p>
</div>
</body>
</html>
Q1. Can anyone explain why?
Can anyone explain how to remove it?
Q2. Can anyone explain why there is a cushion of whitespace above the div? Can anyone explain how to remove it?
Add this:
p {margin: 0; }
Your p element has some margin on the top.
Let me recommend using a CSS reset file. I like the YUI one.
According to firebug it is margin in <p>. At least in 3.6 setting margin-top to p solves problem.
p {
margin-top: 0;
}
It's the paragraph.
If you add
p { margin: 0px; padding: 0px }
all gets well, including the scroll bar.
Why the paragraph feels entitled to leave its parent element like that, I'm not entirely sure yet.
A1. You are getting a scroll bar because the div has a size of 100% of i browser window not 100%. Because the div is the same size as the browser window but is shifted down a scroll bar is needed to display the bottom of the div.
A2. The whitespace above the div is the top margin of the p element.