Best css questions in March 2012

Why does CSS margin top not work?

24 votes

I try to add margin values on a div inside another div. All works fine except the top value, it seems to be ignored. But why?

What I expected:
What I expected with margin:50px 50px 50px 50px;

What I get:
What I get with margin:50px 50px 50px 50px;

CSS:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:block;
}

HTML:

<div id="outer">
    <div id="inner">
        Hello world!
    </div>
</div>

W3Schools have no explanation to why margin behave this way.

You're actually seeing the top margin of the #inner element collapse into the top edge of the #outer element, leaving only the #outer margin intact (albeit not shown in your images). The top edges of both boxes are flush against each other because their margins are equal.

Here are the relevant points from the W3C spec:

8.3.1 Collapsing margins

In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said to collapse, and the resulting combined margin is called a collapsed margin.

Adjoining vertical margins collapse [...]

Two margins are adjoining if and only if:

  • both belong to in-flow block-level boxes that participate in the same block formatting context
  • no line boxes, no clearance, no padding and no border separate them
  • both belong to vertically-adjacent box edges, i.e. form one of the following pairs:
    • top margin of a box and top margin of its first in-flow child

The reason why floating either of your div elements, setting either of them to inline-block, or setting overflow: auto to #outer prevents the margin collapse is because:

  • Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).
  • Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
  • Margins of inline-block boxes do not collapse (not even with their in-flow children).

The left and right margins behave as you expect because:

Horizontal margins never collapse.

Two CSS Classes: Which one Wins?

11 votes

The markup below aligns SAMPLE TEXT to the left.

To me, it seems like it should be aligned to the right. The class that aligns to the right is declared after the one that aligns left. And the class that aligns to the right is even referenced last. So why does the class that aligns to the left win?

CSS

.table {
    width: 100%;
}
.table td {
    text-align: left;
}
.cell {
    text-align: right;
}

HTML

<table class="table">
    <tr>
        <td class="cell">
             SAMPLE TEXT
        </td>
    </tr>
</table>​

Please see my jsFiddle Example.

The .table td selector has a higher specificity. CSS specificity rules are kind of weird... IDs weigh more than class names, which weigh more than tag names.

The specificity rules, in a nutshell:

  • For each tag name, add 1.
  • For each class name, add 10.
  • For each ID, add 100.

The higher values will always override the lower ones. In the case of a tie, the last rule loaded wins.

Convert rgb color to english color name, like 'green'

11 votes

I want to convert a color tuple to a color name, like 'yellow' or 'blue'

>>> im = Image.open("test.jpg")
>>> n, color = max(im.getcolors(im.size[0]*im.size[1]))
>>> print color
(119, 172, 152)

Is there a simple way in python to do this?

It looks like webcolors will allow you to do this:

rgb_to_name(rgb_triplet, spec='css3')

Convert a 3-tuple of integers, suitable for use in an rgb() color triplet, to its corresponding normalized color name, if any such name exists; valid values are html4, css2, css21 and css3, and the default is css3.

Example:

>>> rgb_to_name((0, 0, 0))
'black'

it is vice-versa-able:

>>> name_to_rgb('navy')
(0, 0, 128)

To find the closest colour name:

However webcolors raises an exception if it can't find a match for the requested colour. I've written a little fix that delivers the closest matching name for the requested RGB colour. It matches by Euclidian distance in the RGB space.

import webcolors

def closest_colour(requested_colour):
    min_colours = {}
    for key, name in webcolors.css3_hex_to_names.items():
        r_c, g_c, b_c = webcolors.hex_to_rgb(key)
        rd = (r_c - requested_colour[0]) ** 2
        gd = (g_c - requested_colour[1]) ** 2
        bd = (b_c - requested_colour[2]) ** 2
        min_colours[(rd + gd + bd)] = name
    return min_colours[min(min_colours.keys())]

def get_colour_name(requested_colour):
    try:
        closest_name = actual_name = webcolors.rgb_to_name(requested_colour)
    except ValueError:
        closest_name = closest_colour(requested_colour)
        actual_name = None
    return actual_name, closest_name

