This might be a very simple question, but I can't get it working.
All I want is to have 2 boxes (left and right), both should take 50% of the space and they should show up next to each other.
My current css looks like this:
#left {
text-align: right;
width: 50%;
padding-right: 10%;
float: left;
}
#right {
width: 50%;
text-align: left;
padding-left: 10%;
}
#footer {
clear: both;
}
The HTML looks like this:
<div id='left'>
<h1>Left</h1>
<ul>
<li>Some Listing</li>
</ul>
</div>
<div id='right'>
<h1>Stuff</h1>
<p>
Stuff right
</p>
</div>
<div id='footer'>
</div>
As I said, it isn't working. But I think it should be clear what it should do.
You have to take the padding and margins into account. Putting 50% on each <div> while specifying any padding other than 0, will cause the <div> to wrap. Try removing the padding on the <div>, or reducing the width from 50% to, say, 45% and see what it looks like.
There are 2 things I needed to do to make it work:
1) The width + padding of each div must only add up to 50%. Otherwise, in your original code, they add up to 60%, and both add up to 120%, and they can't fit in the 100% width of the body.
2) I have to also float the second div to the left, or make both div overflow: hidden
(i am still looking into why step 2 is needed)
A full style reset will make sure you avoid falling foul of anything that XSaint mentioned. Margins, Borders and padding will affect this.
So you should make sure that these elements have:
div {
margin: 0;
padding: 0;
border: 0;
}
If you wish to have padding and borders, be sure to reduce the width of the elements accordingly.
One document worth referencing is the box model, that picture is worth 1000 words:
http://www.w3.org/TR/CSS2/box.html
In the note below that diagram, it states that the width affects the width of the content box, not the padded, bordered or margined box. That is the box inside all the others.
you may either do what XSaint32 has suggested or remove the padding from the #left div and put another div #context with the padding inside the #left div. i.e)
Xsaint and Danny Staple gave the best answers so far.
Just complementing their answers, you can also use a property named "box-sizing" in order to ensure correct calculations.
I even recommend adding this property to your (and everybody else) CSS reset, hence Webkit, IE, Opera and Mozilla tends to use different box models.
Related
Problem
I have a header with the basic HTML structure
<div id="header">
<div id="logo"></div>
<div id="navigation"></div>
<div id="userInfo"></div>
<div class="headRight"></div>
<div id="callCenter" class="headRight"></div>
</div>
I cannot change the HTML. Currently it is laid out with floats, and navigation was aligned to the bottom of the header using padding-top. However, it only works when userInfo is 2 lines, and it can be 3 or 4.
What I need to do
Using only CSS, align navigation to the bottom for all nav heights while maintaining the original layout.
What I've tried
Half a dozen stack overflow solutions including the classics position:absolute and vertical-align:bottom on parent. (The former breaks the document flow, and the latter seems not to work because other elements get in the way.)
The fiddle
Cleaned fiddle best I could, but inspect will probably still be easiest.
https://jsfiddle.net/ohrhe4u5/1/
Notes:
The tabs should just touch the bottom of the header.
callCenter is misaligned in this example as well, but you can ignore. It's much lower priority.
New fiddle
I changed header, logo, and navigation to display:inline-block, allowed userInfo to float right, gave the nave extra height to make sure there's always room, and absolute positioned the headRight items.
That leaves me with this. A little janky due to the absolute positioning and forcing the nav height larger. Any better ideas?
https://jsfiddle.net/ohrhe4u5/2/
I generally dislike float for positioning where i can help it (this is a personal preference because i find it sometimes painfully unpredictable), as such, using a combination of position:absolute, min-height and margin i believe i have recreated what you're after.
Basically this solution works by position:absolute'ing the elements that we have some idea of consistent sizes of (the logo and the navigation), then have the header element take its height from the user data and links on the right. We add a min-height to the header element though so that should the user data be reduced to 2 lines, the height is still enough to accommodate the absolutely positioned elements (given they no longer affect the height of the header element by being absolute).
JSFIDDLE
CSS
/* new parts of the css */
#header {
min-height:112px; /* in case user data is made smaller */
padding:10px 10px 0 20px;
position:relative;
}
#logo {
width: 210px;
position:absolute;
top:50%;
width:210px;
height:62px;
left:20px;
margin-top:-32px;
z-index:1; /* bring logo above the user data */
}
#navigation {
position:absolute;
bottom:0;
left:210px;
font-size: 20px;
height: 40px;
z-index: 1; /* bring navigation above the user data*/
}
#userInfo table{
margin:0 0 0 auto;
}
.headRight{
text-align: right;
padding-bottom: 0.2em;
}
I created a DIV which on the right top corner must have two links (Menu and Options):
<div class="Clear">
<ul class="Clear">
<li><a>Menu</a></li>
<li><a>Options</a></li>
</ul>
<h2>Header</h2>
<p>Text</p>
</div>
To align the ul on the right I used "float: right".
The online example is in: http://jsfiddle.net/y2hhm/8/
Each link text will be replace by an icon image using background-image.
It looks fine on the first DIV. But on the second the table is pushed down.
I also tried "position:absolute" but it makes hard to align it on the right.
Does anyone knows how to make the Menu/Options list look the same in both?
EDIT:
Tables have default styles applied to them by the browser. To solve this specific problem on your second fiddle (yellow-orange one), you need to set the table's border-spacing: 0;.
Perhaps you can turn to CSS resets if these pre-set properties annoy you.
-----------------------------
I think you might have overlooked the fact that ul's and ol's have a default styling applied to them, which differs from browser to browser. Some might set padding, others margin (I haven't tested it myself).
All you need to do is add this to your CSS: (tested and working in your fiddle)
ul {
padding: 0;
margin: 0;
}
Your h2 element and table element respond differently to the float of the ul. If you set your h2 CSS to clear:both the margin from the ul will also impact it. The table element for some reason considers the margin of your floated element (I can't explain why).
NB: // are not valid CSS comments. Use /* */.
If you absolutely want the menu to be removed from the flow, set the parent div to position: relative; and the ul to position: absolute; margin-left: 80%; margin-top: 0%;.
The disadvantage of this method is that you have to approximately estimate the menu's length. (in this case I took 80% margin, so estimated at 20%) . Given that your divs have dynamic widths, it will also cause the menu to float outside of the table when the viewport is too small. You can prevent this by setting the div to overflow: hidden;, but overall...
If this were a problem I had to solve, I would simply stick with the float: right; and leave some whitespace between the menu and the next elements...
I am trying to create this effect by using HTML in UIWebView control of iOS. The goal is to create the effect of progress bar on the listing. So far I tried this but as you see, by adding a padding on diV makes everything messed up. How can I achieve similar effect? I have no issue of using table but seems that would be more difficult.
Thanks
Why not just use nested divs and give the inner Div a percentage width.
<div><div class="inner"></div></div>
And CSS:
div {
background-color: blue;
height: 30px;
}
.inner {
width: 50%;
background-color: skyblue;
}
Since divs are block level element they have a 100% width by default so you don't need to explicitly specify it for the outer div if that is sufficient.
Another possibility would be to use a background gradient and just move alter the background-position.
In the code you supplied you have this div:
<div style='position:absolute;left:0%; background-color: hsl(30,100%,59%);width:30%;z-index:10;'> </div>
Just add "top: 0px;" to it so that it becomes
<div style='position:absolute;left:0%; top: 0px; background-color: hsl(30,100%,59%);width:30%;z-index:10;'> </div>
And it will look correct.
Edit: And then give the LI elements position: relative to make it work with multiple elements. See http://jsfiddle.net/tFn78/9
Another version which is a bit cleaner: http://jsfiddle.net/v7zNn/ and adjusts to variable height of the title.
I have a problem with my website and how it appears in some browsers:
http://www.karentiede.com
In Firefox 2.0 and many other browsers, the "content" column overflows to the left and appears on top of the decorative border, making some of the content unreadable.
One Q&A in here suggested that making all the pages HTML 4.01 Strict DOCTYPE might help make all browsers work the same, but that question was the reverse-worked in Firefox and didn't work in IE. Is there another/different fix I should try?
From the CSS:
.column2 {
float: right;
width: 80%;
}
From any of the pages that act up:
<body id="schedule_toc">
<div id="col1_schedule_toc">
<div class="column2">
When I check the site in http://www.browsershots.org, it looks bad on initial display in a lot of the browsers. I've had one or three (probably Firefox) readers tell me they couldn't see the text and I suspect they were probably more sophisticated users than I am a CSS-writer.
I took a look at the page and the problem only appears when you re-size the page.
The problem is your right div is 80% so when the screen becomes smaller and ratios change and that 80% then overlaps into your left background.
Take a look at http://www.dynamicdrive.com/style/layouts/item/css-liquid-layout-21-fixed-fluid/ to see how to set up a "static-fluid" layout.
The reason why this is happening, it seems, is because the image (floated left) isn't the height of the entire page. So, when the page isn't wide enough to accommodate both the image and the text next to each other, the text breaks to the next available whitespace.
Try floating both elements to the left, and apply a left-margin equal to the width of the "decorative" column to column2 as such:
.column1 { float: left; width: 125px; }
.column2 { float: left; margin-left: 125px; }
.clear { clear: both; }
You'll need a clearing div below both elements:
<div class="column1">...</div>
<div class="column2">...</div>
<div class="clear"></div>
The problem is definitely ratios, as pointed out by savageguy. If what you are wanting is a fixed-width left column with a variable width right (main) column then you could use this (not tested but should work):
#col1_schedule_toc {
width: 175px;
float: left;
}
.column2 {
float: right;
width: 100%;
}
EDIT: Incidentally, I noticed that (at least on the page I looked at) you also aren't closing the left column before you open the right, so technically the right column is inside the left, which will cause issues with my suggested fix. So you also need to move the closing div for col 1 so that it's above the opening div for col 2.
EDIT 2: Plus, as pointed out by Plan B, you'll also need a clearing div beneath both elements to prevent the parent (container) div from collapsing:
div.clear {
clear: both;
font-size: 1px;
line-height: 1px;
overflow: hidden;
}
In addition to savageguy's right-on-point advice, the image you have in the page (your picture, etc.) to the left is a fixed width. This is why, when the browser is re-sized, that 80% suddenly becomes too wide.
On column2, setting a left margin of the width of the image + the amount of separation you want (for example, 160 should work, but you can play with it), then making the width of the column2 100% (of the remaining width) should prevent your overlap.
[Edit: Plan B also offers a very robust solution.)
Here's a question that's been haunting me for a year now. The root question is how do I set the size of an element relative to its parent so that it is inset by N pixels from every edge? Setting the width would be nice, but you don't know the width of the parent, and you want the elements to resize with the window. (You don't want to use percents because you need a specific number of pixels.)
Edit
I also need to prevent the content (or lack of content) from stretching or shrinking both elements. First answer I got was to use padding on the parent, which would work great. I want the parent to be exactly 25% wide, and exactly the same height as the browser client area, without the child being able to push it and get a scroll bar.
/Edit
I tried solving this problem using {top:Npx;left:Npx;bottom:Npx;right:Npx;} but it only works in certain browsers.
I could potentially write some javascript with jquery to fix all elements with every page resize, but I'm not real happy with that solution. (What if I want the top offset by 10px but the bottom only 5px? It gets complicated.)
What I'd like to know is either how to solve this in a cross-browser way, or some list of browsers which allow the easy CSS solution. Maybe someone out there has a trick that makes this easy.
The The CSS Box model might provide insight for you, but my guess is that you're not going to achieve pixel-perfect layout with CSS alone.
If I understand correctly, you want the parent to be 25% wide and exactly the height of the browser display area. Then you want the child to be 25% - 2n pixels wide and 100%-2n pixels in height with n pixels surrounding the child. No current CSS specification includes support these types of calculations (although IE5, IE6, and IE7 have non-standard support for CSS expressions and IE8 is dropping support for CSS expressions in IE8-standards mode).
You can force the parent to 100% of the browser area and 25% wide, but you cannot stretch the child's height to pixel perfection with this...
<style type="text/css">
html { height: 100%; }
body { font: normal 11px verdana; height: 100%; }
#one { background-color:gray; float:left; height:100%; padding:5px; width:25%; }
#two { height: 100%; background-color:pink;}
</style>
</head>
<body>
<div id="one">
<div id="two">
<p>content ... content ... content</p>
</div>
</div>
...but a horizontal scrollbar will appear. Also, if the content is squeezed, the parent background will not extend past 100%. This is perhaps the padding example you presented in the question itself.
You can achieve the illusion that you're seeking through images and additional divs, but CSS alone, I don't believe, can achieve pixel perfection with that height requirement in place.
If you are only concerned with horizontal spacing, then you can make all child block elements within a parent block element "inset" by a certain amount by giving the parent element padding. You can make a single child block element within a parent block element "inset" by giving the element margins. If you use the latter approach, you may need to set a border or slight padding on the parent element to prevent margin collapsing.
If you are concerned with vertical spacing as well, then you need to use positioning. The parent element needs to be positioned; if you don't want to move it anywhere, then use position: relative and don't bother setting top or left; it will remain where it is. Then you use absolute positioning on the child element, and set top, right, bottom and left relative to the edges of the parent element.
For example:
#outer {
width: 10em;
height: 10em;
background: red;
position: relative;
}
#inner {
background: white;
position: absolute;
top: 1em;
left: 1em;
right: 1em;
bottom: 1em;
}
If you want to avoid content from expanding the width of an element, then you should use the overflow property, for example, overflow: auto.
Simply apply some padding to the parent element, and no width on the child element. Assuming they're both display:block, that should work fine.
Or go the other way around: set the margin of the child-element.
Floatutorial is a great resource for stuff like this.
Try this:
.parent {padding:Npx; display:block;}
.child {width:100%; display:block;}
It should have an Npx space on all sides, stretching to fill the parent element.
EDIT:
Of course, on the parent, you could also use
{padding-top:Mpx; padding-bottom:Npx; padding-right:Xpx; padding-left:Ypx;}