Best css questions in June 2011

Should css class names like 'floatleft' that directly describe the attached style be avoided?

40 votes

Lots of websites use class names like floatleft, clearfloat, alignright, small, center etc that describe the style that is attached to the class. This seems to make sense so when writing new content you can easily wrap (for example) <div class="clearfloat">...</div> around your element to make it behave the way you want.

My question is, doesn't this style of naming classes go against the idea of separating content from presentation? Putting class="floatleft" on an element is clearly putting presentation information into the HTML document.

Should class names like this that directly describe the attached style be avoided, and if so what alternative is there?


To clarify, this isn't just a question of what to name classes. For example a semantically accurate document might look something like:

<div class="foo">Some info about foo</div>
...
<div class="bar">Info about unrelated topic bar</div>
...
<div class="foobar">Another unrelated topic</div>

Say all these divs need to clear floats, the css would look something like:

div.foo, div.bar, div.foobar {
    clear:both;
}

This starts to get ugly as the number of these clearing elements increases - whereas a single class="clearfloat" would serve the same purpose. Is it recommended to group elements based on the attached styles to avoid repetition in the CSS, even if this means presentational information creeps into the HTML?


Update: Thanks for all the answers. The general consensus seems to be to avoid these class names in favour of semantic names, or at least use them sparingly provided they don't hinder maintenance. I think the important thing is that changes in the layout should not require excessive changes to the markup (although a few people said minor changes are okay if it makes overall maintenance easier). Thanks to those who suggested other methods to keep CSS code smaller as well.

It's great until you re-design, and narrow is highlighted yellow, center converts better left-justified, and the image you called floatleft now belongs on the right.

I'll admit to the sin of using floatleft and clear as CSS class names, but it is much easier to maintain your CSS if you choose names that relate to the semantic meaning of the content, like feedback and heroimage.

Stacking Divs from Bottom to Top

24 votes

when appending divs to a div with a fixed height, the child divs will appear from top to bottom, sticking at the top border.

┌─────────────────────────┐
│ Child Div 1             │
│ Child Div 2             │
│                         │
│                         │
│                         │
└─────────────────────────┘

I'm now trying to display them from bottom to top like this (sticking to the bottom border):

┌─────────────────────────┐
│                         │
│                         │
│                         │
│ Child Div 1             │
│ Child Div 2             │
└─────────────────────────┘
┌─────────────────────────┐
│                         │
│                         │
│ Child Div 1             │
│ Child Div 2             │
│ Child Div 3             │
└─────────────────────────┘
┌───────────────────────┬─┐
│ Child Div 2           │▲│
│ Child Div 3           │ │
│ Child Div 4           │ │
│ Child Div 5           │█│
│ Child Div 6           │▼│
└───────────────────────┴─┘

And so on... I hope you get what I mean.

Is this simply doable with css (something like vertical-align: bottom?) or do I have to hack something together with javascript?

Thank you very much for your help. :)

All the answers miss the scrollbar point of your question. And it's a tough one. If you only need this to work for modern browsers and IE 7+ you can use table positioning, vertical-align:bottom and max-height.

Demo (vertical-align)

.wrapper { display:table-cell; vertical-align:bottom; height:200px;  }
.content { max-height:200px; overflow:auto;  }

html

<div class="wrapper">
  <div class="content">
     <div>row 1</div>
     <div>row 2</div>
     <div>row 3</div>  
  </div>
</div>  

Other than that, I think it's not possible with CSS only. You can make elements stick to the bottom of their container with position:absolute, but it'll take them out of the flow. As a result they won't stretch and make the container to be scrollable.

Demo (position-absolute)

.wrapper { position:relative; height:200px; }
.content { position:absolute; bottom:0; width:100%; }

IE6: Background-Image Load Event

18 votes

I am displaying a bunch of thumbnail images and the latency can be very high (over a VPN) so I send all the thumbnails in a single file (like a sprite) and set the CSS background-image and background-position properties of a div to show the thumbnails. The problem I'm having is with IE6 and figuring out when the image has loaded... I'm using the BackgroundImageCache hack:

document.execCommand("BackgroundImageCache",false,true);

To check when the image is loaded I use this code:

$('<img>').attr('src', 'ThumbSpriteTest.png').load(function() {
    $('.Thumbnails').css('background-image', 'url(ThumbSpriteTest.png)');
});

