Category Archives: gotcha

CSS Selector behavior

Well, no matter how long you program CSS, you can get tripped up by the most basic of things. Today it was psuedo element selectors. I wanted to style the placeholder text of an element to be accessible. That meant I needed a darker color. So I did this:

color: #666;

And it didn’t work. And I couldn’t figure out why. So I looked again at the code I created, and started eliminating things. I was in chrome, and so I did this:

color: #666;

And it worked!

So I then I did this:

color: #666;

And it didn’t work. So then I looked at some code on a site that did work. And I saw that they did it like this:

color: #666;
color: #666;
color: #666;
color: #666;

And so I did the same. And it worked. And I scratched my head. And then I stumbled across this explanation (scroll down to Chris Coyer’s comment).

Lightbulb! Doh!

We are so used to being able to list styles with browser prefixes, one after another, and ones that the browser doesn’t recognize get ignored. But this is not the same with element selectors in a group.

It was a trippy morning.

greasemonkey userscript issue

It took a lot of googling, but I finally figured out why some of my greasemonkey scripts weren’t respecting the @include directives I had in my UserScript section.

Greasemonkey doesn’t like leading spaces in the UserScript section. So watch for tabbed formatting and the like, and keep your directives flush left. Like so:

// ==UserScript==
// @name             My Script
// @description      A greasemonkey script I wrote
// @include*
// @grant            none
// ==/UserScript==
script code goes here....

As you can see, it’s okay to use formatting after the double slashes.

But don’t do this!

// ==UserScript==
   // @name         My Script
// ==/UserScript==

Hope this helps someone else!

Who invented margin collapsing, anyway?

Margin collapsing. I don’t like it.

I suppose it’s okay in some instances, like for paragraphs. But maybe it could have been kept to p tags. Or somehow the rules could be clearer. I don’t know. Something like that.

I like things to make sense. Margin collapsing doesn’t always make sense to me. And sometimes it turns into margin expanding.

When it hits me unexpectedly at the top of a UI, where more than just the element I gave a margin to gets a margin, this is the trick I pull out of my sleeve. I put margin-top:-1px;padding-top:1px on the parent element.

Okay, that fixes vertical margin-collapsing along the tops of elements. What about horizontal margin collapsing along the sides. Is there such a thing?

Yup, there is (maybe not officially). I ran into that today, too.

So, I have this layout where the left and right columns are floated and a defined width, and the center column is allowed to take up the rest of the room. It was a good way to do it at the time, where the UI was flexible enough to accommodate 1, 2 or 3-column layouts and older browsers. Now I am re-skinning it with just CSS. And the center column sets a new block formatting context.  And I want a margin on it. I could see it in Firebug. The margin I added to the center column was sitting behind the floated left column.

So I added a right margin to the left column instead and the margin showed up. Woo hoo! However, it has occurred to me that I’m not exactly sure why. I think the answer must be in the W3C Visual Formatting spec, but I can’t find it.

But it’s late, the end of the day, and I’m not going to sweat it right now. I’m just going to document this so I don’t forget it later.

Put advanced pseudo class style definitions on their own line

In Internet Explorer 8, if you list a couple of style declarations together and a pseudo class it doesn’t recognize is in that list, it won’t apply the styles from the declarations it does understand. For example:

td:last-child, td.last{border-right:1px solid gray}

In the above example, even if you have a td with a class of last assigned to it, IE8 won’t apply the border style because it chokes on td:last-child. You should do this instead:

td:last-child{border-right:1px solid gray}
td.last{border-right:1px solid gray}

However, it appears that within style declarations, when defining properties, IE will just skip over properties/values it doesn’t recognize. Which is good because then we can mix in all those proprietary -moz, -webkit, etc.declarations.

So, if you are running into unexpected results, this is one more trick to add to your bag.

IE6 Negative Margin Bug

Negative margins can be really useful for offsetting content from it’s container.  I find them useful when I need to indent most content from the edge of a container but allow certain items to go edge to edge.

But, alas, in certain cases Internet Explorer 6 cuts off the content that is outside the container of the element when that container has layout.

The solution is to also set layout on the element you are trying to offset.  My favorite way of setting hasLayout on an element is to use zoom:1.  It has NO side effects.

According to this article, you also should set position:relative to keep from triggering another bug.

An example always helps:

/* this is our list container, with hasLayout set */

/* this is our list item, with fixes */

Negative Margins and IE (prior to version 8)

I haven’t written a post in awhile. But I just came across one of those bugs that kept me poking around the internet and ultimately coming up with some magic combination of styles that happens when you get desperate and start just saying “maybe this will work.” I finally came across the combination that did.

And I always have to document this stuff because 3 months down the road when I bump into it again I have NO idea what I did to fix it.

So, here’s the issue. With negative left and right margins and no width on an element, you can stretch the width of an element. I find this comes in handy when I want to put padding on a div, but there is an occasional element that needs to stretch to the edges of that div. And so I came across a need to stretch an element. Did this:

margin:0 -10px;
padding:0 10px;
border:1px solid gray

The reason I used padding that mirrored the negative margin was that I still wanted the text indented, I just wanted the border to stretch to the edges of the parent div. But you probably already got that.

It looked so beautiful. Until I opened it up in IE6. Well, no surprise there. And then I opened it up in IE7. Broken. Wah? This is the browser that’s supposed to be better. IE8, et tu? Nope, actually, IE8 got it right. There is hope for the future!

I started poking around the web. Found some good articles on this stuff which I’ll actually paste into the bottom of this post. Tried everything they said. Found something about sometimes display:inline will fix IE bugs. We don’t know why, the article said, it just does. I had already tried display:inline-block which also fixes a lot of things but that hadn’t worked. So I tried the display:inline. It actually fixed the indent! However, my border now only stretched the width of the text. Okay, what if I add width:100%, I thought? It might not work because I’m stretching beyond the 100%. But it was worth a shot. And it was the magic combination. I did wind up qualifying it to only IE6 and IE7 using the technique of assigning a class to the body tag via conditional comments that I then use to qualify the styles. I like that technique because it keeps the hacks in the same stylesheet as the rest of the styles.

So, again, here is the fix:

.ie6 .myStretchedElement, .ie7 .myStretchedElement{

It also works for right-to-left display.

Here are those links I promised:

  1. The Definitive Guide to Using Negative Margins (Smashing Magazine)
  2. CSS Float Theory: Things You Should Know (Smashing Magazine)
  3. The Positive Side of Negative Margins

IE RTL Maximize Restore Issues

And I hit yet another bidi bug in Internet Explorer. I suppose it makes sense and maybe it was bad programming on my part, but none of the other browsers were complaining….

Here’s the issue. I have a 2 column or 3 column layout. I have a bunch of stuff in that layout – some components declared as position:relative to set them as parent containers for some absolutely positioned elements inside of them. I load the page in Internet Explorer in a RTL language. The browser window isn’t maximized. I maximize it. I restore it. Various components in my layout shift to the right. Seems like they are lining up to the right column now instead of the center column.

The fix? Put position:relative on the center column and the parent container of all the columns.

Toodles. On to fix more Internet Explorer bugs.