Best css questions in August 2011

How does this CSS triangle shape work?

372 votes

There're plenty of different CSS shapes over at http://css-tricks.com/examples/ShapesOfCSS/ and I'm particularly puzzled with a triangle:

Triangle

#triangle-up {
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 100px solid red;
}

So, how and why does it work?

CSS Triangles: A Tragedy in Five Acts

As alex said, borders of equal width butt up against each other at 45 degree angles:

borders meet at 45 degree angles, content in middle

When you have no top border, it looks like this:

no top border

Then you give it a width of 0...

no width

...and a height of 0...

no height either

...and finally, you make the two side borders transparent:

transparent side borders

That results in a triangle.

The End

Why <script src="min.js"></script> but <link rel="stylesheet" href="min"> why not <style href="min.css"></style>

16 votes

My one of relative who started to learn Web Development asked me this question.

Why <script src="min.js"></script> but <link rel="stylesheet" href="min.css"> why not <style href="min.css"></style> why we use link tag to add external css in the page but when we link css to page but we use <style>...</style> when we write css inside <head>?

I told him that it's because of Specification. Is there any more info to give to him?

It's historical... coincidence? You can recommend him reading part about Past of diveintohtml5.org, where there are some interesting stories, actually mail correspondences, between web developers. Web developers means they were, in fact, developing the Web we see nowadays ;)

I.e. <img> tag we are used to:

<IMG SRC="file://foobar.com/foo/bar/blargh.xbm">

could be:

<ICON name="NoEntry" href="http://note/foo/bar/NoEntry.xbm">

or

<A HREF="..." INCLUDE>See photo</A>

or

<INCLUDE HREF="...">

but finally devs decided to stick with <img>, which was already implemented:

We’re not prepared to support INCLUDE/EMBED at this point. … So we’re probably going to go with (not ICON, since not all inlined images can be meaningfully called icons). For the time being, inlined images won’t be explicitly content-type’d; down the road, we plan to support that (along with the general adaptation of MIME). Actually, the image reading routines we’re currently using figure out the image format on the fly, so the filename extension won’t even be significant.

I don't know direct answer to your question, but I'm pretty curious about <link> tag, too. Finding answer would probably include some web archives digging.

Convert CSS background shorthand to longhand

12 votes

I am trying to write a function that converts a short hand css declaration of background to long hand. I've written the below function but it has a couple of issues. One it doesn't take into account that background-color can be colour values such as black, yellow. In addition, what if some the properties contain inherit and none? Here is an example:

url('http://2.bp.blogspot.com/-h28qvOsfm1c/TaGyO_qAFcI/AAAAAAAAA9w/I7zPQLy0zVM/s640/funny-image.jpg') inherit inherit 0 0 #FFFFFF;

Convert the above to CSS long hand. Here is my function, can it be improved to cover other cases?

function rewrite_background($b){

    $long_hand = "";

    $count = count($b); 

    for($i=0; $i < $count; $i++){

        if(stripos($b[$i], '#') !== false){

            $long_hand .= 'background-color: '.$b[$i].'; ';

            unset($b[$i]);

        }else if(stripos($b[$i], 'url') !== false){

            $long_hand .= 'background-image: '.$b[$i].'; ';

            unset($b[$i]);

        }else if((stripos($b[$i], 'repeat') !== false) || (stripos($b[$i], 'no-repeat') !== false) || (stripos($b[$i], 'repeat-x') !== false) || (stripos($b[$i], 'repeat-y') !== false)){

            $long_hand .= 'background-repeat: '.$b[$i].'; ';

            unset($b[$i]);

        }else if((stripos($b[$i], 'scroll') !== false) || (stripos($b[$i], 'fixed') !== false)){

            $long_hand .= 'background-attachment: '.$b[$i].'; ';

            unset($b[$i]);

        }else{

            // not recognized

        }

    }

    $b = array_values($b);

    if(isset($b[0])) $long_hand .= 'background-position: '.$b[0].' '.$b[1].';';  

    return $long_hand;

} 