This works in every browser I've tried except IE6... even with the cache hack it is loading the image, firing the event, setting the background-image property and downloading the image again (and my .Thumbnail elements are blank while it re-downloads).

It seems to me that the cache hack is only changing the behavior of the CSS references and not the img tag. How can I tell when the background image is loaded without downloading it twice? Is it possible in IE6?

EDIT: Using: document.execCommand("BackgroundImageCache",true,true); seems to work (with both parameters as 'true'). I'm having trouble finding any documentation on the BackgroundImageCache command and it's parameters (I've found plenty of examples of using it to fix the CSS problem, but they all use false,true as parameters and don't explain them)... the bounty is still good for anyone with good information/documentation on the BackgroundImageCache command and it's parameters!

(I'm not sure why I'm excited to find something that works after wasting so many hours due to IE's shortcoming)

This is definitely poorly documented, as it is considered a hotfix for ie6, and will stay that way, seeing this is already fixed in ie8. Anyway, here is what is dug up bout it.

execCommand method: http://msdn.microsoft.com/en-us/library/ms536419(v=vs.85).aspx

 bSuccess = object.execCommand(sCommand [, bUserInterface] [, vValue]);
 //sCommand is the name of command to execute
 //[bUse...] is to give permission to display a dialog window (if applicable)
 //[vValue] value to pass as parameter to the command

[bUserInterface]: is just a Boolean indicator for a dialog box, that is not used by all the possible command. But is used for example to save files / create link / etc... Eg: http://man.ddvip.com/web/dhtml/constants/createlink.html

So you may want to check if this value works when set to false, it should work in theory... But hotfixes can break for funny reasons.

About the hotfix: http://support.microsoft.com/kb/823727

Anyway, this feature only appear as a patch to IE6. So dun assume it will work for all ie6 browser. While it was introduced to prevent multiple loading + leakages, and not "caching" the way you are using it, it still does what the name suggests (hopefully). So dun be surprised it hiccups on the way on unpatched versions (auto update should fix this though)

With that warning, please catch the execution for the success or fail Boolean values, if you have features dependent on it. And I guess make the best with what you have (to be sad enough to be forced to support ie6)

Pixels vs. Points in HTML

17 votes

When creating an HTML page, should I specify things like margins with pixels or with points?

Is one of them considered to be better practice than the other? Any advantages or disadvantages to either one?

Use px or em

Points (pt): Points are traditionally used in print media (anything that is to be printed on paper, etc.). One point is equal to 1/72 of an inch. Points are much like pixels, in that they are fixed-size units and cannot scale in size.

Generally, 1em = 12pt = 16px = 100%.

[Conclusion]

The winner: percent (%).

  • JohnB note: this is for TEXT. Obviously you asked about "things like margins." (I assume you mean padding also.) For that, I would recommend px or em. Personally, I switch, depending on the particular situation.

MORE ARTICLES

Point values are only for print CSS!

(Comment further down)

Points are for print? Nope.

Points are not for print exclusively. Theoretically, points are for defining an absolute measure. Pixels are not absolute, since depending on your screen and chosen definition (not resolution), the resolution (pixels per inch) can go from a lot (150dpi) or very little (75dpi). Which means your pixels can be a size, or maybe half that size. Which means that text you design to be perfectly legible on your screen may look too big on your client’s screen (“please make the text smaller, ok?”) or too small to be readable on your neighbor’s screen (“hey, the website you told me about the other day? the one you said you had worked on… well i couldn’t read the text very well, it’s so small”).

Points are a solution to this issue. But browsers and operating systems need to manage those. Basically, it means:

browsers have to calculate the display size in pixels using the given value (say, 10pt) and the screen’s real resolution; operating systems have to communicate the real current resolution, and not a default value.

Also:

What does a pipe (|) do in a CSS selector?

Asked on Mon, 27 Jun 2011 by Kraz css
15 votes

I found the following definition in a CSS stylesheet :

*|*:link {color:#ff00ff;}

What's the use of the |? Is it some sort of CSS Hack?

It separates namespace and element name.

Unless a default namespace has been defined, *|*:link is a complicated way of writing *:link or just :link.

In an XML document, you could have the following:

<el xmlns="http://name/space" />
<style>
@namespace namespace_example url(http://name/space);
namespace_example|el {background: red;}
</style>

How does the bre.ad (http://bre.ad) background work?

14 votes

Bre.ad has this background where it keeps moving and there is an illusion of a baker's truck moving on the road. I was wondering how that was done and can it be done so that the image is moving vertically instead of horizontally?

The entire background is this long png file, and the city scapes and clouds are transparent background pngs that are layered over it in multiple divs.

Background (Town):

Background

CityScape:

Cityscape

The relevant HTML from the page source:

<div id="bread-world">
    <div id="puffyclouds" style="background-position: 0 -75px"></div>
    <div id="cityscape" style="background-position: 0 105px;"></div>
    <div id="ocean"></div>
    <div id="town" style="background-position: 0 0;"></div>
    <div id="truck"></div>
</div>

and the relevant CSS from all.css

#town{
    background:url('//bread-images.s3.amazonaws.com/invite/town.png?1308363721') 
    repeat-x 542px 0px;
    width:5806px;
    left:0;
    bottom:0;
    height:599px;
    position:absolute
    }

and similarly for the other divs. The repeat-x property is used to repeat the background so as to mimic the effect of continuous scrolling. Also, the left end of the image and the right end line up, so as to give a smooth transition.

The animation is done by homepage.js which slowly shifts the background-position linearly. The relevant lines are:

function r(){
    m.css({backgroundPosition:"0 -75px"}).animate({backgroundPosition:q+"px -75px"},{duration:n,easing:"linear"}),
    k.css({backgroundPosition:"0 0"}).animate({backgroundPosition:o+"px 0"},{duration:n,easing:"linear"}),
    l.css({backgroundPosition:"0 105px"}).animate({backgroundPosition:p+"px 105px"},{duration:n,easing:"linear",complete:r})
}

Is there any way to change the color of text "halfway" through a character on a webpage?

11 votes

One thing I've seen in some Desktop applications is the ability to change the color of text as the background changes -- to effectively have multiple colors on a single character. I've seen this most commonly with progress bars that display the percentage inside the bar. Generally a darker background color will be used as the progress bar color, and as it progresses, the dark color doesn't contrast enough with the dark text, so the text color changes as soon as the bar overlaps with the text. This image should explain what I mean:

Progress Bars

As you can see, the text is black when it's at 0% -- when there is no dark background. When the background image fully progresses to 100%, the text is completely white. But in the middle, as you can see at 50%, the text is half black/half white, and it's actually split on the "0" character in this example.

Is there any way to do this at all on a webpage? CSS, Images, Jquery, otherwise? (Preferably not Flash or a Java applet though -- I'm really wondering whether an HTML-based solution is possible.) Thanks!

I'll get you started:

  1. Create two equally sized "progress bars" (divs). Set their size to the full width they would be if they were at 100%.
  2. Set one bar to black text with a white background and the other to yellow text with a blue background, as per your example above.
  3. Set the yellow/blue bar in a parent div and increase the width of the parent on every percentage increase. Position the parent above the black/white bar.
  4. Also on every increase, update the labels of both progress bars to represent the percentage.

That will simulate the same effect without having to manually paint half a character. It will be difficult in CSS because you will have to position one over the other.

The benefit of doing it this way is that you can easily display half-painted characters. There is already a jQuery progress bar you can use, though.

Why do big sites use 'bad practices'?

8 votes

I often see articles, posts and comments something like:

  • globals are bad in javascript
  • script tags should be at bottom of page
  • CSS should be in external files and at the top of page
  • scripts should be in external files, not plain script-tags.
  • etc.

I've looked up the HTML source of some big sites and have noticed that they have a lot of plain javascript and CSS inside HTML markup. JavaScript and HTML are note always obfuscated, and so on.

There are quite a few separate issues here.

  1. What you see when you "view source" is not usually what they develop with. It's usually a compressed / optimised form generated from "source" code.
  2. Claims about what is "best practice" are necessarily generic, and don't apply to all scenarios (especially if you're a big site and need specialised optimisation). These guidelines should be considered individually for each project.
  3. Best practice, or even clean code, doesn't directly translate to return on investment. It may be nice to have consistent naming schemes, but is it worth the time developing and enforcing the scheme across 100s of developers?
  4. Laziness, incompetence, or Friday nights.

How can I tell when a CSS background image has loaded? Is an event fired?

8 votes

I have a sidebar widget that has an image background.

Over this is a search input form. I don't want the input to show before the image has loaded.

Is there a way to attach an load event handler to CSS background images like normal img elements/objects?

I know this could be done on a normal image, but I'd like to keep it as a CSS background because the image is part of a sprite. I am using jQuery, so solutions using jQuery or plain DOM JS are equally good.

You could load the same image using the DOM / a hidden image and bind to the load event on that. The browser's caching should take care of not loading the image twice, and if the image is already loaded the event should fire immediately... not tested, tough.

Wrap a list to the right

8 votes

If i had a list like the following:

<ul>
  <li>Alex</li>
  <li>James</li>
  <li>Thomas</li>
  <li>Is</li>
  <li>Asking</li>
  <li>Questions</li>
  <li>On</li>
  <li>Stackoverflow</li>
</ul>

The default will be displayed like:

* Alex   
* James
* Thomas
* Is
* Asking
* Questions
* On
* Stackoverflow

What CSS would i use to get it to display like:

* Alex     * Questions
* James    * On
* Thomas   * Stackoverflow
* Is
* Asking

Thanks in advance...

For modern browsers

ul{
    -ms-column-count: 2;
    -o-column-count: 2;
    -moz-column-count: 2;
    -khtml-column-count: 2;
    column-count: 2;
    }

Why do <fieldset>s clear floats?

8 votes

Consider the following test case, in which a floated and an inline element are placed inside a <fieldset> versus a <div>:

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
        .float {float:right; background-color:red; height:200px;}
    </style>
</head>
<body>
<fieldset>
    <span>Inline!</span>
    <div class="float">Float!</div>
 </fieldset>
<fieldset>
    <span>Inline!</span>
    <div class="float">Float!</div>
</fieldset>

<div>
    <span>Inline!</span>
    <div class="float">Float!</div>
</div>
<div>
    <span>Inline!</span>
    <div class="float">Float!</div>
</div>
</body>
</html>

When rendered, the fieldsets are 200 pixels tall (they clear the floats?) while the divs are only as tall as the inline elements. What is the cause of this behavior, and is there a workaround which allows the fieldsets to behave as the divs do?

Apparently <fieldset> elements are their own block formatting contexts:

The fieldset element is expected to establish a new block formatting context.

That's why floated elements don't float out of them. I would guess that this has to do with the nature of fieldsets as visual form control groups. There could be other reasons, but off the top of my head that sounds the most plausible.

There doesn't appear to be a way to undo this, but I wouldn't be surprised; you can't destroy a block formatting context after creating it.


By the way, <fieldset>s don't clear floats. When an element clears floats, it clears only the floats that come before it. A parent element doesn't clear its children's floats either, but it can establish a formatting context for them to float in. This is the behavior seen with <fieldset>, and it's also what overflow: hidden/auto does.

From the spec (emphasis mine):

This property indicates which sides of an element's box(es) may not be adjacent to an earlier floating box. The 'clear' property does not consider floats inside the element itself or in other block formatting contexts.

Additionally, as mentioned in the comments, there is no clearing style defined by browsers for that element, so the default clearing style would already be the default value of none. This is shown in this demo, in which only one of the fieldsets coming after the floating box is defined to have clearing properties and is indeed the one clearing the float.

jQuery - Change css for all divs of a class except 'this'

7 votes

I need it so when I click on a div of class 'mydiv', all divs of that class have a z-index of 1, except for the div I clicked on which as a z-index of 2.

Clicking on the div again needs to change its z-index back to 1.

So far ive come up with the following:

    $('.mydiv').toggle(function() {
        $('.mydiv').css('z-index','1');
        $(this).css('z-index','2');
    }, function() {
        $(this).css('z-index','1');
    });

If you click on a div and then click on it again (returning the z-index to 1) before clicking on another one it works fine.

However if you click on a div, and then click another one without clicking the first one (to toggle it back to z-index 1), sometimes it works and sometimes it doesn't do anything. Im assuming the problem is in the first part of my code because this:

$('.mydiv').css('z-index','1');

Is not always run before this:

$(this).css('z-index','2');

Is that the problem and if so how can I fix this? Thanks

UPDATE - Sorry for not thinking of this initially, but ive simplified my question here, the actual page will need to have css positioning animations. So when you click on a div it moves with a smooth animation. I think that means I cant just change the css by toggling a class. Thanks

-

UPDATE 2 - I thought I had this working, and then I tested in IE8 and 7. IE9 is ok (along with every other browser I tested with) but IE7 and IE8 make all of the images jump around when you click on any of them. Here is the demo (all css and jQuery are within the page):

http://smartpeopletalkfast.co.uk/jquery/basicDemo12-bugfix-3.htm

And here is the jQuery:

    $(".image-div").click(function () {


        var divRefTwo = $(".image-div").not(this);
        $(".image-div").not(this).animate({
                width: '250px',
                left: '0px',
                marginRight: '0px',
                backgroundPosition: '-125px'
            }, 400, function() {
                $(divRefTwo).css('z-index','1');
            });

        if ($(this).css('z-index') == 1) {
            $(this).css('z-index','2');
            $(this).animate({
                width: '500px',
                left: '-125px',
                marginRight: '-250px',
                backgroundPosition: '0px'
            }, 500, function() {
                //
            });
        }
        else {
            var divRef = this;
            $(this).animate({
                width: '250px',
                left: '0px',
                marginRight: '0px',
                backgroundPosition: '-125px'
            }, 500, function() {
                $(divRef).css('z-index','1');
            });
        }

    });

I think whats happening is this: The background image position for div.image-div starts at -125px. When you click a div.image-div, jQuery animates the background position for all the other divs of the the same class to -125px. Only divs that are expanded should change, as the other divs already have background position of -125px.

For some reason IE resets the background position to 0, and then animates to -125px. So the animation ends up in the correct place, but animates to get their when it shouldn't.

Any ideas why this is happening? Is this a jQuery IE bug or a CSS hierarchy of selectors thing? Thanks

So now we changed everything again. Based on the OP edit, now the code would be:

$(".mydiv").click(function () {
    var $t = $(this);
    $t.siblings().css("z-index", 1).animate({
            "margin-top": 0
        }, "fast");
    if ($t.css("z-index") == 1)
        $t.css("z-index", 2).animate({
            "margin-top": -10
        });
    else
        $t.css("z-index", 1).animate({
            "margin-top": 0
        }, "fast");
});

Here is the again updated working sample.

Now let me explain the logic of the code.

// Since we'll use $(this) (the clicked div) in many places
// of the code, I started caching it in a var named $t.
var $t = $(this);

// Then I get all the siblings (The other divs that are beside this,
// or are children of the same parent). The I change back all this divs to
// z-index = 1 and animate their top down to 0.
$t.siblings().css("z-index", 1).animate({ "margin-top": 0 }, "fast");

// Next we have the if statement to check if the clicked div is with
// z-index = 1 (unclicked) or z-index = 2 (already clicked).
if ($t.css("z-index") == 1)

// Then we change the current div to z-index = 2 and animate it 10px upper.
$t.css("z-index", 2).animate({ "margin-top": -10 });

// Or else we change back the current div to z-index = 1 and animate it down.
$t.css("z-index", 1).animate({ "margin-top": 0 });

Issue with applying dotted border to cells in table design

7 votes

Here's my fiddle:

http://jsfiddle.net/gFA4p/84/

In this screenshot, the green lines represent where I'm trying to apply dotted lines.

enter image description here

I am able to get the left-right borders to appear as dotted lines, but not the bottom borders.

How can I resolve this?

The issue you're seeing is due to the rules of conflict resolution when it comes to border collapse. Solid takes precedence over dotted:

http://lachy.id.au/dev/css/tests/bordercollapse/bordercollapse.html

I believe you will need to make the conflicting borders dotted as well. So if you went a cell's left border to be dotted, you'll need to make the right border of the cell to its left also dotted (or anything of lower precedence, but dotted make the most sense).

How to keep text opacity 100 when its parent container is having opacity of 50

7 votes

I have a list div which have a opacity set to 50 and inside this div I want to display some text with opacity 100,

Here's what I mean:

<div id="outer">
  <div id="inner">
    Text
  </div>
</div>

The CSS would be:

#outer {
  opacity: 0.5;
}

#inner {
  opacity: 1.0;
}

I tried that, but it doesn't work.

please help

Regards

This tutorial is pure genius

In essence, you're overriding this css "hiccup" by floating a transparency over a div, then presenting the type layer at 100% opacity over that. It just works!