Blog Improve It

Margins on the HR tag: a case solved

Posted by Leandro Mello about 1 year ago.

Basically, the smack on the head that makes IE behave is display: block. After that, you can play with whichever margins you want on <hr />.

I am one of those who use the <hr /> tag to split sections. It’s semantically more coherent than dividing by styling the very divs’ borders, it looks better when you view the HTML without CSS, and all that stuff that’s been discussed a lot all around. I came to appreciate <hr />’s usefulness.

The fact, however, is that it’s a pain to style this tag. For each browser different attributes must be edited in order to achieve the same effect. With some working, the <hr /> gets the same look in every browser.

What really makes people all over forums pull their hair out is the damn margin that surrounds the <hr /> in IE. IE’s margin is stubborn, indestructible, uncontrollable, unstylable. Wherever I looked for, people gave in to adopting the margins, and more persistent designers even encased the <hr /> into a <div> to get the desired style. In other words, some gave up too easily, some took desperate measures and wouldn’t care to make things right.

One day, I stumbled upon two blog articles which came near to a solution. Neither of them solved the case by itself. But joining both, it worked! Tests confirmed that by mixing both theories I could attain any margin size I wanted, in every browser — even zero. But, in a very unfortunate turn, I never bookmarked such articles, nor have I saved my test files. A very looked-for answer, lost in such a silly way...

This article is about my specific case: I wanted to use <hr /> free from any nonsense divs, and with zero margin — even in IE. And, above all things, this article is all about leaving the answer somewhere safe and under everyone’s reach. Now that I’ve remembered the solution, I won’t lose it again.

“Smack that head”

After I’d lost track of those articles and weeks had passed by, all I could remember was that Internet Explorer needed a smack in the head: a completely unexpected, counter-intuitive attribute that would get it back to its senses. Basically, the smack on the head that makes IE behave is display: block. After that, you can play with whichever margins you want on <hr />.

Who figures. The <hr /> element is already a block. In every way it looks like a block element. Breaks line above, breaks line below, there’s nothing inline on it. And that seems to be why so many forums chase their tails for a solution: few would suspect that it is necessary to remind <hr /> that it’s actually a block. Saying display: block would be plain redundant and unnecessary. But damned IEvil demands it in order to realize “oh well, what do you know, it’s true...”.

How it happened to me:

On with my case. I wanted to add some <hr /> tags to Brazilian photographer Patricia Figueira’s site, as an experiment for future execution on her own site, as well as on our currently under development product, beonthe.net.

First step was to insert those tags in the spaces between header, main content and footer. Let’s see the HTML:

<div id="header">
  (header content)
</div>
<hr />
<div id="main_content">
  (main content)
</div>
<hr />
<div id="footer">
  (footer content)
</div>

And came out the gray line between divs. Like this:

Safari: Hr was added correctly.

Opera: Hr added correctly as well.

Firefox: Hr added correctly, just like the others.

Internet Explorer 7: Hr was added correctly, but had margins that pushed away the divs’ content.

Internet Explorer 6: Hr was added correctly, but also had the margins that pushed away the divs’ content.

(Boy, that’s IE...)

Once inserted, I wanted each divider line to have the following features:

First task is simple. In our style sheet application.css, we write:

hr {
  clear:      both;
}

Now comes the second task: cleaning the spaces the line generates on IE. But as said before and so many times on blogs all around, <hr />’s margin on IE is persistent, ruthless, stainless, shameless. People around have tried everything: margin: 0, padding: 0, line-height: 0, font-size: 0, even overflow: hidden. Going margin zero works with standard-compliant browsers, but nothing beats those gaps on IE.

So, in our application.css, let’s guarantee there’s no margin on the smart browsers:

hr {
  clear:      both;
  margin:     0;
}

The explanation for IE’s insistent margins is that IE renders the <hr /> tag with a vertical margin 7px longer than other browsers. In other words, if you write...

hr {
  clear:      both;
  margin:     7px 0;
}

... You get, in a decent browser, the expected: Exactly 7px up and 7px down.

