Jump to content

Margin And Padding, In Theory?


MGmirkin
 Share

Recommended Posts

So, I'm relatively new to CSS, taught myself in a weekend a couple weeks ago, but am having some implementation problems... Who isn't? :) And can you help?Here's the code I'm working with in one of the "Try It Now" boxes from the CSS tutorial:

<html><head><style type="text/css">body { margin:0px; padding:10px;}div.container { width:100%; margin:0px; padding:0px; border:1px solid gray; line-height:125%;}div.header,div.footer { width:100% padding:5px; color:white; background-color:gray; clear:both; text-align:center;}div.left { float:left; width:40%; margin:0; /*padding:5px;*/}div.content { float:left; width:60%; /*border-left:1px solid gray;*/ /*padding:5px;*/}h1.header { padding:5px; margin:0px;}</style></head><body><div class="container"><div class="header"><h1 class="header">W3Schools.com</h1></div><div class="left"><p>"Never increase, beyond what is necessary, the number of entities required to explain anything." William of Ockham (1285-1349)</p></div><div class="content"><h2>Free Web Building Tutorials</h2><p>At W3Schools you will find all the Web-building tutorials you need,from basic HTML and XHTML to advanced XML, XSL, Multimedia and WAP.</p><p>W3Schools - The Largest Web Developers Site On The Net!</p></div><div class="footer">Copyright 1999-2005 by Refsnes Data.</div></div></body></html>
So, I'm noticing a frustrating trend when trying to use floated divs with percentage widths and things like borders, margins and padding. Trying to figure out if CSS is powerful; enough and flexible enough to do the relatively simple and stupid things I want it to do... So far I seem to keep hitting walls with the simplest things.So, here's my quandary: it seems like adding margins, padding or borders messes with positioning of floated objects using widths set to percentages. It's quite frustrating.The short and simple of it is that I'd LIKE to be able to have a container div with a specified width and then two or more child divs with widths that are a percentage of the parent div and all the child divs' total widths (including borders, margins and padding) would equal the width of the parent precisely.So far, whenever I add padding or margin to one of the child divs it appears to expand the size of that child div, causing the TOTAL width of all child divs to exceed 100% of the width of the parent div and thus cause the floating to foul up with one or more of the divs wrapping to the bottom of the page below all the other sibling divs within the parent.Is this typical? If so, how do I avoid it?Ideally, what I'd LIKE to be able to do is to specify the percentage widths as ABSOLUTE MAXIMA for those objects and have all the other "stuff" fit inside that maximum. That is to say, border, margin and padding specifications would SUBTRACT pixels from the absolute maximum width, rather than adding pixels to an ABSOLUTE MINIMUM width. If I specify one div at 40% and one div at 60%, those should be immutable quantities. MAXIMA for those objects, thus their total cannot exceed 100% of the parent object. So, if I have padding of 10px on the second child div, it SUBTRACTS those 10px on each side from the absolute maximum and then positions elements inside that div relative to the maximum minus the padding (for instance text-align:justify; would be justified within said padding 10px on each side from the absolute maximum of 60% of the parent div).Or likewise, if I specify border-style:solid; border-width:1px; border-color:black; padding:10px;margin:0px;I'd want it to render from outer to inner with the results being akin toouter div: 60% of parent divno marginborder of 1px within that 60% maximumpadding of 10px withing the 60% minus 1px-on-all-sidestext positioned inside that div relative to the 1-pix-on-all-sides border and additional 10px-on-all-sides padding (so the text would effectively be 11-px on all sides from the 60% maximum)Does that make sense, and is it possible within the scope of CSS? So far it seems like the padding, margin and border all add to the size of the div. So if I specify 40% / 60% it tends to add up more like 40% +1px +10px / 60% + 1 px + 10px, which obviously adds up to MORE THAN 100% of the container and leads to the aforementioned problems with wrapping.Are there some attributes I'm missing or is there some workaround for this, or is this simply me living in fantasy land? Personally, I think it should be possible to specify something PRECISELY like this, if CSS is as powerful a display and formatting tool as everyone claims it is.If at all possible, I'd prefer not to have to manually specify every pixel width for every element. I'd like the browser to do as much of the maths for me as possible using percentages.So, can I tell it not to exceed 40% and 60% of a container tag? Or will things like borders, margins and padding always EXTEND the object you've specified a percentage width for, making percentages fairly USELESS and defeating the purpose of their use?If this is something not currently within the standard, perhaps it's something that should be STRONGLY suggested for the next version?Any coder gurus run across this issue before and figured out a simple solution? Having things like margins and padding SUBTRACT from the total maximum width rather than adding to it?Hope that all made some kind of sense to someone out there.I'm thinking that maybe I could put yet another div inside the child div and not specify a % width, just the margin and/or padding of that div and then put the text in there. But that seems like a kludge and div overkill. There's got to be a simpler way? Know what I mean?Best,~MG
Link to comment
Share on other sites