requested_colour = (119, 172, 152)
actual_name, closest_name = get_colour_name(requested_colour)

print "Actual colour name:", actual_name, ", closest colour name:", closest_name

Output:

Actual colour name: None , closest colour name: cadetblue

Is `:not(:hover)` and `:hover` a safe way to hide accessible elements?

11 votes

Sometimes it appears helpful to make certain page elements only visible on e.g. hovers. An example is stackoverflow's "feedback - Was this post useful to you?"-widget. As those elements might be crucial to the interface, such a show-on-hover-feature should be a progressive enhancement or, in other terms, unobtrusive and degrade gracefully.

The usual way appears to be employing javascript, e.g. hiding the elements and making them available when a parent element is hovered. The reason for that choice might be :hover is not support for all elements especially in legacy browsers, thereby forbidding you to hide elements in the first place up to css2. (for a js/jQuery example cf. jquery showing elements on hover)

I wonder if you can achieve such a feature safely* with pure css3, using :not(:hover) and :hover, not affecting older browsers. As far as I can see, the requirement is that every browser supporting :not() must support :hover for all elements. According to the following sources, that appears to be the case

Example implementation: http://jsfiddle.net/LGQMJ/

What do you think? Any objections or other sources?

*by safely I mean the browser should always show all elements as a last resort.

Your solution looks alright for CSS3. There isn't anything I can think of to improve your solution for modern browsers as the opacity property will never be applied by browsers that don't support it anyway.

There is literally no other browser besides IE6 and NN4 (and older) without support for :hover on elements other than a. As implied in your question, all browsers that support :not() are known to also fully support :hover.

That said, you end up leaving IE7 and IE8 missing out on the hover effect, the latter of which is still quite prevalent. You're probably looking to support IE6 as well, but here's a solution that I believe will address these concerns, if you need it:

  1. Omit :not(:hover) altogether so your first selector becomes less specific rather than equally specific to your second selector with :hover, and you can reach out to IE7 and IE8 which don't support :not() but do support :hover on all visual elements:

    div span.question {
        opacity: 0;
    }
    div:hover span.question {
        opacity: 1;
    }
    
  2. Use the visibility property instead of the opacity property to reach out to IE7 and IE8 which don't support CSS3 opacity:

    div span.question {
        visibility: hidden;
    }
    div:hover span.question {
        visibility: visible;
    }
    
  3. Use CSS2/3 combinators that IE6 doesn't support but IE7 and IE8 do (child >, adjacent sibling +, general sibling ~) to hide both rules from IE6. This borders on "hacky", but your situation is one where the child combinator > fits very well, so it can be integrated organically rather than hacked in like the famous html > body filter:

    div > span.question {
        visibility: hidden;
    }
    div:hover > span.question {
        visibility: visible;
    }
    

Updated fiddle

Make a div nested in a jQuery UI dialog resize with the dialog?

10 votes

My jQuery UI dialog contains two div elements. One has a fixed height and should be aligned at the bottom of the dialog at all times. The other one should take up the remaining space.

enter image description here

Basically I’d like all the dimensions highlighted in blue to remain unchanged on resize. Or, in other words, the red div resizes in both dimensions but the green div keeps its height.

What’s the easiest way to do this in jQuery UI or even just plain CSS?

I’ve found a way to do this that doesn’t use any JavaScript. It doesn’t even involve any hacks; just plain normal CSS3. Fiddle here: http://jsfiddle.net/nty5K/16/

Basically, both divs are position: absolute, and each of the sides is anchored individually using the top, bottom, left and right properties. The top div has all four positions specified, making it resize with the container while preserving the exact distance to each edge of the container. The bottom div has three of the positions fixed, whereas the top is defined only indirectly, via a fixed height.

In practice, the divs will need to be placed into a wrapper div that has position: relative, otherwise the top/bottom divs will be positioned relative to the body element.

Not sure about browser compatibility yet, but this worked fine in Firefox 10, IE9 and Chrome 17. Didn’t test this in earlier versions.

Painless css3 writing

10 votes

When I want to create a gradient background in css3 I have to do this:

