Adding CSS border changes positioning in HTML5 webpage
The issue comes from something called "margin collapsing". It's simple: 2 adjoining margins collapse to the highest of the two (I say two, but it could be more).
In your case, '#mydivs' margin-top
- 80px - is touching the 'header's margin-top
- 0px. They're adjoining - there's no element between them, nor padding, nor border.
The margins collapse, therefore, to the highest of the two (80px), and it is then applied on the highest of the elements in the parent-child hierarchy - that's the header
in this case.
One solution to this problem is to put something between the margins; either of some padding, or a border on the header works fine.
header {
border-top: 0.1em solid rgba(0,0,0,0);
}
A second solution (my preferred one), is to make the parent element create a new block formatting context. That way, its margins simply won't collapse with that of its child.
How do you create a block formatting context?
There are four possible ways.
- by floating it.
- "position absoluting it".
- adding one of these displays: “table-cell”, “table-caption”, or “inline-block".
- adding an overflow other than visible.
To prevent the margins from collapsing you could do any of these 4. I usually go for number 4) - set overflow to auto, as it's only side affect... well it's improbably likely to become a problem.
header {
overflow: auto;
}
That's basically it for parent-child margin collapsing. There's also margin collapsing between siblings and the rule is pretty much the same: 2 adjoining margins collapse to the highest of the two. It's the solutions that are not.
Here's a great explanation of margin-collapsing - http://www.howtocreate.co.uk/tutorials/css/margincollapsing
Unable to position HTML elements using CSS
you need to remove the margin from the .header h1
tag - instead of your margin-left:100px;
try margin: 0 0 0 100px
. Also some browsers put top margin onto p tags so you may want to reset that margin too.
You can't add padding
or background-color
to your image tag
If you have chrome, try using the inbuilt dom inspector (right click and inspect element), it will show you what is happening with your elements
I would personally restructure your html so it looks like this:
<div class = "container" >
<div class = "header">
<div class="imageHolder"><img src = "http://lorempixel.com/100/100" alt = "logo" /></div>
<div class="textHolder">
<h1> Website name </h1>
<p><strong>- Tagline ,if any, goes here</strong></p>
</div>
</div>
</div>
and then you can use the following styles:
body{margin-top: 0px; background-color: #FBFBFB;}
.container{width: 1200px; margin-left: auto; margin-right: auto; margin-top : 0px; background-color: white; }
.header .imageHolder {float: left; width:110px; background-color: orange;}
.header .imageHolder img {margin:5px;}
.header .textHolder {float:right; width:1090px;}
.header h1{font-size: 40px; font-family: "lucida console"; letter-spacing: 1.2px; background-color: pink; margin:0;}
.header p {margin:0; color: gray; font-family: Verdana; font-size: 15px; letter-spacing: 1.4px; position: relative; background-color: lime; margin-left:-30px; width:1120px;}
http://jsfiddle.net/peteng/XJVW3/
CSS borders interfering with absolute positioning
Try out CSS2 outline
property:
.bordered {
outline:2px solid blue;
}
Outline does not affect element position.
You can also use CSS3 outline-offset
as seen here: http://www.css3.info/preview/outline/
Adding css border to :after element
Try adding a :before element that creates the same arrow as your :after but make it a little bit larger, and red. make sure the :before is behind your :after and it should give the same affect as having a border on your :after arrow.
.bubble::before
{
content: '';
position: absolute;
border-style: solid;
border-width: 0 16px 16px;
border-color: red transparent;
display: block;
width: 0;
z-index: 1;
margin-left: -16px;
top: -16px;
left: 50%;
}
edit: linked to correct jsfiddle
revised fiddle
CSS: Positioning a box over top over a main div
Position the contact box absolutely.
For what it's worth, none of your CSS above will work because you're using a dot to signify the class of the div, rather than a # pound sign to signify ID of the div (div.logo
corresponds to <div class="logo">
, div#logo
corresponds to <div id="logo">
)
#page-wrap {
/* parents of absolutely positioned elements must have a position */
position: relative;
}
#contactDetails {
position: absolute;
top: 0;
right: 0;
/* you could use 'left: 0;' instead, to move to the left edge */
width: 300px;
}
Border style do not work with sticky position element
The problem occurs because of the use of border-collapse: collapse
. When browsers collapse the borders, the top and bottom border on the <th>
must be getting applied to surrounding elements—the top border to the <table>
and the bottom border to the following <tr>
.
If you use border-collapse: separate
and fashion your borders to sit on one side, the borders will truly attach to the <th>
, stay fixed as expected, and appear collapsed.
Here are example styles that can be applied to your HTML snippet.
#wrapper {
width: 400px;
height: 200px;
overflow: auto;
}
table {
width: 100%;
text-align: center;
border-collapse: separate; /* Don't collapse */
border-spacing: 0;
}
table th {
/* Apply both top and bottom borders to the <th> */
border-top: 2px solid;
border-bottom: 2px solid;
border-right: 2px solid;
}
table td {
/* For cells, apply the border to one of each side only (right but not left, bottom but not top) */
border-bottom: 2px solid;
border-right: 2px solid;
}
table th:first-child,
table td:first-child {
/* Apply a left border on the first <td> or <th> in a row */
border-left: 2px solid;
}
table thead th {
position: sticky;
top: 0;
background-color: #edecec;
}
How to understand this CSS Menu Demo?
The overflow: hidden
contains the floated li
s inside the ul
by creating a blocking context, there is a in-depth explanation here:
Adding CSS border changes positioning in HTML5 webpage
The float: left
pulls everything over to the left hand side, and in your case in a line, without a float: left
or right
the default is none
which means elements will just stack which is why you're getting a column style layout.
The inline-block
, or a block
in other uses, makes the element incorporate the padding, in the example you provided, into its height. For example, if you had text 10px high and 20px padding on the top and bottom, the element would be 10px as the padding would get ignored, with adding a display type of block
or inline-block
this takes it into account and renders at a height of 50px.
Text in Border CSS HTML
You can do something like this, where you set a negative margin
on the h1
(or whatever header you are using)
div{
height:100px;
width:100px;
border:2px solid black;
}
h1{
width:30px;
margin-top:-10px;
margin-left:5px;
background:white;
}
Note: you need to set a background
as well as a width
on the h1
Example: http://jsfiddle.net/ZgEMM/
EDIT
To make it work with hiding the div
, you could use some jQuery like this
$('a').click(function(){
var a = $('h1').detach();
$('div').hide();
$(a).prependTo('body');
});
(You will need to modify...)
Example #2: http://jsfiddle.net/ZgEMM/4/
Related Topics
How to Position an Image at The Bottom of Div
Delete White Space Between Divs
Browser Displays Page Without Styles for a Short Moment (Visual Glitch)
Default Settings of Unrecognized HTML Elements
Jekyll Syntax Highlighting Not Working - Classes Are Not Being Added
How to Make a Div to Wrap Two Float Divs Inside
Overflow-X Overwritten by Overflow-Y
Horizontal Centering Text Over Image via CSS
How to Center Form in Twitter Bootstrap
Youtube Embedded Video as Iframe with Border-Radius
<Div> Inside Link (<A Href="">) Tag
CSS Background Images Not Loading