And on IE, a sum of what you wrote plus its native margins: 14px up and 14px down (7 + 7).

“So”, I might think, “I just have to write negative margins for IE”. Would be the intuitive thing to do, but IE isn’t all about intuitiveness. It won’t work: the upper margins goes away, but the lower one never gives in! Check it out: The hr tag gets upper space = zero, but the lower space doubles: it takes the upper space’s 7px for itself!

The ace in the hole

Enter in our application.css the attribute display: block:

hr {
  clear:      both;
  margin:     0;
  display:    block;
}

This is the last attribute I’d think about to eliminate margins. I can’t explain why it works. It’s counter-intuitive. It’s redundant. It’s idiot. And nevertheless (or perhaps just because of this) it makes IE wake up.

Now we can think about that negative margin subject. Then we just correct application.css:

hr {
  clear:      both;
  margin:     -7px 0;
  display:    block;
}

And voilà! Finally, an <hr /> tag with no margins! Not an illusion! It IS possible to totally eliminate an hr’s margins on IE!

Conditional comment:

Problem with using negative margins is that standard-compliant browsers interpret them just as they are — negative: Negative margins on Safari.

We have to set a behavior for each type of browser.

I’m used to using conditional comments. Some say they are bad, but so far they have but helped me a lot.

On to the <head> on HTML. There we insert a condition for IE:

<!--[if IE]>
  <link href="/stylesheets/application_ie.css" media="all" rel="stylesheet" type="text/css" />
<![endif]-->

It’s purpose is to call a style sheet with rules exclusively for Internet Explorer: application_ie.css.

In this new application_ie.css style sheet, we apply the negative margins we had up to now:

hr {
  margin:     -7px 0;
}

There you are. This is the only rule that distinguishes the <hr /> tag on smart browsers and on Internet Explorer. Now we can go back to application.css and make our margins go zero:

hr {
  clear:      both;
  margin:     0;
  display:    block;
}

And the result is: consensus! On the smart browsers: (Appearance of hr on Safari. It&rsquos the same as on IE!)

... and on IE: (Appearance of hr on IE6. Now every browser’s hr has got the same look.)

Finishing touches

Only the third task’s left, which is to make those lines invisible. This is easy with visibility: hidden:

hr {
  clear:      both;
  margin:     0;
  display:    block;
  visibility: hidden;
}

Which renders the <hr /> invisible, but still taking the room it has been taking before, in a way there’s a 2 pixel gap between the header and the main content: The hr is now gone, but there is still a gap where the hr was before. We have to get rid of it.

Note: Using display: none is useless in this case, because it cancels the clear: both attribute. And we want it to break the floats. In this case, better stick with visibility: hidden.

On the decent browsers, this gap is due to border width. 1px borders around a zero height element result in a 2px total height. A border attribute should do it:

hr {
  clear:      both;
  margin:     0;
  display:    block;
  visibility: hidden;
  border:     none;
}

The gap is now gone on Safari and Opera. But Firefox and IE need a little further push. Remind them the element’s height must be null:

hr {
  clear:      both;
  margin:     0;
  display:    block;
  visibility: hidden;
  border:     none;
  height:     0;
}

Firefox now is okay. But on IE, the gap, instead of disappearing, got reduced to 1px (boy, that’s IE...). That’s because on IE’s <hr /> the borders aren’t defined by the border, but instead by the color (have I mentioned IE isn’t all about intuitiveness?). As one’s color can’t just go “zero” to make the gap go, the way left is to tweak the margins we have on application_ie.css, adding 1px above or below:

hr {
  margin:     -8px 0 -7px 0;
}

And there you have the final result: On all browsers, an invisible divider line with no margins. Mission complete.

Conclusion

This was my very specific case involving the <hr /> tag. If you are one of those people who pulled your hair out because of IE’s stubborn margins, know that there’s a solution. You don’t need to adapt you precious layout to fit the margins, nor you have to enclose the tag within a <div> only for it. Best practices, now!