background-color: #3584ba;
background-image: -webkit-gradient(linear, left top, left bottom, from(#54a0ce), to(#3584ba)); /* Safari 4+, Chrome */
background-image: -webkit-linear-gradient(top, #54a0ce, #3584ba); /* Safari 5.1+, Chrome 10+ */
background-image:    -moz-linear-gradient(top, #54a0ce, #3584ba);  /* FF3.6 */
background-image:      -o-linear-gradient(top, #54a0ce, #3584ba); /* Opera 11.10+ */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#54a0ce', endColorstr='#3584ba'); /* IE */

and this is really annoying. Is there a better solution, for example a jquery plugin, that will make my code cross browser compatible, if I just use:

background-image: -webkit-linear-gradient(top, #54a0ce, #3584ba); /* Safari 5.1+, Chrome 10+ */

for example? Is there a tool to help me write css3 code more easy?

There are many tools for this:

These are generally referred to as CSS Preprocessors.

You would end up writing something like this once, like a function definition (usually called a "mixin"):

.linear-gradient(@start, @end) {
    background-color: @end;
    background-image: -webkit-gradient(linear, left top, left bottom, from(@start), to(@end)); /* Safari 4+, Chrome */
    background-image: -webkit-linear-gradient(top, @start, @end); /* Safari 5.1+, Chrome 10+ */
    background-image:    -moz-linear-gradient(top, @start, @end);  /* FF3.6 */
    background-image:      -o-linear-gradient(top, @start, @end); /* Opera 11.10+ */
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='@start', endColorstr='@end'); /* IE */
}

Then to apply:

.my-class {
    .linear-gradient(#54a0ce, #3584ba);
}
.my-other-class {
    .linear-gradient(#ccc, #aaa);
}

Highly recommend.

Bottom to top <ul> element arrangement

9 votes

I'm trying to find out how I can force elements to start from the bottom going to the top.

I have searched through stackoverflow and I can't seem to get the answer that i need. This picture should explain it:

explanation image

This should help too:

<?php require("connectdb.php"); ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery Dynamic Drag'n Drop</title>
<script type="text/javascript" src="javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="javascript/jquery-ui-1.7.1.custom.min.js"></script>
<script type="text/javascript" src="javascript/jquery.ui.ipad.altfix.js"></script>


<style>
body {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 16px;
    margin-top: 10px;
}

ul {
    margin: 0;
}

#contentWrap {
    width: 800px;
    margin: 0 auto;
    height: 500px;
    overflow: hidden;
    background-color: #FFFFFF;
    border: solid 2px #EEEEEE;
}

#contentTop {
    width: 600px;
    padding: 10px;
    margin-left: 30px;
}

#sortable { list-style-type: none; margin: 0; padding: 0;}

#sortable li { margin: 20px 20px 1px 20px; 
padding: 1px;
 float: left; 
 width: 70px; 
 height: 70px; 
 font-size: 12px;
 text-align: center; 
 background-color:#cfcfcf;
 position: absoute;
 bottom: 0;
 display: inline-block;
 float: right;
 }


#contentRight {
    float: right;
    width: 300px;
    margin-top: 100px;
    padding:10px;
    background-color:#336600;
    color:#FFFFFF;
}

#save
{    
    width: 100px;
    height: 30px;
    margin-right: auto;
    margin-left: auto;
    background-color:#336600;
    color:#FFFFFF;
    text-align: center;
}
.on { background-color:#000000; color:#782322; }

            #header{
                background-color: #EEEEEE;
                font-weight: bold;
                width: 804px;
                margin-left: auto ;
                margin-right: auto ;
                padding: 2;
            }
</style>


<script type="text/javascript">
//$(document).ready(function(){ 



    $(function() {

    $(document).bind('touchmove', function(e) {
        e.preventDefault();
    }, false);  

        $("#sortable").sortable({ opacity: 0.6, cursor: 'move', update: function()     {
            var order = $(this).sortable("serialize") +     '&action=updateRecordsListings'; 
            $.post("updateDB.php", order, function(theResponse){
            });                                                              
        }                                 
        }).addTouch();
        $( "#sortable" ).disableSelection();

        //$("li").click(function(){
            //$(this).addClass("on");
        //});   
    });

//});   
</script>

</head>
<body>
    <?php 
        session_start();
        $teacherID = $_SESSION['teacherID'];
        $classID = $_SESSION['csID'];
        $qryClass = "SELECT * FROM class_schedule WHERE csID = '". $classID ."';";
        $class = mysql_query($qryClass);
        while($row = mysql_fetch_array($class))
        {
            $subjCode = $row['subjCode'];
            $section = $row['section'];
            $semester = $row['semester'];
            $sy = $row['SY'];
            $time = $row['time'];
        }
    ?>
    <div id = "header">
        <?php 
            //echo "What do you want to do, " .$fname . "?<br>";
            echo "Subject: " . $subjCode . " Block: " . $section . " -     Semester:" . $semester . " - SY:" . $sy . " - " . $time;
        ?>
    </div>
    <div id="contentWrap">
            <ul id="sortable">
                <?php
                session_start();
                $query  = "SELECT e.*, CONCAT(s.lname,', ', s.fname) name     FROM enrollment e, student s
WHERE e.studentID = s.studentID AND e.csID = '". $classID ."' ORDER BY sort;";
                $result = mysql_query($query);
                $c = 0;
                while($row = mysql_fetch_array($result, MYSQL_ASSOC))
                {
                    //if($c != 4)
                        echo "<li id='recordsArray_'"     . $row['id'] . ">" . $row['name'] . "</li>";
                }
                ?>
            </ul>       

    </div>
    <div id="save">
        Blackboard
    </div>


</body>
</html>

A css solution fiddle

ul, ul li {
-webkit-transform: scaleY(-1);
   -moz-transform: scaleY(-1);
    -ms-transform: scaleY(-1);
     -o-transform: scaleY(-1);
        transform: scaleY(-1);

}
ul {
    width: 350px;
}
 li {
    display: inline-block;
    width: 70px;
    zoom: 1;         
    *display: inline;
}

This works by flipping the entire UL and then each LI on it's Y axis.

Save object states in .data or attr - Performance vs CSS?

9 votes

In response to my answer yesterday about rotating an Image, Jamund told me to use .data() instead of .attr()

First I thought that he is right, but then I thought about a bigger context... Is it always better to use .data() instead of .attr()? I looked in some other posts like what-is-better-data-or-attr or jquery-data-vs-attrdata

The answers were not satisfactory for me...

So I moved on and edited the example by adding CSS. I thought it might be useful to make a different Style on each image if it rotates. My style was the following:

.rp[data-rotate="0"] {
    border:10px solid #FF0000;
}
.rp[data-rotate="90"] {
    border:10px solid #00FF00;
}
.rp[data-rotate="180"] {
    border:10px solid #0000FF;
}
.rp[data-rotate="270"] {
    border:10px solid #00FF00;
}

Because design and coding are often separated, it could be a nice feature to handle this in CSS instead of adding this functionality into JavaScript. Also in my case the data-rotate is like a special state which the image currently has. So in my opinion it make sense to represent it within the DOM.

I also thought this could be a case where it is much better to save with .attr() then with .data(). Never mentioned before in one of the posts I read.

But then i thought about performance. Which function is faster? I built my own test following:

<!DOCTYPE HTML>
<html>
<head>
<title>test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
function runfirst(dobj,dname){
  console.log("runfirst "+dname);
  console.time(dname+"-attr");
  for(i=0;i<10000;i++){
    dobj.attr("data-test","a"+i);
  }
  console.timeEnd(dname+"-attr");
  console.time(dname+"-data");
  for(i=0;i<10000;i++){
    dobj.data("data-test","a"+i);
  }
  console.timeEnd(dname+"-data");
}
function runlast(dobj,dname){
  console.log("runlast "+dname);
  console.time(dname+"-data");
  for(i=0;i<10000;i++){
    dobj.data("data-test","a"+i);
  }
  console.timeEnd(dname+"-data");
  console.time(dname+"-attr");
  for(i=0;i<10000;i++){
    dobj.attr("data-test","a"+i);
  }
  console.timeEnd(dname+"-attr");  
}
$().ready(function() {
  runfirst($("#rp4"),"#rp4");
  runfirst($("#rp3"),"#rp3");
  runlast($("#rp2"),"#rp2");
  runlast($("#rp1"),"#rp1");
});
</script>
</head>
<body>
    <div id="rp1">Testdiv 1</div>
    <div id="rp2" data-test="1">Testdiv 2</div>
    <div id="rp3">Testdiv 3</div>
    <div id="rp4" data-test="1">Testdiv 4</div>
</body>
</html>

It should also show if there is a difference with a predefined data-test or not.

One result was this:

runfirst #rp4
#rp4-attr: 515ms
#rp4-data: 268ms
runfirst #rp3
#rp3-attr: 505ms
#rp3-data: 264ms
runlast #rp2
#rp2-data: 260ms
#rp2-attr: 521ms
runlast #rp1
#rp1-data: 284ms
#rp1-attr: 525ms

So the .attr() function did always need more time than the .data() function. This is an argument for .data() I thought. Because performance is always an argument!

Then I wanted to post my results here with some questions, and in the act of writing I compared with the questions Stack Overflow showed me (similar titles)

And true enough, there was one interesting post about performance

I read it and run their example. And now I am confused! This test showed that .data() is slower then .attr() !?!! Why is that so?

First I thought it is because of a different jQuery library so I edited it and saved the new one. But the result wasn't changing...

So now my questions to you:

  • Why are there some differences in the performance in these two examples?
  • Would you prefer to use data- HTML5 attributes instead of data, if it represents a state? Although it wouldn't be needed at the time of coding? Why - Why not?

Now depending on the performance:

  • Would performance be an argument for you using .attr() instead of data, if it shows that .attr() is better? Although data is meant to be used for .data()?

UPDATE 1:
I did see that without overhead .data() is much faster. Misinterpreted the data :) But I'm more interested in my second question. :)

Would you prefer to use data- HTML5 attributes instead of data, if it represents a state? Although it wouldn't be needed at the time of coding? Why - Why not?

Are there some other reasons you can think of, to use .attr() and not .data()? e.g. interoperability? because .data() is jquery style and HTML Attributes can be read by all...

UPDATE 2:

As we see from T.J Crowder's speed test in his answer attr is much faster then data! which is again confusing me :) But please! Performance is an argument, but not the highest! So give answers to my other questions please too!

UPDATE 3:

My test seems to be false because of the fire-bug I used while testing! The same file in chrome listed attr faster and a second test on jsperf also says attr is faster

This performance part of the question screams of premature optimization; see below. (Lest you get the wrong idea: I too am frequently guilty of wondering about the same sort of premature optimization question.)

But getting performance out of the way (other points addressed below the graph): As far as I can see, attr is faster than data in jQuery 1.7.1: http://jsperf.com/jquery-setting-attr-vs-data This surprises me. Not that it's remotely likely to matter.

Gratuitous bar graph (longer lines = faster performance):

Gratuitous bar graph from jsperf

Are there some other reasons you can think of, to use .attr() and not .data()?

At least a couple come to mind:

  1. The advantage of data is that it doesn't have to write to the element every time; you only write to the actual element the first time, and from then on jQuery is just updating a value in a JavaScript object it maintains in a separate object cache (connected to the element via a key). (I'm not sure why it's slower than attr; perhaps because of the indirection.)

  2. One thing I dislike about data is that it's not symmetrical: The first time you access data on an element, the data object is seeded with data-* attributes from the element; but from there on out, there is no connection between the two.

    Example (live copy | live source):

    var target = $("#target");
    display("data('foo'): " + target.data("foo"));
    display("data-foo: " + target.attr("data-foo"));
    display("Setting data('foo')");
    target.data("foo", "updated data('foo')");
    display("data('foo'): " + target.data("foo"));
    display("data-foo: " + target.attr("data-foo"));
    display("Setting data-foo");
    target.attr("data-foo", "updated data-foo");
    display("data('foo'): " + target.data("foo"));
    display("data-foo: " + target.attr("data-foo"));
    

    Assuming the #target element starts out with data-foo="bar", the output is:

    data('foo'): bar
    data-foo: bar
    Setting data('foo')
    data('foo'): updated data('foo')
    data-foo: bar
    Setting data-foo
    data('foo'): updated data('foo')
    data-foo: updated data-foo

    That can be confusing and surprising. The way you have to think about it is that the data-* attributes are default values only. I just don't like how they're so dependent on whether you've called data before or not; unless you never write to the data-* attribute directly, you can't be sure what value data will get (the original from the markup, or a value you updated later before you called data). It seems a bit chaotic to me, but if you set yourself rules (never write to data-* attributes directly and only ever use data, for instance), you can avoid the chaos.

  3. When you use attr, you can only store strings. When you use data, you can store any JavaScript value or object reference.


Because performance is always an argument!

Not in 2012. :-) Or at least, it's a lot lower down the list relative to other arguments than it used to be absent a specific, demonstrable performance problem.

Let's look at your runfirst #rp4 results: 10k iterations of attr took 515ms; 10k iterations of data took 268ms. That's 51.5 usec (microseconds, millionths of a second) each vs. 26.8 usec each. So you're wondering whether to use data if it saves you 24.7 usec per operation. Humans perceive things on the order of tenths of seconds. So for it to matter, you have to do this op roughly 4,000 times in a tight loop for a human to notice the difference. That's just not even close to worth worrying about, even in a mousemove handler.

If you're into that kind of territory (4,000/second in a tight loop), you'll probably want to avoid storing the information on the element at all.

Why in CSS does '!' in have the opposite meaning to its use in C-based languages?

9 votes

For example, in JavaScript, !important means 'not important'. In CSS, it means 'this is important'.

Are there languages other than CSS where an exclamation mark is used for affirmation rather than negation? Why was the '!' chosen in CSS?

EDIT

I don't know if it's a coincidence, but ! is the earliest non-system and non-whitespace character in the ASCII table (at #32). In terms of parsing, would that make it quicker?

! is more of an escape character than it is an operator. It is part of important, rather than a separate piece (e.g. in JavaScript I'd see this as ! and somevar, whereas in CSS I see this as !important). So, it isn't so much affirmation as you put it; it just so happens to be the character they chose to throw in front of the keyword important.

Also, in non-programming languages, ! is often used to draw attention to something, although it is often accompanied by some other sort of shape/symbol as well (e.g. ⚠), and this is likely the reason why ! was chosen. It may be helpful to see it as important! or ¡important! (!important is just easier to parse and type than the alternatives).

Edit: As noted by @mike-samuel: "The lexical scanner section of the CSS2.1 grammar spec lists !important as a single token ("!"({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T} {return IMPORTANT_SYM;}) although it does allow whitespace and comments between the ! and important."

How is text thickness calculated according to css property "font-weight"?

7 votes

Font weight in Firefox:

font-weight in firefox

Font weight in Chrome:

font-weight in chrome

The font-weight value is in the order of 100,500,600,700,900, which is set according to the W3C standard.

You can clearly see that the text thickness is not changed linearly, and in different browser not exactly the same (it's almost the same from 100 to 500.). So I wonder, is there a standard on how the text is calculated according to font-weight?

The algorithm, at least in theory, is: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-weight

The CSS3 specification is similar - http://www.w3.org/TR/css3-fonts/#font-weight-prop

As it states, bold faces are often synthesized by user agents for faces that lack actual bold faces.

I've found its often better to avoid font-weights all together, and use a specific font face.

Can you create this shadowed gradient style line using CSS3?

7 votes

Here's a picture of exactly what I'm trying to produce.

I've been able to style a <hr /> using SVG as the background image to create this effect, but would like to be able to produce the same thing using CSS3 I've but have been having trouble.

I was wondering if any CSS gurus out there might know a way to achieve the same thing or if it's not really possible w/ pure CSS?

Thanks for any help.

I create the effect which you want please check this:

http://jsfiddle.net/fx5Lk/

How to make hovering over one div to trigger changes in another div?

7 votes

I am looking to create the next effect for my next website:

  1. I have 3 DIVs with some text content in the left column.
  2. I have an image in a div in the right column.
  3. Image in the right div have 3 different independent image parts, each separate part has to be highlighted when I hover over one of the divs (related to that particular image part) in the column on the left. The DIV I am hovering over has to be highlighted as well on hover.
  4. I also want the same effect only this time when I hover over any of those image parts in DIV on in the right column. I want it to highlight the related div, as well as highlight image part itself.

I know it all might sound really confusing, so I made a picture hopefully explaining my project visually. (check the attached image).

Now I am not sure if this can be solely achieved with use of only CSS, or by combination of CSS and jQuery or smn.

If anyone ever encountered similar implementation, or knows where I can find a code example, or could direct me in the right direction, I would really appreciate it!!!

You could set up mouseover bindings on your continent image and its corresponding div on the left:

$('.div1').mouseover(hoverOne);
$('.continent1').mouseover(hoverOne);
var hoverOne = function(){
    //hightlight elements
}

//lather...rinse...repeat for the rest

How to get actual (not original) height of a CSS-rotated element

6 votes

I need to obtain actual height of several different elements (for the sake of precise custom tooltip positioning), and some of these elements (not all) are rotated. $(elem).outerHeight() returns the original height, instead of the actual displayed height.

Here's the fiddle with a very simple example: http://jsfiddle.net/NPC42/nhJHE/

I see a possible solution in this answer: http://stackoverflow.com/a/8446228/253974, but am still hoping there is a simpler way.

Dusting off my high school geometry and my formidable graphics skills, I put this diagram together. If you have variables width, height, and rotation in javascript, you could express the height this way:

var rotated_height = width * Math.sin(rotation) + height * Math.cos(rotation);

enter image description here

Can this navigation be done completely in CSS

6 votes

I am a little stuck. I have created almost everything in the picture below. What I am stuck on is I am trying to figure out how I would set it up so that when a user clicks one of the links it makes the line below become red (after the next page loads). Obviously I would need to use Jquery to detect the page then add inline css, but what I am struggling with is I want this to be as easy as possible so that I can give this template to others and then they can add or remove items as necessary. I was trying to figure out if I could somehow use a li element to do this but I have not found a way yet. Does anyone have any ideas to help me?

enter image description here

Build your menu like this, in HTML:

<body id='Search' >
    <div id='menu'>
        <div class='bars'></div>
        <a href='/home/' title='Home'>Home</a>
        <a href='/community/' title='Community'>Community</a>
        <a href='/search/' title='Search'>Search</a>
        <a href='/contact/' title='Contact'>Contact</a>
        <div class='bars shift'></div>            
    </div>
</body>

Note that the body tag has a page-specific id (as Cody suggests). Also note that this id must be the same as the value of the title attribute for the menu link.

Then use this CSS:

.bars {border-top:1px solid #CCC;border-bottom:1px solid #CCC;height:5px;}
.shift {margin-top:-6px;}
#menu {font-family:arial;font-size:12pt;text-align:center;}    
#menu a {display:inline-block;padding:7px;text-decoration:none;color:#000;}
.active {border-bottom:5px solid red;}

Finally, add this jQuery to each page:

$(document).ready(function(){
    var id = $('body').attr('id');
    $('#menu a').each(function () {
        var title = $(this).attr('title');
        $(this).removeClass('active');
        if (title == id) $(this).addClass('active');
    });
});

You can see a live fiddle demo here. (To test, just change the id of the body element and press run.)

EDIT: The benefits of this method compared to Cody Grays' method is that you don't need to modify the css every time you change the HTML when you add, remove or edit a menu item. On the other hand it uses jQuery. However, if you want a pure css solution, just remove the jQuery, and the id of the body element, and instead directly apply the .active class to the particular link, depending on the particular page (similar to jackJoe's suggestion).

This can easily be modified if you must use <li> elements.