Why does margin-top get applied to the containing element here? - html

I'm sure this has been asked many times but I couldn't work out what to search for.
I have the following HTML and CSS (see jsfiddle for a live example):
<!--HTML-->
<body>
<div id="container">
<div id="header">
<ul>
<li>Item1</li>
<li>Item2</li>
</ul>
</div>
</div>
</body>
/* CSS */
#container {
background-color: red;
width: 400px;
height: 200px;
margin: auto;
}
#header ul {
list-style: none;
margin-top: 20px; /* I want this to be the margin at the top of the ul, not the container */
}
#header li {
float: left;
margin-right: 10px;
}
The problem I'm having is with the margin-top of the <ul>. It's adding space above the #container <div>, not above the <ul>. I must be missing something fundamental about CSS, because I just don't get this behaviour. Could someone enlighten me please?

Due to margin collapsing, if it touches the top of the body then that's where the margin lives. Easy fix is to just rely on top padding.

Try the padding. I've also found that using a CSS reset is helpful in getting everything to behave more similarly across browsers.
http://meyerweb.com/eric/tools/css/reset/

Related

Removing the default 8px margin from body

This question have been asked before I'm aware of, but unfortunately still haven't found a solution. Even though I tried using their solutions.
My problem is that I can't get rid of the default 8px margin on around the body/html tag. It looks like that it doesn't even respond to the changes I put in between the curly brackets.
Html:
<div class="header">
Header123
</div>
<div class="nav">
<ul>
<li>HOME</li>
<li>PROJECT</li>
</ul>
</div>
<div class="main">
Article
</div>
<div class="footer">Footer</div>
CSS:
body,html {
margin: 0;
text-align: center;
background-color: blue;
}
.container
{
margin: 0;
background-color: red;
}
.header
{
text-align: left;
height: 90px;
background-color: green;
margin: 0;
}
.nav
{
float: right;
}
.nav ul
{
list-style: none;
height: 30px;
padding: 0px;
margin: 0px;
}
.nav ul li
{
margin: 10px;
}
.footer
{
height:40px;
}
Link: https://jsfiddle.net/RasmusGodske/yg2gsa0t/
For HTML:
<body style="margin:0;padding:0">
For CSS:
body {margin:0;padding:0}
Probably you are having a difficulty because margin and padding are two different things. You should try both and use the one that suits your needs.
You can read more about margin vs padding from here
Remember: margin is outside an element's border; padding is inside.
You need to set the padding of the body element to zero. (The margin of the body element is meaningless; it'd represent a space outside the browser window!)
As an aside, you don't need to set any CSS properties on the html element. body already contains everything that you'd want to set properties on.
You can directly remove the margin using:
body { margin: 0; }

CSS overflow:hidden with floats

I read the following code on w3schools and do not understand how the overflow property would impact whether text appears to the right of the ul or not.
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
}
li {
float: left;
}
a {
display: block;
width: 60px;
background-color: #dddddd;
padding: 8px;
}
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
</ul>
<p><b>Note:</b> overflow:hidden is added to the ul element to prevent li elements from going outside of the list.</p>
I know that overflow:hidden is used to handle content that goes outside of the box but don't understand how it applies in this instance.
I try to end the confusion:
ul is a block-level element as is the p element (they stretch to 100% of the parent width). That is why per default the p will appear below the ul if no width or display is declared on those elements.
Now in your example the ul contains only floated elements. This makes it collapse to a height of 0px (It still has 100% width though as you can see in the example). The adjacent p will appear to the right of the floated lis because they are considered as normal floated elements.
Now declaring overflow (any value other than visible) establishes a new block formatting context, which makes the ul contains its children. Suddenly the ul "reappears", not having size 0px anymore. The p is getting pushed to the bottom. You could also declare position:absolute to achieve the same "clearing" effect (with the side effect that now the ul is taken out of the normal element flow - the ps will be overlapped by the ul.)
See the example fiddle
If you are into the technical stuff, compare the according paragraphs of the CSS spec:
ยง10.6.3 Block-level non-replaced elements in normal flow when 'overflow' computes to 'visible'
and
ยง10.6.7 'Auto' heights for block formatting context roots. (Thanks to BoltClock for digging out the links).
ul{
list-style-type:none;
margin:0; padding:0;
background-color:#dddddd;
border:2px solid red;
}
li{
float:left;
}
a{
display:block;
width:60px;
background-color:#555;
color:white;
}
p{
margin:0;
outline:2px dotted blue;
}
#two{
clear:both;
overflow:hidden;
}
No overflow:
<ul>
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
</ul>
<p>Notice the collapsed ul - no background-color visible, collapsed border and this paragraph treats the lis as regular floats </p>
<br>
With overflow: hidden
<ul id="two">
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
</ul>
<p>the ul reappeared - it now contains the child li's - the float is cleared</p>
Setting overflow: hidden on an element causes a new float context to be created, so elements that are floated inside an element that has overflow: hidden applied are cleared.
http://www.w3.org/TR/CSS2/visuren.html#block-formatting
To quote from HTML & CSS Is Hard
To summarize, when you have an extra unfloated HTML element at the
bottom of a container div, use the clear solution. Otherwise, add an
overflow: hidden declaration to the container element. The underlying
idea for both options is that you need a way to tell the browser to
incorporate floats into the height of their container element
Instead of the overflow:hidden; use clear:both; for the <p>. here it is in use http://jsfiddle.net/Mvv8w/. Basically overflow:hidden will clear anything that is aside it just as clear:both; does.
This is why w3schools is not a reliable source for web designer/developers. You are correct, it is a terrible example.
It doesn't because, in this example, the parent element does not have a fixed with. Furthermore, it's an un-ordered list tag, which is going to stretch to the size of it's children regardless.
http://jsfiddle.net/EhphH/
CSS
.parent {
width: 150px;
height: 100px;
padding: 10px;
background: yellow;
overflow: hidden;
}
.child {
float: left;
width: 75px;
height: 120px;
margin: 10px;
background: blue;
}
.baby {
width: 200px;
height: 25px;
background: green;
}
Markup
<div class="parent">
<div class="child">
<div class="baby">
</div>
</div>
<div class="child">
</div>
</div>

