views:

154

answers:

4

While creating GUIs I've come across the "double margin" problem several times, where two elements have the same margin defined and end up being spaced twice as far apart as I intended.

One solution I use is to define the margin on only some sides of the element (for example, only on the top if I expect elements to be stacked vertically), but then I'm missing a bottom margin for the last element.

How do you deal with this problem? Examples in any language or framework are welcome.

+1  A: 

Despite the tag, it really does depend on the language and its GUI manager. Some allow you to set arbitrary spacing (like you're talking about).

My main exposure to this problem is in CSS because that's what I do day in, day out. I keep things simple: float block items left and only use left-hand margins on those items.

This requires you to set widths and doesn't work for everything (relative/% widths being the most obvious)... But it does work for me for a lot of the time. IE6 can throw spanners in my day because of its built-in double-margin rendering bug but it's usually simply fixed.

For those not sure about what the question is asking: imaging you a box you want to show on the screen. You want to say that boxes should have a margin of 30px around them. Now imagine you have two boxes to show next to each other. If you set an absolute 30px margin, those boxes would be 60px apart. Solve for x.

Oli
A: 

Internet Explorer doesn't collapse margins correctly all the time, so while we wait for IE7 usage to shrink the safer method is to use padding instead when possible.

If you set margin or padding on only some sides of the elements, you can use padding in the parent element to get the right distance to the last elements.

Guffa
A: 

I have two tactics for dealing with this:

1) Give the elements a one-sided padding and then make up for the first/last element discrepancy in the CSS for the container. E.g.:

<ul>
   <li>Cats</li>
   <li>Dogs</li>
   <li>Birds</li>
</ul>

ul { padding-bottom: 10px; }
ul li { padding-top: 10px; }

2) Add a class to the first/last element in the HTML or using a jQuery (or other framework) selector. E.g.:

<ul>
   <li class="first">Cats</li>
   <li>Dogs</li>
   <li class="last">Birds</li>
</ul>

ul { padding-bottom: 10px; }
    ul li { padding-top: 10px; }

$(document).ready(function(){
   $('ul li:last').addClass('last');
});
skybondsor
Obviously, this is an html/css/javascript-fueled perspective!
skybondsor
+1  A: 

Some languages/frameworks allow you to set margins in a 'layout' itself, which wouldn't have the issue of double margins when you set the margin on a per-widget basis.

For example, with QLayout in Qt you can simply use setSpacing(int size); on the layout object to set the spacing between widgets, and higher level layouts (like QGridLayout) allow you to do more complex things. In Qt, if you also wanted extra space around the edge of the parent widget (which could be a top level window), you can set that with a call to setContentsMargins(int left, int top, int right, int bottom); on that widget.

I'd imagine most GUI toolkits would have similar constructs.

Kitsune
This is a good solution to the problem, if the language/toolkit supports it.
emddudley