Here's a puzzle. Basic page, one element:
http://jsfiddle.net/PZj6t/
HTML:
<div id="container"></div>
CSS:
body, html {
height: 100%;
margin: 0;
padding: 0;
background-color: black;
}
#container {
position: relative;
margin: 0 auto;
width: 400px;
height: 100%;
background-color: #666;
}
That one looks how I want, with the #container neatly flush to the top. But when I add a nested element:
http://jsfiddle.net/PZj6t/1/
HTML:
<div id="container">
<nav id="topnav"></nav>
</div>
CSS (new):
#topnav {
width: 100%;
height: 40px;
margin: 30px 0;
background-color: red;
}
The container jumps down. It seems that the margin-top from #topnav is somehow being passed to the container, and now the page has a scrollbar I don't want. (I'm testing in Chrome.) How do I prevent this?
(As a further mystery, if I add border: 1px solid white; to the #container's CSS, the jump disappears. Which would be fine, except that also adds two pixels worth of undesirable scroll to the page.)
This is due to a feature of CSS called margin collapsing. If there is no padding or border on a parent element, the parent and its child's margins "collapse" to the greater value of the two and is essentially applied to the parent.
For your situation, I would suggest simply adding an additional inner wrap within the container, and throwing some padding on it to simulate the margin effect you're looking for: http://jsfiddle.net/PZj6t/3/
Anything within the #inner div or below should behave as you expect, as margins only collapse when they are at the edge of their parent (and no padding or borders are present).
display:inline-block;
On Your nav element appears will fix this. Its to do with margin-collapsing see here for more detail.
Jblasco is correct, this is a neater solution though: http://jsfiddle.net/PZj6t/4/
#container {
position: relative;
margin: -1px auto 0;
width: 400px;
height: 100%;
padding-top:1px;
background-color: #666;
}
#topnav {
width: 100%;
height: 40px;
margin: 29px 0 30px;
background-color: red;
}
#container {
margin: 0 auto;
width: 400px;
height: 100%;
background-color: #666;
border:1px solid;
}
http://jsfiddle.net/PZj6t/12/
Update:
http://jsfiddle.net/PZj6t/1/
apply display:inline-block; on both container and topnav
Related
I want to create a side navigation, which should be full height of the browser window. Each menu item (DT) has additional element (DD) where I will put some filters later on. When I click a menu item, its additional element opens, and pushes all other closed items to bottom of the menu. The problem is that once it's opened the size of the parent DL exceeds the screen instead of staying full height.
Could you please suggest a solution to resolve the issue.
HTML
<dl>
<dt>Item</dt>
<dd class="active">Filters</dd>
<dt>Item</dt>
<dd>Filters</dd>
</dl>
CSS
body, html{
height: 100%;
padding: 0;
margin: 0;
}
dl{
display: block;
margin: 0;
width: 200px;
background: grey;
height: 100% !important;
}
dt{
background: #ccc;
padding: 5px 10px;
}
dd{
display: none;
margin: 10px;
}
dd.active{
display: block;
height: 100%;
}
JSFIDDLE
Please do remove dd.active { height: 100% } and check it...
Think this will help you.
The !important declaration is unnecessary. If you know the number of menu items (e.g. 2) and their height (e.g. 40px), maybe this could help:
dd.active {
height: calc(100% - 80px);
}
An alternative (and equally inelegant) solution would be to use tables. Setting the table height to 100% will automatically stretch the rows with unspecified height to fill the remaining space (so only the rows that correspond to the menu items should have their height specified).
My solution:
<dl>
<dt>Item</dt>
<dd class="active">Filters</dd>
<dt>Item</dt>
<dd>Filters</dd>
</dl>
body, html{
height: 100%;
padding: 0;
margin: 0;
}
dl{
display: table; /*changed*/
margin: 0;
width: 200px;
background: grey;
height: 100% !important;
}
dt{
background: #ccc;
padding: 5px 10px;
}
dd{
display: none;
margin: 10px;
}
dd.active{
display: table-row; /*changed*/
height: 100%;
}
UPDATED JSFIDDLE
I'm working on making a simple photography website for someone, and I'm stuck trying to figure out the horizontal positioning. I have the margins set to auto on left/right, and the position set on relative. It should go in the middle, shouldn't it?
I have a picture slideshow that I want in the middle, and then there's the navigation that I have on the right side. The nav is in the right place, but the slideshow is stuck overlapping with the navigation and I can't figure out how to get it to center horizontally.
Here's the nav:
#nav {
position: fixed;
top: 22%;
right: 1%;
text-align: center;
}
The rogue slider:
#slider {
background:#000;
border:5px solid #eaeaea;
box-shadow:1px 1px 5px rgba(0,0,0,0.7);
height:400px;
width:600px;
margin: 100px auto 0;
overflow:visible;
position:relative;
}
The slider is contained in the wrapper div:
.wrapper {
height: 100%;
width: 55%;
margin-right: auto;
margin-left: auto;
background: #eaeaea;
padding-bottom: 150px;
}
What can be done to get this right?
If you need more info, you can take a look at the page and source code:
bwphotog.com
The child .container element is wider than its parent, .wrapper. If you remove the 960px width of the container it will be centralized.
Change your .container class to this
.container {
margin: 0 auto;
overflow: hidden;
/* width: 960px; */
}
I have this code:
<div style="margin: 0px; padding: 0px;">
<div style="border: 1px solid #aaaaaa; padding: 8px; width: 40%; top: 0; left: 0; margin-bottom: 10px; position: relative;">
....
</div>
<div style="border: 1px solid #aaaaaa; padding: 8px; width: 40%; top: 0; right: 0; margin-bottom: 10px; position: relative;">
....
</div>
</div>
My end goal is to have two boxes each sharing 50% of width with margin in-between them.
Instead they are shown below each other which I do not want. They appear not to respect their designated position values. (I even set width to only 40% for both, so it was not an issue of all space used.)
For reference: I chose not to use float since I don't want them to realign underneath each another. I chose not to use table display since I would like IE7 compatibility. I have never done much CSS, so my question is hopefully simple to solve (crossing fingers)
As others have mentioned, you are missing either float: left (remove top/right/bottom/left values) or position: absolute.
If you want width to be fluid but padding to be fixed (or vice-versa), then you need width: 50% with box-sizing: border-box. This makes the padding part of that 50%.
If you want width and padding to both be fluid, this trick isn't necessary. Just use percentage measurements for both so the total is 50% (e.g., width: 48%; padding: 1%).
You really just need to float your inner divs, to make it all a bit easier, add box-sizing attribute.
Lets say having this HTML:
<div class="box"></div>
<div class="box"></div>
And then just add something like this:
.box {
float: left;
width: calc(50% - 5px);
margin-right: 5px;
padding: 8px;
border: 1px solid #aaaaaa;
box-sizing: border-box;
}
.box:last-child {
margin: 0 0 0 5px;
}
By using calc(), you have to subtract the margin of each .box. And the use of box-sizing property is to avoid that border and padding were added to the width, which is the default behavior on the CSS box model. You should have a look on caniuse to see compatibilities and the use of vendor prefixes.
There're really more than a way to do the same thing. But I think this one is a very solid way to achieve your goal.
http://jsfiddle.net/gVwar/
I believe this fiddle solves your problem. Error being you didn't float the divs.
Block level elements will never be placed adjacent to one another when not floated, unless when positioned absolutely or fixed.
Note: If you want to position your elements with top, left & right properties, you'll have to set their position: absolute.
Are you looking for something like this?
Check the demo out at the link above.
<div class="box1">X</div>
<div class="box2">X</div>
CSS
* {
margin: 0;
padding: 0;
}
.box1 {
width: 48%;
background-color: white;
border:1px solid black;
}
.box2 {
width: 48%;
background-color: white;
border:1px solid black;
}
.box1, .box2 {
display: inline-block;
margin: auto;
}
#media screen and (max-width: 300px){
.box1, .box2 {
width: 46%;
float: right;
display: inline-block;
margin-right: 1%
}
I have a parent div with two child div(header and body), I want to set header position fixed on top and only body should scroll.
HTML
<div class="box">
<div class="header">Header</div>
<div class="body">Body</div>
CSS
.box {
height: 300px;
border: 1px solid #333;
overflow: auto;
}
.header {
position: absolute;
width: 100%;
height: 100px;
background: #ccc;
}
.body {
height: 300px;
background: #999;
margin-top: 101px;
}
I found the header div overlaps parent div's scroll bar. I can't set parent div position as relative because I want header position fixed. I can't set header position as 'fixed' because this content avilable somewhere middle of the page.
How can I avoid absolute positioned child not overlaps parent's scroll bar?
Find jsfiddle: http://jsfiddle.net/T43eV/1/
The overflow property should be set on the .body, not .box, as such : http://jsfiddle.net/T43eV/8/
Does this help?
.box { position:relative; }
EDIT: There isn't any need to use absolute anyway, remove that and put overflow:auto on .body.
jsFiddle
.box {
height: 300px;
border: 1px solid #333;
}
.header {
width: 100%;
height: 100px;
background: #ccc;
}
.body {
height: 200px;
background: #999;
width:100%;
overflow: auto;
}
EDIT: I don't think you can do this consistently across platforms. You could kind of do it by setting your right property on .header to be as large at the scrollbar, but the size of the scrollbar is bound to the operating system and isn't a single size.
You could look into an iframe as that will create a page within your page, scrollbar and all.
If it helps set z-index:-1 in .header and the header will not overlap the scroll bar.
Here is the working fiddle:
http://jsfiddle.net/T43eV/28/
One way of doing it would be by using a sticky position. This will keep the header inside the scrollable div but won't make it overlap the scroll (or get behind the scroll if you set a lower z-index)
.box {
height: 300px;
border: 1px solid #333;
overflow: auto;
}
.header {
position: sticky;
top:0;
height: 100px;
margin-bottom:-100px;
background: #ccc;
}
.body {
height: 300px;
background: #999;
margin-top: 101px;
}
However this is not supported by internet explorer
I am trying to vertically center one div (containing a search bar) inside another (a top banner). I was under the impression that to do so you did the following:
#banner {
height: 35px;
width: 100%;
}
#searchbar {
height: 15px;
position: relative;
top: 50%;
margin-top: -7.5px; /* half of the height */
}
This works fine until you add the margin-top at which point it is applied to the #banner as well.
Is there an alternative way to do this, or am I just doing it wrong?
Here's a jsFiddle of my actual code.
I use line-height with the value being the same as height of parent div.
As seen here: http://jsfiddle.net/vkJ78/24/
CSS:
#banner {
background-color: #770E17;
height: 35px;
width: 100%;
border-bottom: 1px solid #333;
}
#src {
width: 300px;
height: 15px;
border: 1px solid #333;
padding: 3px;
}
#srcdiv {
width: 308px;
margin: 0px auto;
position: relative;
line-height: 35px;
}
EDIT: Per recommendation from NGLN, this will also fix horizontal centering, #srcdiv and #src having equal widths.
You have to add overflow: hidden to #banner. To clear the float, I guess.
Then, modify the negative margin to margin-top: -11px in #srcdiv (you have to sum the div height, the border, and the padding for the total height)
http://jsfiddle.net/vkJ78/1/
Give margin:0px and padding:0px and remove margin-top
body {
margin:0px;
padding:0px;
}