HTML & CSS: How to create four equal size tabs that fill 100% width?

I am trying to create a navigation panel for my website. I would like it to consist of:
Four tabs in equal size with text-centered in each tab.
They should fill the whole page width.
I would really like the design to be flexible and browser friendly. I have tried various float techniques, but I can't get it to work. I hope that you can help me out!
Thank you.
HTML
EDIT: it's 2015 and HTML5 has been there for a while; following code should be inside a nav element (html5doctor) with landmark ARIA attribute role="navigation" on it (and 99.9% of the time be unique in any given page).
A navigation panel should use an unordered list of links:
<ul id="nav">
<li>One</li>
<li> Second</li>
<li>Third</li>
<li>Fourth and last, so large that... worst case</li>
</ul>
CSS
EDIT2: It's 2017, just use Flexbox ๐Ÿ˜ฒ (with or without flex-wrap: wrap)
inline-block is useful but has one drawback: whitespace between two elements must be carefully managed. Whether removed or no </li> in HTML5 or </li> at the beginning of the following line stuck like </li><li>next item or other tricks, you still have to do something or it'll create a ~4px gap between 2 elements.
25% + 25% + 25% + 25% doesn't equal 100% on all browsers if the total isn't a multiple of 4. Each browser has its own rounding method.
If you want elements to total 100% width and equal width, another method is to use display: table (and table-cell) with table-layout: fixed to force browsers to use the other table algorithm, the one that doesn't try to adapt cells width to content but respect the widths wanted by the designer/developer as far as possible.
ul {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
#nav {
display: table;
table-layout: fixed;
text-align: center;
}
#nav li {
display: table-cell;
width: 25%;
padding-right: 1px;
height: auto;
vertical-align: bottom;
}
#nav a {
display: block;
min-height: 100%;
padding: 4px 10px;
background-color: #222;
color: white;
border-radius: 6px 6px 0 0;
}
Fiddle
http://jsfiddle.net/PhilippeVay/aHCy3/1/
edit: http://jsfiddle.net/PhilippeVay/aHCy3/2/ with another method for space between each tab, courtesy of my colleague.
You don't need floats for this. Just set the width to 25%, or a tiny bit less than 25%. If you're using this on a block level element, set display: inline-block. This will work for all browser sizes, as well as respond to window resize.
HTML
<div class="nav">Nav 1</div>
<div class="nav">Nav 2</div>
<div class="nav">Nav 3</div>
<div class="nav">Nav 4</div>โ€‹
CSS
body, html {
width: 100%;
padding: 0;
margin: 0;
}
.nav {
width: 24%; /*Slightly less than 1/4th of the width*/
display: inline-block;
padding: 0;
margin: 0;
text-align: center;
}โ€‹โ€‹
Live demo
css:
.tab {
float: left;
width:25%;
height:25px;
background:black;
border:1px solid #fff;
box-sizing: border-box;
}โ€‹
html:
<div class="tab"></div>
<div class="tab"></div>
<div class="tab"></div>
<div class="tab"></div>โ€‹
jsfiddle: http://jsfiddle.net/zP7Xh/6/

Is there an easy way to center a <div> inside another <div> with css?

