Category Archives: css

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.

Advertisements

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.

Internet Explorer and Opacity

To change the opacity of an item, we can use this CSS declaration:

opacity:0.25; /*the css standard*/
filter:alpha(opacity=25); /*sets opacity in IE*/

Hmmm. IE doesn’t support the CSS standard. Quelle surprise!

Here’s something else. If the element you are trying to make transparent doesn’t have layout in IE, the opacity won’t be set. The solution? Put zoom:1 on the element.

And I haven’t figured this completely out in IE8 standards mode, but I was trying to set opacity on an image wrapped in a link by assigning the opacity to the link itself. Should be inherited, I thought, like in IE8’s predecessors. But it wasn’t. I wound up getting it to work by assigning opacity directly to the image instead of the link.

So in summary, to get opacity to work in Internet Explorer versions 6 – 8:

  • Use filter:alpha(opacity=x), where x is a number from 0 to 100
  • place zoom:1 on the element if needed
  • assign the opacity directly to an image

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:


.myStretchedElement{
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{
display:inline;
width:100%
}

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

Image Resizing in IE

Here’s an interesting blog post about improving the quality of images that you are resizing in your UI when viewing them in IE.

The (proprietary) css attribute is -ms-interpolation-mode:bicubic;

It does say that it’s probably safest to apply the fix only to images you are explicitly resizing. Until I read that line I was all set to add it to my base styles stylesheet….

Setting min-width and max-width in IE 6

Internet Explorer 6 doesn’t support the min-width and max-width styles. But we can use expressions to get around this. Expressions are something IE supports that allows you to set a css value to the result of a javascript statement.

Here is how we can set a minimum width of 960 pixels in IE6.

* html .myClass{width:expression(documentElement.clientWidth < 960 ? (documentElement.clientWidth == 0 ? (body.clientWidth < 960 ? "960px" : "auto") : "960px") : "auto")}

What this says is that if the width of the element with class of myClass is less than 960 pixels, set the width to 960px else set it to auto (which will preserve the current size). There is extra code in here to account for whether or not your page is set to use xHTML or HTML in the doctype, which changes the object reference for the body tag (xHTML uses documentElement intead of body).

I’ve found this article on the web, which says that reqular expressions are very expensive on the page, and you should use javascript instead.

And also this article, which says that the browser can freeze if you set the width of the browser to the same value. It suggests tweaking the code to something like this, instead:

* html .myClass{width:expression(documentElement.clientWidth < 962 ? (documentElement.clientWidth == 0 ? (body.clientWidth < 962 ? "960px" : "auto") : "960px") : "auto")}

Probably good to do that to be on the safe side.

Multiple class syntax

Okay, I’ve known for a long time that you could assign multiple classes to an element, like so:

<div class="large red">Some text</div>

Then I could reference code css to define red styles and large styles.


.large {font-size:2em}
.red {color:red}

And the text would be large and red. All good. But what I wanted to be able to define was a style that only applied if both classes were on an element. And I’ve been going along not realizing that the syntax was available. How could I have missed that in the book (it was on page 34)? But I did. So, maybe someone else has, too. Here is the syntax.

.large.red{border:1px solid black}

And so my div text, above, will be large, red, and have a black border. The syntax is to just butt those class definitions up next to each other with no space in between them. Simple. Happy coding!

CAVEAT: This does not work in IE 6. So, if you have the luxury of not having to code for that old browser, or if you are able to put Dean Edwards’ IE7 script on your server, you can use this syntax.