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:

::-webkit-input-placeholder,
::-moz-placeholder,
:-ms-input-placeholder,
::placeholder{
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:

::-webkit-input-placeholder{
color: #666;
}

And it worked!

So I then I did this:

::-webkit-input-placeholder,
::placeholder{
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:

::-webkit-input-placeholder{
color: #666;
}
::-moz-placeholder{
color: #666;
}
:-ms-input-placeholder{
color: #666;
}
::placeholder{
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.

Display: inline-block in webkit

To fix funky alignment issues with inline-block elements, add vertical-align:top to the element.

http://stackoverflow.com/questions/11890670/displayinline-block-not-centering-vertically-in-chrome

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          http://www.domain.com/*
// @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!

JQuery UI drifting position

I have run into an issue with the jQuery UI position() function. If I use it to position a popup menu relative to the element that was clicked, the next time I open the menu, it drifts to the right, even though I am clicking the same element each time.

After googling and trying things, this is what I came up with:

$(“#myMenu”).show().position({my: “left top”, at: “left bottom”, of: e.target, collision: “fit flip”}).hide().delay(600).fadeIn().focus();

That’s a mouthful, huh?

First off, we can’t position a hidden object so we need to show it first. Then, it appears we need to separate the positioning from the animation, so we hide it again, then fade it in. I also put a delay in there so it wouldn’t pop up right away, and then I set focus on the menu.

Since I am newish to jQuery, I don’t really know the significance of separating the positioning from the animation, but here is the link that turned me onto the solution.

 

Fiddling with CSS3 box-shadow

Box shadow declarations can confuse me. So I decided to create a jsfiddle to show the basics and where I could play with additional styling in the future.

You can use box-shadow to help create double borders, and you can play with the values to get just shadows on certain sides of the box. You can shadow inside or outside the box. You can add multiple values for box-shadow, separated by commas, to build up your styling.

Here is a great reference for box-shadow, with additional examples.

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.

Getting Started with HTML5

At IBM, I work on a common set of UI components that various product teams use to build their pages. I wanted to switch that code over to HTML5. Some product teams wanted to start using it. Some wouldn’t be changing their code. How to make everybody happy? Switch to HTML5 in a way that xHTML/HTML would still work. Here’s how to do that in 3 easy steps:

Change your doctype and html tag

<!DOCTYPE html>
<html lang="en-US">

Or, leave your existing tags in place

Define the elements to IE

<!--[if IE]>
<script>
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('header');
document.createElement('hgroup');
document.createElement('nav');
document.createElement('section');
...and any other elements you are using
</script>
<![endif]-->

Or don’t.

Define the elements in your CSS

/*html5 elements*/
article, aside, footer, header, hgroup, nav, section {display:block;}

Or leave them out.

Style using classes

This is the key point.  If you do your styling using classes you can assign them to either your new HTML5 elements, or your old DIVs.  And then your stylesheet will plug into either kind of page.

The only gotcha I’ve found

HTML5 is considered strict mode.  In strict mode, an inline image includes 4 pixels of space at the bottom for the descender.  This means there can be differences in image alignment between HTML5 and a transitional doctype.

There are a couple of solutions you can try if you don’t like the alignment of your image with the surrounding elements.  Play with vertical-align.  Try vertical-align: bottom to start.  And if you can, try setting display:block on the image – not a good solution if you are trying to keep your images inline, but just throwing it out there, because it does remove that invisible 4 pixels.

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.

More IE and inline-block

You didn’t think one posting about IE and inline-block was going to handle all the issues, did you? Did you? The issue I am going to talk about in this post is an oldy but a goody.

Display:inline-block is only supported in IE6 & 7 on elements that are natively inline. Say what?

You’ll find if you add that property to a block element, assuming your element will nicely shrinkwrap, you will be disappointed. The fix is to use display:inline;zoom:1;. Then you will get an element that acts like an inline block.

Source article for this information

Peace,
Chris

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 */
ul.myList{
padding:10px;
zoom:1;
}


/* this is our list item, with fixes */
li.selected{
margin-left:-10px;
padding-left:10px;
zoom:1;
position:relative
}