Thanks to Abs comment I decided to rewrite this code from scratch. (I hope that's acceptable.)

This class will parse just about any line of background shortcut properties in any order, including those that are invalid according to the specs. background: top top, for instance, is treated as background-position: center top.

See the spec at w3c

All color values are fully supported, including rgb, rgba, hls, hlsa, short-form hex (e.g. #fff), long-form hex (e.g. #123Abc), and color names.

!important is now supported.

inherit seemed as though it would be the most challenging problem, but turns out to be the simplest. For this property I referred to http://reference.sitepoint.com/css/inheritvalue, which states:

When you’re using shorthand notation such as background, you can’t mix inherit with other values. For example, the following background declaration is wrong:

p {
  background: #fff inherit left top;
}

... inherit must be the only value in the declaration, because there’s simply no way of identifying the subproperty to which the value inherit refers—after all, it’s not unique within the sequence. In the example above, inherit becomes ambiguous.

To deal with ambiguity, this class simply ignores everything else (except !important) and applies inherit to all properties as if you had used background: inherit

<?php
class CSSBackground
{
    private $color_names = array(
        'AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine', 'Azure',
        'Beige', 'Bisque', 'Black', 'BlanchedAlmond', 'Blue',
        'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue', 'Chartreuse',
        'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson',
        'Cyan', 'DarkBlue', 'DarkCyan', 'DarkGoldenRod', 'DarkGray',
        'DarkGrey', 'DarkGreen', 'DarkKhaki', 'DarkMagenta',
        'DarkOliveGreen', 'Darkorange', 'DarkOrchid', 'DarkRed',
        'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue', 'DarkSlateGray',
        'DarkSlateGrey', 'DarkTurquoise', 'DarkViolet', 'DeepPink',
        'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick',
        'FloralWhite', 'ForestGreen', 'Fuchsia', 'Gainsboro',
        'GhostWhite', 'Gold', 'GoldenRod', 'Gray', 'Grey', 'Green',
        'GreenYellow', 'HoneyDew', 'HotPink', 'IndianRed', 'Indigo',
        'Ivory', 'Khaki', 'Lavender', 'LavenderBlush', 'LawnGreen',
        'LemonChiffon', 'LightBlue', 'LightCoral', 'LightCyan',
        'LightGoldenRodYellow', 'LightGray', 'LightGrey', 'LightGreen',
        'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue',
        'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow',
        'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon',
        'MediumAquaMarine', 'MediumBlue', 'MediumOrchid', 'MediumPurple',
        'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen',
        'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue', 'MintCream',
        'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace', 'Olive',
        'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod',
        'PaleGreen', 'PaleTurquoise', 'PaleVioletRed', 'PapayaWhip',
        'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple', 'Red',
        'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Salmon', 'SandyBrown',
        'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',
        'SlateGray', 'SlateGrey', 'Snow', 'SpringGreen', 'SteelBlue', 'Tan',
        'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White',
        'WhiteSmoke', 'Yellow', 'YellowGreen'
    );

    private $m_bgcolor = 'transparent';
    private $m_bgimage = 'none';
    private $m_bgrepeat = 'repeat';
    private $m_bgattachment = 'scroll';
    private $m_bgposition = '0% 0%';
    private $m_bgimportant = false;
    private $m_bg;

    public function __construct($bg)
    {
        // reformat array names for efficient pattern matching
        $this->color_names = '/\b('.implode('|',$this->color_names).')\b/i';

        $this->m_bg = $bg;  // save original

        $bg = $this->parse_important($bg);
        $bg = $this->parse_inherit($bg);
        $bg = $this->parse_color($bg);
        $bg = $this->parse_image($bg);
        $bg = $this->parse_repeat($bg);
        $bg = $this->parse_attachment($bg);
        $bg = $this->parse_position($bg);
    }

    public function original()
    {
        return $this->m_bg;
    }

    public function color()
    {
        return $this->m_bgcolor;
    }

    public function image()
    {
        return $this->m_bgimage;
    }

    public function repeat()
    {
        return $this->m_bgrepeat;
    }

    public function attachment()
    {
        return $this->m_bgattachment;
    }

    public function position()
    {
        return $this->m_bgposition;
    }

    public function important()
    {
        return $this->m_bgimportant;
    }

    private function parse_important($c)
    {
        // check for !important
        if (preg_match('/!important/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgimportant = true ;
        }

        return $c;
    }

    private function parse_inherit($c)
    {
        // check for !important
        if (preg_match('/inherit/i', $c, $m))
        {
            $this->m_bgcolor = $this->apply_important('inherit');
            $this->m_bgimage = $this->apply_important('inherit');
            $this->m_bgrepeat = $this->apply_important('inherit');
            $this->m_bgattachment = $this->apply_important('inherit');
            $this->m_bgposition = $this->apply_important('inherit');
            $c = '';
        }

        return $c;
    }

    private function parse_color($c)
    {
        // check for hexit color value
        if (preg_match('/#([[:xdigit:]]{3}){1,2}/', $c, $m))
        {
            $c = str_replace($m[0], '', $c);

            $this->m_bgcolor = $this->apply_important($m[0]);
        }

        // check for rgb color value
        elseif (preg_match('/rgb\(\d{0,3}\,\d{0,3},\d{0,3}\)/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgcolor = $this->apply_important($m[0]);
        }

        // check for rgba color value
        elseif (preg_match('/rgba\(\d{0,3}%?\,\d{0,3}%?,\d{0,3}%?\,\d(\.\d)?\)/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgcolor = $this->apply_important($m[0]);
        }

        // check for hls color value
        elseif (preg_match('/hls\(\d{0,3}\,\d{0,3}%,\d{0,3}%\)/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgcolor = $this->apply_important($m[0]);
        }

        // check for hlsa color value
        elseif (preg_match('/hlsa\(\d{0,3}\,\d{0,3}%,\d{0,3}%\,\d(\.\d)?\)/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgcolor = $this->apply_important($m[0]);
        }

        // check for transparent
        elseif (preg_match('/transparent/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgcolor = $this->apply_important('transparent');
        }

        // check for color names
        elseif (preg_match($this->color_names, $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgcolor = $this->apply_important($m[0]);
        }

        return $c;
    }

    private function parse_image($c)
    {
        // check for double word positions
        if (preg_match('/url\((.*?)\)|none/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            if (isset($m[1]))
            {
                $m[0] = str_replace($m[1], urlencode($m[1]), $m[0]);
            }
            $this->m_bgimage = $this->apply_important($m[0]);
        }

        return $c;
    }

    private function parse_repeat($c)
    {
        // check for repeat values
        if (preg_match('/\b(repeat-x|repeat-y|no-repeat|repeat)\b/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgrepeat = $this->apply_important($m[0]);
        }

        return $c;
    }

    private function parse_attachment($c)
    {
        // check for repeat values
        if (preg_match('/scroll|fixed/i', $c, $m))
        {
            $c = str_replace($m[0], '', $c);
            $this->m_bgattachment = $this->apply_important($m[0]);
        }

        return $c;
    }

    private function parse_position($c)
    {
        // check for position values
        if (preg_match_all('/left|right|center|top|bottom|-?\d+([a-zA-Z]{2}|%?)/i', $c, $m))
        {
            $horz = '0%';
            $vert = '0%';

            if (!isset($m[0][1]))
            {
                $x = strtolower($m[0][0]);
                switch ($x)
                {
                    case 'top':
                    case 'bottom':
                        $horz = 'center';
                        $vert = $x;
                        break;
                    case 'left':
                    case 'right':
                    case 'center':
                        $horz = $x;
                        $vert = 'center';
                        break;
                    default:
                        $horz = is_numeric($x) ? "{$x}px" : $x;
                        $vert = 'center';
                }
            }

            else
            {
                $horz = strtolower($m[0][0]);
                $vert = strtolower($m[0][1]);

                if (($horz === $vert) && in_array($horz, array('left','right')))
                {
                    $vert = 'center';
                }

                if (($horz === $vert) && in_array($horz, array('top','bottom')))
                {
                    $horz = 'center';
                }

                if ($horz === 'top' || $horz === 'bottom')
                {
                    list($horz,$vert) = array($vert,$horz);
                }

                if ($vert === 'left' || $vert === 'right')
                {
                    list($horz,$vert) = array($vert,$horz);
                }
            }

            $this->m_bgposition = $this->apply_important("$horz $vert");
        }

        return $c;
    }

    private function apply_important($prop)
    {
        return $prop . ($this->m_bgimportant ? ' !important' : '');
    }
}

header('Content-type: text/plain');

// Sample usage code:
$bg = 'url("chess.png") gray 50% repeat fixed';

$cssbg = new CSSBackground($bg);

echo "background: ", $cssbg->original(), "\n\n";
echo "background-color: ", $cssbg->color(), "\n";
echo "background-image: ", $cssbg->image(), "\n";
echo "background-repeat: ", $cssbg->repeat(), "\n";
echo "background-attachment: ", $cssbg->attachment(), "\n";
echo "background-position: ", $cssbg->position(), "\n\n";
echo "!important applied: ", $cssbg->important() ? 'true' : 'false', "\n";

?>

Thanks for the comments. Keep 'em comin'. :)

How do you show just the first line of text of a div and expand on click?

11 votes

I want to show just the first line of a block of wrapped text, and then reveal the whole block on click. Also, I'd like to know how to toggle it back to the compact one-line version on a second click.

Is there an easy way to do this through css + javascript? I use jQuery.

Assuming that you don't want to use any JavaScript library (which is odd).

See: http://jsfiddle.net/JUtcX/

HTML:

<div id="content"></div>

CSS:

#content {
    border: 1px solid red;
    height: 1em;
    padding: 2px; /* adjust to taste */
    overflow: hidden    
}

JavaScript:

document.getElementById("content").onclick = function() {
    this.style.height = 'auto';
}

Alternatively, if you would like to use a JavaScript framework such as jQuery, you can animate it.

See: http://jsfiddle.net/JUtcX/2/

$('#content').click(function() {
    var reducedHeight = $(this).height();
    $(this).css('height', 'auto');
    var fullHeight = $(this).height();
    $(this).height(reducedHeight);

    $(this).animate({height: fullHeight}, 500);
});

How to set auto-margin boxes in flexible-width design using CSS?

10 votes

I have DIV with flexible width set e.g. min-width:800px and max-width:1400px. In this DIV, there are many boxes with fix width 200px and display:inline-block. So depending on parent DIV width, these boxes fill the entire space.

My problem is the blank space on the right side which is caused by variable width of the parent div. Sometimes this blank space is small and looks fine, but with different widths of the parent div, this blank space is almost 200px.

I don't know, if I described my problem in enough detail, I hope this picture will help to describe my actual situation:

enter image description here

And this is what I would like to have:

enter image description here

This auto-margin could be easily achieved by using TABLE. However, I don't know the exact number of columns, since it depends on user's screen resolution. So I can't use table and rather stick with CSS.

Anyone has an idea how to solve this ? Thank you in advance for your comments and answers.

EDIT: I don't need support of IE6. I would like to support IE7, but IE7 is optional as I know there are limitations so I will probably use fixed width of "div.wrapper" in IE7

EDIT2 I need to handle multiple rows of these boxes, so they don't exceed the "div.wrapper" box and wrap correctly in multiple lines of boxes, not just in one long line.

EDIT3 I don't know the number of "columns" as this is very variable depending on user's screen resolution. So on big screen there could be 7 boxes in one row, and on small screens there could be just 4 boxes in one row. So I need solution that doesn't set fixed number of boxes in one row. Instead, when the boxes don't fit in one row, they should just wrap to a next row.

This is as close as IE7-compatible CSS can get: http://jsfiddle.net/thirtydot/79mFr/

If this still isn't right, it's time to look at using JavaScript and hopefully also jQuery. If you define your requirements properly, it should be trivial to get this perfect with JavaScript.

HTML:

<div id="container">
    <div></div>
    <div></div>
    ..
    <span class="stretch"></span>
</div>

CSS:

#container {
    border: 2px dashed #444;

    text-align: justify;
    -ms-text-justify: distribute-all-lines;
    text-justify: distribute-all-lines;

    min-width: 800px;
    max-width: 1400px
}

#container > div {
    margin-top: 16px;
    border: 1px dashed #f0f;
    width: 200px;
    height: 200px;
    vertical-align: top;
    display: inline-block;
    *display: inline;
    zoom: 1
}
.stretch {
    width: 100%;
    display: inline-block;
    font-size: 0;
    line-height: 0
}

The extra span (.stretch) can be replaced with :after.

This still works in all the same browsers as the above solution. :after doesn't work in IE6/7, but they're using distribute-all-lines anyway, so it doesn't matter.

See: http://jsfiddle.net/thirtydot/79mFr/2/

There's a minor downside to :after: to make the last row work perfectly in Safari, you have to be careful with the whitespace in the HTML.

Specifically, this doesn't work:

<div id="container">
    <div></div>
    <div></div>
</div>

And this does:

<div id="container">
    <div></div>
    <div></div></div>

Can I style an image's ALT text with CSS?

10 votes

I have a dark blue page and when the image is loading (or missing) the ALT text is black and difficult to read (in FF).

Could I style it (with CSS) to be white?

Setting the img tag color works

http://jsfiddle.net/YEkAt/

img {color:#fff}

Does the order of rules in a CSS stylesheet affect rendering speed?

9 votes

While this could possibly result in a simple yes or no answer I'll go for it anyway


Consider the following example:

HTML

<html>
    <head>
    </head>
    <body>
        <div class="foo">
            <span class="bar">Hello world!</span>
            <p>Some really interesting text.</p>
        </div>
    </body>
</html>

CSS

html {
    /* some css */
}
body {
    /* some css */
}
div.foo {
    /* some css */
}
div.foo span.bar {
    /* some css */
}
div.foo p {
    /* some css */
}

Will the order in which css rules appear, have any effect on how (fast) the browser can render the page? ( in this example it won't really matter, but consider a real website with loads of html and css )

So the above css script will render faster or easier for the browser than :

div.foo p {
    /* some css */
}
div.foo span.bar {
    /* some css */
}
div.foo {
    /* some css */
}
body {
    /* some css */
}
html {
    /* some css */
}

Do browsers care? Should we?


Read before asking:

After some more testing and reading I came to the following conclusion, no, it does not matter. Even after some ‘extreme’ testing, I could not find anything that supports the idea that the order matters.

There were no 'flashed of unstyled content' or the likes, it just took way longer to load the page ( way way longer :D )

Tests I ran I created a test page with 60.000 div elements, each having a unique ID attribute. Each of these ID’s had their own css rule applied to it. Below that I had a single span element with a CLASS attribute, which was also had a css rule linked to it.

These tests created a html file of 2MB with a corresponding css file of 6MB.

At first I attempted these tests with 1.000.000 divs and css rules, but Firefox did not approve and started crying, begging me to stop.

I generated these elements and their css with the following simple php snippets.

<?PHP

    for ($i = 0; $i < 60000; $i++) {
        echo "
#test$i {
    position: absolute;
    width: 1px;
    height: 1px;
    top: " . $i . "px;
    left: 0;
    background: #000;
} <br />
";
    }

?>

And

<?PHP

    for ($i = 0; $i < 60000; $i++) {
        echo "
<div id=\"test$i\"></div>
";
    }

?>

The result was put in a html and css file afterwards to check the results.

Mind you, my browser ( Firefox 5 ) really did not appreciate me playing around with this, it really had some issues generating the output, the occasional this program is not responding message was not afraid to show it's face.

These tests were ran on a localhost, ran by a simple XAMPP installation, it might be possible that external servers result in a different resultset, but I am currently unable to test that.

I tested a few variations on the above:

  • Placing the element before all the generated divs, in the middle and at the end
  • Placing the span’s css definition before, in the middle or at the end of the css file.

Oh and may I suggest: http://www.youtube.com/watch?v=a2_6bGNZ7bA while it doesn't exactly cover this question, it does provide some interesting details about how Firefox ( and possibly other browsers )work with the stuff we throw at it.

What is the purpose of this CSS snippet?

9 votes

I have the following snippet in my stylesheet. What is the impact or purpose?

* {
    margin:0;
    padding:0;
    top: 0px;
    left: 0px;
}

It's a reset CSS. It's purpose is to remove default non-zero spacings for all (*) elements. All browsers have some default style sheet and they're not very consistent with each other. Take <form> as an example.

Note: Setting the left and top properties to 0px doesn't look right to me. It will most probably cause problems with absolute positioning. When positioning an element absolutely you may want to define only it's vertical or horizontal offset (not both), leaving the other offset unchanged. That reset CSS doesn't allow that because it gives values for both vertical and horizontal. Also you may want to position an element from the bottom. If you have that reset it will have both bottom and top which in most cases is not wanted and may alter the height of the element or not respect one of the offsets. In any case it will give you something not intended and break your layout.

For those who want to learn more: http://www.w3.org/TR/CSS2/visuren.html#absolute-positioning

div.classname in css file

9 votes

I have seen some developers write

HTML:

<div class="test"> some content </div>

CSS:

div.test {
  width:100px.
}

What is the purpose of doing div.className instead of just .className.

Does this mean this style will be applied only when the class is applied to a div.

So, <span class='test'>content</span> will have no effect of 'test' with the css above? If that is the case, is that best practice? This is almost like style overriding for different type of elements, mixing styles with rules!

To really answer your question, though, first I have to answer a couple of other questions. Because, as you will see, it's all about context.

  • What is the point of HTML?
  • What is a div?
  • How is it different from other HTML elements?
  • And what does it mean when a element has a class (or collection of classes)?

I'll give you my opinion on the answers to those question, and then we can have a meaningful discussion on best-practices.

What is the point of HTML?

The point of HTML is to add context to your data. Text, all by itself, can be a very powerful thing. Since the invention of the printing press, it has served humanity very well as an extremely powerful communication tool. Take the following document for example:

My shopping list
Bread
Milk
Eggs
Bacon

Even with this simple text document, most people can dechiper the intent of the writer; its a shopping list. There is a heading, and a collection of list items that need to be purchased.

So whats the point of HTML then, if simple text documents are enough?

Fair question. If text is enough to communicate, then why do we need HTML?

The reader of the document attempts to parse the information they get. That processes is imbedded with a ton of cultural tricks and learned patterns that are used to reconstruct the origional intent. It is trivial for most people with a basic understanding of english to determine the meaning of the document. However, as the complexity of the document increases (or the familiarity of the reader with the context decreases), then it becomes more and more difficult to parse correctly. Assumptions are made; context becomes unclear. Eventually, the readers ability to accurately decode the message falls apart, and the message is indechiperable.

This is the space where HTML exists. It is desinged to wrap around data, providing context and meaning. So even if you (or the computer) are unable to process the the actual information, you can understand the context in which it should be in. For example the same document with HTML:

<h1>My shopping list</h1>
<ul>
    <li>Bread</li>
    <li>Milk</li>
    <li>Eggs</li>
    <li>Bacon</li>
</ul>

Now, even if we weren't able to understand the actual data, we have a contextual backdrop to intpret the data. We have a heading, an unordered list, which has a collection of list items.

<h1>Xasdk bop boop</h1>
<ul>
    <li>Zorch</li>
    <li>Quach</li>
    <li>Iach</li>
    <li>Xeru</li>
</ul>

I have no idea what that means, but atleast I know its a heading and an unordered list. That is the way the browser sees your HTML document; Some data, wrapped in context.

What is a div? How is it different from other HTML elements?

HTML elements define context; They describe the content they wrap around. HTML shouldn't alter or change the meaning of the data, it simply augments it and defines relationships between the data: parent, child, sibling, ancestor... So a li element describes a list item. A h1 element describes a heading. A table element describes a table, and so on.

So, what is a div then? Well, a div is an block-level HTML element that has no context of its own. By itself, it doesn't mean anything (other than it is a block).

While most other HTML elements (with the exception of the span element) have some kind of implicit context, the div element does not. That is a huge difference. It's a blank box. It's a box that doesn't mean anything. When you put something in a 'div', you are saying that its in a box, but that box doesn't really mean much.

So what is the point of a div then?

The div tag provides a blank slate for you to define your own context. Back to our shopping list example, right now, there is a weak relationship between the unordered list and the heading. They are weakly associated siblings, they just happen to be next to each other, but nothing really binds them together as a unit. What we would really like to say is:

<grocery_list>
    <h1>My shopping list</h1>
    <ul>
        <li>Bread</li>
        <li>Milk</li>
        <li>Eggs</li>
        <li>Bacon</li>
    </ul>
</grocery_list>

But we can't do that within the confines of the HTML spec. But what we can do is this: Stick them in a 'box':

<div>
    <h1>My shopping list</h1>
    <ul>
        <li>Bread</li>
        <li>Milk</li>
        <li>Eggs</li>
        <li>Bacon</li>
    </ul>
</div>

What does it mean when a element has a class (or collection of classes)?

But, again, that box doesn't mean that much right now. What we really would like to do is give that box some context of our own. We want to invent our own element. Thats where the class attribute comes into play. While HTML elements augment data, HTML attributes augment elements. We can say:

<div class="shopping_list">
    <h1>My shopping list</h1>
    <ul>
        <li>Bread</li>
        <li>Milk</li>
        <li>Eggs</li>
        <li>Bacon</li>
    </ul>
</div>

So we are saying that our div is really a shopping_list. That shopping_list has a heading, and an unordered list of items. HTML is supposed to make your data more clear, not less clear.

So, finally, how does this all relate to your question?

When you are writing CSS, you are leveraging your context (elements, classes, ids, and the relationship between elements) to define style.

So back to the shopping list example. I could write a stlye that said

<style>
    ul {
        background-color: red;
    }
</style>

But what am I really saying? I'm saying: "All unordered lists should have a background color of red". And the question is: Is that really what I mean? When writing CSS you should keep your structure in mind. Is it right to say all div elements should look a particilar way, or say only divs with a specific class? For example, I would aruge that this might be better:

div.shopping_list h1 { font-weight: bold; font-size: 2em; border-bottom: 1px solid black; }
div.shopping_list ul li { 
    margin-bottom: 1ex;
}

Here, I am saying that these elements, in this particular context should look this particular way.

So in your example, what does a div with a class of test really mean? What is the content? What context are you trying to clarify? Then that will tell you what your style selectors should look like.

For example.

<div class="shopping_list important">
    <h1>My shopping list</h1>
    <ul>
        <li>Bread</li>
        <li>Milk</li>
        <li>Eggs</li>
        <li>Bacon</li>
    </ul>
</div>

<table class="budget">
    <tbody>
        <tr class="important">
            <tr>Account Balance</tr><td>$0.00</td>
        </tr>
</table>

Is a css selector of .important a good idea? Is an "important shopping list" the same thing as an "important table row in a budget table"?

And only you can answer that, depending on what your data is and how you have decided to mark up that data.

There are a bunch of technical topics to get into about CSS specificty, good practices for maintaining complex style sheets, complex associations between elements. But ultimately it all boils down to answering these questions:

  1. What am I trying to communicate? (Data)
  2. What context is the data in? (HTML)
  3. What should that look like? (CSS)

Once you can answer those questions, then everything else will start to fall into place.

Hover box with (vertically and horizontal) centered text

8 votes

I made a on-hover-information-box for an image-mosaic for a client. When the person hovers the image (different orientations, so its flexible sized) he gets another div above it with some informations. The flexibility is the problem: I want the content of the div vertically and horizontal centered. At the moment it looks like this:

.linkbox {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    width: 100%;
    height: 100%;
    color: #fff;
    font-size: 1.9em;
    font-weight: bold;
    background-color: rgba(0, 0, 0, 0.5);
    text-align: center;
}

But I want to the stuff to appear in the middle of the box. So my first thought: padding-top:40%; and a height of (maybe!?) 50% and the rest for the Information. I know I have to make the size in % too but thats just gross. Do you have any idea?

The project is here: http://www.davidgoltz.de/2011/archive/

You have a look at this : Link http://jsfiddle.net/qfXVa/2/

div.linkbox {
    position:absolute;
    top:0;
    left:0;
    width: 100%;
    height: 100%;
    color: #fff;
    font-size: 10px;
    font-weight: bold;
    background-color: rgba(0, 0, 0, 0.5);
    text-align: center;
    display: table;
    vertical-align: middle;
}

div.linkbox div {
    display: table-cell;
    vertical-align: middle;
}

I basically set a container for the text content and aligned it Vertically and Horizontally middle to the parent.

Ordering of vendor-specific CSS declarations

8 votes

I think I've written something like the following a thousand times now:

.foo {
    border-radius: 10px;         /* W3C */
    -moz-border-radius: 10px;    /* Mozilla */
    -webkit-border-radius: 10px; /* Webkit */
}

But only now have I thought about whether the ordering of those is important? I know that between -moz-* and -webkit-* it doesn't matter, since at most 1 of those will be read, but is it better (in terms of future-proofing, etc) to do the W3C standard first or last?

The best practise is undisputedly to have the unprefixed property last:

.foo {
    -moz-border-radius: 10px;    /* Mozilla */
    -webkit-border-radius: 10px; /* Webkit */
    border-radius: 10px;         /* W3C */
}

Whichever is last out of -webkit-border-radius and border-radius will be the one that's used.

-webkit-border-radius is the "experimental" property - the implementation may contain deviations from the specification. The implementation for border-radius will match what's in the specification.

It's preferable to have the "W3C implementation" used when it's available, to ensure consistency between all the browsers that support it.

Why not sprite larger images that are page content?

8 votes

The typical rule of thumb when it comes to using CSS sprites for images is that you should only do it for smaller images (like icons) and that actual image content should always be represented through <img> elements. My question is: why? Aren't the advantages of spriting worthwhile for content images as well?

One reason I have read is to enable the use of alt text, to be more syntactically correct and accessible to screen-readers. However, when that is a concern, couldn't you just as easily use a single tiny transparent image with all the syntactical sugar atop a sprite that presents the real visual content?

You could, but:

  1. Content images don’t tend to be re-used as much as UI-type images like icons. Imagine a newspaper site: if every content image they used were part of a sprite, that sprite would very quickly get huge, and would be downloaded even by users who only looked at one story.

  2. Website content is generally expected to be maintained by people who don’t know CSS. It’s a bit unreasonable to expect content editors to edit a master sprite image file, re-save out to a JPG, and some CSS just to put an image on a page.

  3. If you sprite a lot of large image files, the sprite file is really large. It might take an unacceptably long time to download when the user first visits the page, or it might use up too much bandwidth on users who only end up seeing one of the images within the sprite.

Obviously, those are generalisations — in a specific situation, it might make perfect sense to sprite larger/moe contenty images.

On using an <img> tag with a tiny transparent image file for sprites, you can do that for any sprite images — it’s often useful for clipping and positioning the sprite image beyond what background-position allows.

Is there a way to make Visual Studio 2010 autocomplete selectors based on my HTML markup?

8 votes

Imagine I have this:

<div id="wrapper">
</div>

In my CSS file, when I type in:

#

Is there a way to make Visual Studio show me intellisense of all id's in my HTML markup?

Actually Visual Studio itself doesn't provide an inbuilt functionally to autocomplete classes or ids.

Luckily there is a plugin which is providing this feature: http://www.jetbrains.com/resharper/ I'm using it and it provides me with a list of classes or ids like intellisense.

Proper way to render initially hidden HTML elements

8 votes

I'm for years using something like this in my HTML for elements which should be hidden:

<div style="display: none"></div>

It's ok, but I can't stand in-line styles anymore.

  1. Hiding elements programatically in JavaScript window.onload event is too late -- it will flash on the screen.

  2. I can create CSS class 'hidden', but with browser's aggressive loading strategies (like in Opera) the block may appear for a second (before CSS is loaded).

Is there any better way?

As far as I know the class="hidden" method is the best. If the any browser loads the page before applying styles then a lot would look wrong, not just your hidden elements. I don't know of any browser doing this - but then I don't use Opera.

I suggest you use class="hidden"

How do I make an image start at the bottom of it's container?

8 votes

I have a tall image inside a short container with overflow: hidden;. The bottom of the image is cut off. How do I make the top get cut off instead of the bottom?

dramatized

give the container the following css:

position:relative;

and the image the following css:

position:absolute;
bottom:0px;

P.S.
Very nice (and clear) illustrations btw

How do you manage css stylesheet files and inclusions in a large ruby on rails application?

5 votes

How should you manage the organizing of css files and inclusions in a large ruby on rails application, assuming you're not using a framework? Naturally you'd have your application level styles (e.g. reset.css, applcation.css). But after that what's the best approach? I could see using controller specific sheets or more granular view specific ones (though I don't immediately see how this would be implemented). Are there other sensible options? What would be the pros and cons?

By the way, I'm working in pre 3.1 rails right now, and it seems like the inclusion of the asset pipeline may impact the answer here -- but am happy to hear solutions from either a pre or post asset pipeline perspective.

Thanks!

Moving this into answers because it's (just a bit) hefty for a comment, even though I realize it is not the exact answer you're looking for.

I haven't moved on to rails 3.1 yet, but I have been using Compass/Sass for quite some time, and I can loosely describe my (somewhat ever-changing) practices.

Check out Compass here: http://compass-style.org/

My goal is to be as modular as possible, and separate my styles into categories in several different ways. A sample structure might look like this. I'm embedding comments along with the file hierarchy, so hopefully it's readable.

- stylesheets
    # at top level, the files which are eventually concatenated and output, the main
    # sheet, "screen", a stripped version for a wysywyg editor, and some overrides.
    - screen.scss
    - print.scss
    - ie.scss
    - wysiwg.scss

    # also in this folder I tend to keep a reset
    - _reset.scss

    # and then separated, "includes" and "partials", includes being purely definitions
    # and mixins, while partials being their application (actual CSS output)
    - _includes.scss
    - includes
      - _definitions.scss   # some global variable defs 
      - _typography.scss    # typography mixins and defs
      - _colors.scss        # colors mixins and defs, and so on
      - ...

    - _partials.scss
    - partials
      - _application.scss   # top level layout + tweaks that don't belong anywhere else
      - _typography.scss    # the generation of typography CSS
      - _colors.scss        # the generation of colors CSS, and so on
      - ...

      - _layouts.scss       
      - layouts             # layout specific styles
      - _controllers.scss
      - controllers         # controller specific styles
      - _modules.scss       
      - modules             # modular, reusable pieces (widgets, breadcrumbs, navs, etc)
      - _vendor.scss        
      - vendor              # everything vendor, (jquery-ui, qtip, colorbox)

The basic idea is that everything gets compiled into the top level *.scss files, the only ones which aren't "partials" prefixed with an underscore. These files are very simple, and tend to look like this.

# screen.scss, import all partials
@import 'reset';
@import 'partials';

# wysiwyg.scss doesn't need all the partials, but needs the basic stuff
# and the semantic classes for wysiwyg users, e.g. ".red", etc.
@import 'reset';
@import 'partials/typography';
@import 'partials/colors';
@import 'partials/semantic';

_layouts.scss and other files which share folder names are simple collective imports of the files in their respective directories.

The general idea is that partials stay as thin as possible, with the brunt of the work being done in mixins. Compass thankfully provides a full grab-bag of these as well which I make heavy use of.

For some this type of file structure may be unwieldy, but I find it works well for my purposes. Especially once you get a good library of mixins and swappable partials going. It makes it somewhat easy to tweak a few variable definitions or replace one partial or mixin with another for quick global changes.