I have a navigation bar at the top of a page I am developing. I want a certain <div> to be centered in the bar (which is another <div>). Is there an easy way to do this with CSS? I tried using pixels but that does not work when you resize the window.
I am trying to center it horizontally not vertically.
Update:
The <div> that I want centered is one of three <div>s in one <div>. It is a search bar.
below is an image of what I want and what it is with margin set to auto. (sorry the image does not exactly show where I want the search bar placed. I want it placed a little more to the left (at the center of the nav bar)
Apply margin-right: auto; margin-left: auto; to the inner <div>. See this example.
#wrap { margin:0 auto; width:800px; }
If you don't want to set an explicit width you'll have to use an alternate method.
There are a variety of ways to do it, but this simple reduction should get you going...
This won't work on IE6 and below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Untitled</title>
<style type="text/css">
#nav {
display: table;
width: 100%;
}
#nav div {
display: table-cell;
background-color: red;
}
.menu1 {text-align: left;}
.menu2 {text-align: right;}
.site-search {text-align: center;}
</style>
</head>
<body>
<div id="nav">
<div class="menu1">
MENU ONE
</div>
<div class="site-search">
SEARCH BOX
</div>
<div class="menu2">
MENU TWO
</div>
</div>
</body>
</html>
You'll need to reset the text-align of your descendent elements to left or whatever you need.
IF you need IE6 support you could do something along the lines of...
<style type="text/css">
#nav {
border: 1px red solid;
overflow: hidden;
text-align: center;
}
.menu1 {
float: left;
width: 30%;
text-align: left;
}
.menu2 {
float: right;
width: 30%;
text-align: right;
}
.site-search {
display: inline;
}
</style>
Depending on your situaltion you could use the first example by default and fallback to the second example for IE6 using Conditional Comments..
<div>
<div class="cen">
</div>
</div>
and then
.cen{
margin:auto;
}
This would horizantally center align your div
Another method which hasn't been mentioned is to use absolute positioning with a negative margin. Works cross-browser too, but you need an explicit width.
<div class="parent-container"> <!-- this needs to have position: relative -->
<div id="search">Search...</div>
</div>
Here's the CSS
.parent-container {
position: relative; // this is so #search is positioned relatively to it's parent
}
#search {
position: absolute;
width: 250px; // note the explicit width
left: 50%; // This moves the element 50% to the left
margin-left: -125px; // This is exactly HALF of the elements width
}
If you don't quite understand it, let me know and I'll try add a bit more information.
Update
Another way is to use the table-cell approach, as discussed here.

Can I center a <ul> with left-aligned <li>s?

I'd like to center a list of left-aligned items.
This is what I currently have:
<!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>Shrinkwrapped List</title>
<style type="text/css">
#wrapper {
margin: auto;
width: 500px;
border: solid 1px #CCCCCC;
}
#header {
text-align: center;
font-size: 200%;
}
#content {
text-align: center;
}
#content ul {
text-align: left;
font-size: 150%;
list-style-type: none;
margin: 20px auto;
padding: 0px;
border: solid 1px #666666;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="header">
Shrinkwrapped List
</div>
<div id="content">
<ul>
<li>Lorem ipsum</li>
<li>Dolor sit amet</li>
<li>Consectetur</li>
<li>Adipiscing elit</li>
<li>Morbi odio</li>
<li>Mi blandit vehicula</li>
</ul>
</div>
</div>
</body>
</html>
Which produces a page that looks like:
What I really want looks like this:
I can accomplish this by adding width: 200px; to #content ul but the problem is that I have a lot of lists like this and they all have various widths.
I'd like the <ul> to shrink to the content so it can be centered correctly. Or am I going about this the wrong way?
Thanks for any help you can provide.
Solution
Thanks to KennyTM and Magnar, here is the solution:
Add these four lines to #content ul's CSS rules:
display:-moz-inline-stack;
display:inline-block;
zoom:1;
*display:inline;
I've tested this in IE6, IE7, IE8 and Firefox 3.6. The results looks like the second image above and the list always fits to the content of the items.
Set the <ul> to use display: inline-block;. See http://jsbin.com/atizi4.
Note that inline-block is not supported (completely) for IE โ‰ค7.
You can probably adopt my previous answer. Inline-block for IE, display:table for modern browsers. Might need to explicitly specify a list-style-type.
Edit: Since this is a list, may be able to get away with inline-block on the ul and not display:table. You need to declare in a separate rule, display:inline; after inline-block for IE.
I'd look at using CSS and putting a margin: 0 auto on the <ul> with a maximum width container.
Try this. It involves in incompatibilities, but I don't really know how older browsers handle margins and padding and all that anymore since I only work with new ones. It only involves some minor changes to your CSS.
/* I didn't style the other parts, so I'm taking them out to save space. */
#content {
margin: 0 auto;
}
#content ul {
border-top: solid 1px #666666;
border-bottom: solid 1px #666666;
text-align: left;
font-size: 150%;
list-style-type: none;
margin: 20px auto;
padding: 0px;
width: 202px;
}
#content li {
border-left: solid 1px #666666;
border-right: solid 1px #666666;
margin: 0 auto;
padding: 0;
width: 200px;
}
Edit: I want to clarify what I changed. I changed how content is aligned, but honestly, you can change that back, I don't think it has an effect.
What I originally did was set a fixed width and centered your li element, which you had no styling for. That just centered the content. The border you placed was on the ul so it was very wide, but if we placed it in the li then we would have many boxes. So, I split the border style. The reason why #content ul has a 202px width is because borders count on the outside of the width.
I hope the explanation made it clear to why it worked. Good luck! I tested this out in Google Chrome.
A solution compatible with any browser, no matter how old it is:
Center the table and put your list inside.
Example:
<table style="margin-left:auto; margin-right:auto;"><tr><td>
<ul>
<li>Line1</li>
<li>Line test 2</li>
<li>Line long for test</li>
</ul>
</td></tr></table>