I hope I have helped relieve your pain in the neck. Now the answer is right here, for the whole world. Soon you’ll see it in action at Patricia Figueira’s site and at beonthe.net. But if this article doesn’t solve your particular case, write me. Let’s think together of solutions for taming <hr /> — and maybe, just maybe, Internet Explorer itself.

Tags  | 4 comments

Where do rants come from?

Posted by Vinícius Teles about 1 year ago.

Have you ever realized how aggressive people tend to be on the net? You probably have. Specially if you're used to participate in online forums. And who isn't?

Rants keep popping at different points quite often. Does it reflect a behavior that is also present in the physical world? Do people engage in rants as often in the physical world as they do on the net?

I don't think so. And most of all, I think the way people approach those rants online are far more violent than the they do in the fewer occasions when they participate in physical world rants. Why is that so?

I believe there are at least two components to the answer. The first one is the nature of the communication itself. The second is the nature of the relationships.

The nature of communication

When we write, we activate different pathways in our brain compared to the ones we use when we speak. This difference seems to influence significantly the message we're trying to convey and most of all, the way we go about it. To understand more about it, check out the excellent Pragmatic Thinking and Learning.

Have you ever caught yourself writing something to someone that you wouldn't say to that person? There you go. It seems to me that we're more sincere when we write. It's as if the act of writing itself opened a window in our soul that allows our real thoughts to flow through. At first sight this would be a good thing. But when it comes to online communications this can be pretty harmful.

Messages written on a paper or online aren't effective ways to convey emotions. This means that identifying the emotional state of the author of the message is an exercise of guessing. A text that looks as if it's been written by a very angry person might have been written by someone who's not angry at all and vice-versa.

Overtime I've learned, the hard way, to not trust my judgement when reading online messages. I should always do my best not to try to guess the emotional state of the authors of the messages I receive. I've been involved in so many problems because of misunderstood emails that I began to use electronic messages much more carefully.

There's one more problem associated with the medium of communication. And this is more of an internet problem. It's easy and fast to communicate on the net. Although we can claim this is good in so many ways, it's also dangerous.

When we write an email, all too often we press the send button without reviewing the message and giving ourselves some time to thing and reflect on what we've just written. This is really bad. Specially because we're opening our souls and being maybe too much honest. It's not to say that honesty is a bad thing. It's just that sometimes, some messages need to be crafted more carefully, specially if the content is somehow sensitive. In our hush we forget to apply some filters that might contribute to the proper understanding of our intents. The funny thing is that if we were to say the same thing to the same person we would probably have filtered many parts or just been careful with the way we talk.

The nature of relationships

The second reason why I think rants arise have to do with the fact that people communicating online often don't know each other personally. And that can make a huge difference.

Take the case of DHH, creator of Ruby on Rails. People tend to create all sorts of bad images of him based on his writings on the net. I had the chance to talk to him in Portland and in Chicago a few months ago. What I realized then is that he's actually a very nice guy. He was very kind to me and anyone else who would talk to him. So I'd say that DHH in person is very different from who we think he is considering only his online "version". As a matter of fact this kind of realization has also come to me in many different occasions when I would have the opportunity to meet somebody that I only communicated with on the net.

Conferences are really great in this sense and thats the part that I enjoy the most. You get a chance to meet people and get to know who they really are. Most of the time I find out they're much nicer in person than I would have expected.

After meeting some people in conferences I would never think of them in the same way again. I always become more understanding and forgiving about their messages online. Since the messages can't erase the fact that I know that person and I know he or she is better than their messages would make me think of them.

Conclusion

To wrap it up, don't give too much credit for your interpretation of the emotional state of the author of a message. Be very suspicious of it. Also, try to pay attention to your writing and even better, if you have something controversial to communicate try to say it in person or just make a phone call. And finally go to conferences and try to meet people and get to know who they really are. By the way, Rails Summit Latin America will take place a few weeks from now. It will be a great place to meet people that you probably only know online. You'll probably be surprised once you meet them in person!

Tags  | 1 comment