In a standards-compliant browser, borders, margins, and padding are added to the initial definitions, whether that's in pixels or relative units. There is no way around this in 2010. When CSS 3 is fully implemented, a rudimentary calc() function will be added that will make your wish come true. But we're a few years away from that..The only exception (a small one that won't help you) applies to block-level elements (like divs) whose default width is the width of the window. Borders and padding are subtracted from the total width in that case.

Link to comment
Share on other sites

There is no way around this in 2010. When CSS 3 is fully implemented, a rudimentary calc() function will be added that will make your wish come true. But we're a few years away from that..
Drats! :)Hmm, would my kludge at least work, perhaps?That is to sayparent div-1st child div @ 40%--grandchild div with padding-2nd child div @ 60%--grandchild div with paddingBest,~MG
Link to comment
Share on other sites

Having played around with this for a bit, my kludge does seem to work pretty well, happily...

<html><head><style type="text/css">body {  margin:0px;  padding:0px;}div.Container {  height:100%;  width:100%;  margin:0px;  padding:0px;  background-color:yellow;}div.CDiv {  float:left;  margin:0px;  padding:0px;  background-color:green;  color:white;}div#CDiv1 {  width:40%;}div#CDiv2 {  width:60%;}div.GCDiv {  margin:5px;  padding:5px;  border-style:solid;  border-width:1px;  border-color:black;  background-color:blue;  color:white;  text-align:center;}</style></head><body><div class="Container">  <div class="CDiv" id="CDiv1">	<div class="GCDiv">	  40%	</div>  </div>  <div class="CDiv" id="CDiv2">	<div class="GCDiv">	  60%	</div>  </div></div></html>

http://w3schools.com/css/tryit.asp?filename=trycss_colorPaste the code here (replacing all else) and apply it... Seems I can get it working pretty well doing what I want using the extra grandchild divs in conjunction with some ID attributes on C (child) divs.And without specifying a % width on the GC (grandchild) divs, it seems to do the margin or padding with respect to the C (child) divs, which themselves are sized as percentages of the Container div.Guess it's a moderately elegant kludge.Now if the only border I put on the GC divs would combine into a SINGLE pixel width where they meet at the center rather than 2 pixels across (which looks tacky in my opinion)... Ahh CSS, how thou mockest my attempts to make an elegant page using elegant code. I suppose I'll have to manually specify the border on each side of one of the two GC divs to leave off the center side... And, no collapse-border:collapse; doesn't seem to do the trick. Don't think about suggesting I add display:table; to the GC divs, 'cause from what I can tell, having just tried that, it seems to make them behave like inline elements rather than block elements so the background color doesn't extend to the edges of the C divs. Grr... What's up with THAT Can can it be fixed? Meh, easier to just do this:

<html><head><style type="text/css">body {  margin:0px;  padding:0px 30px 0px 30px;}div.Container {  height:100%;  width:100%;  margin:0px auto 0px auto;  padding:0px;  background-color:yellow;}div.CDiv {  float:left;  margin:0px;  padding:0px;  background-color:green;  color:white;}div.GCDiv {  margin:0px;  padding:5px;  background-color:blue;  color:white;  text-align:center;}div#CDiv1 {  width:40%;}div#CDiv2 {  width:60%;}div#GCDiv1 {  /*margin:5px 0px 5px 5px;*/  border-style:solid;  border-width:1px 0px 1px 1px;  border-color:black;}div#GCDiv2 {  /*margin:5px 5px 5px 0px;*/  border-style:solid;  border-width:1px;  border-color:black;}</style></head><body><div class="Container">  <div class="CDiv" id="CDiv1">	<div class="GCDiv" id="GCDiv1">	  40%	</div>  </div>  <div class="CDiv" id="CDiv2">	<div class="GCDiv" id=GCDiv2>	  60%	</div>  </div></div></html>

There... I'm actually kind of proud of myself. Not too bad, right?Guess this makes me an extremely newbie CSS hacker, eh? Seeing as how I seem to have fixed my own problem. Albeit with a non-ideal solution, since no ideal solution currently exists. C'est la vie...

Edited by MGmirkin
Link to comment
Share on other sites

Adding a 0 border width to one side works pretty well. Be aware that you can also define border-sides individually. The following would also work:

border-right: 0

Using 0 like that clobbers all css properties, not just width. It's not better, really, but perhaps the intent is more obvious when you read it.I do not notice a doctype declaration in your HTML. Since you seem to have posted the whole document, I'll assume your document does not have one. This could lead to havoc. Please read why we use them.

Edited by Deirdre's Dad
Link to comment
Share on other sites

Adding a 0 border width to one side works pretty well. Be aware that you can also define border-sides individually. The following would also work:
border-right: 0

Using 0 like that clobbers all css properties, not just width. It's not better, really, but perhaps the intent is more obvious when you read it.I do not notice a doctype declaration in your HTML. Since you seem to have posted the whole document, I'll assume your document does not have one. This could lead to havoc. Please read why we use them.

Well, I was just playing around with the code in the tutorial pages' "Try It Now" feature so I could tinker with the code and see instant results of changes... Don't have a specific project for this, so no actual pages. In a real page, I guess I'd probably have to use a DTD declaration, though I'm not familiar enough with 'em yet to know the differences... Strict vs. transitional vs. ...? Will have to look into that more closely.Originally learned HTML c. 1997-2001, self-taught. Mostly used as a hobby. Just trying to play a little catch-up. :)Anyway, I think my solution in the second code example above worked rather well, at least it seem sto have rendered rather well in my copy of Firefox. :)And, yep, I did end up manually specifying the borders / margins of the grand child <div>s, per side.Best,~MG
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...