dchapman
dchapman

Reputation: 365

Overlay table cells with two buttons on hover

I have a table as viewed here: http://jsfiddle.net/chapmand/7c7SZ/10/

Essentially, its a calendar. What I want to add to it is, when I mouse over a cell of the table I want an overlay on the cell. The overlay should fill the cell, be transparent, and be split down the middle so that I can make the left side clickable and the right side clickable separately.

The major issue I have been having is getting the overlay to position properly because of the number that is in each cell. The number displaces the overlay so that and breaks the layout. The number should be in the top right corner of each cell.

I have been working on this for a few hours with no success. Any suggestions on what the structure of the data inside each cell should look like and what I need to do with the css to make it display the way I want?

Upvotes: 1

Views: 3797

Answers (2)

mu is too short
mu is too short

Reputation: 434665

To get your <abbr> elements in the upper right corner, you want to use position: absolute; top: 0; right: 0 but that would require position: relative on the <td>; the problem is that not all browsers will allow position: relative on a table cell so so you have to wrap the table cell's content in a <div>:

<td>
    <div class="td-hack">
        <abbr>11</abbr>
    <div>
</td>

And then this (with borders and background colors for illustrative purposes only) will put everything in the right place:

td {
    width: 50px;
    height: 50px;
    background: #eee;
    border: 1px solid red;
}
.td-hack {
    width: 100%;
    height: 100%;
    position: relative;
}
abbr {
    position: absolute;
    top: 0;
    right: 0;
    padding: 2px;
}

The same sort of position: absolute trickery will work for your overlay:

<div class="overlay">
    <div class="o-left"></div>
    <div class="o-right"></div>
</div>

And style it with something like this:

.overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #dfd;
}
.o-left,
.o-right {
    width: 50%;
    height: 100%;
    display: inline-block;
}
.o-left {
    background: #dff;
}
.o-right {
    background: #ffd;
}

Then you just need to append the overlay to .td-hack when the hover starts and remove it when the hover ends; this example uses jQuery to avoid the noise of a raw JavaScript solution:

var overlay = '<div class="overlay">'
            + '<div class="o-left"></div>'
            + '<div class="o-right"></div>'
            + '</div>';
$('td').hover(
    function() {
        $(this).find('.td-hack').append(overlay);
    },
    function() {
        $(this).find('.overlay').remove();
    }
);

A live demo of the technique: http://jsfiddle.net/ambiguous/ah5s3/1/

Upvotes: 2

mVChr
mVChr

Reputation: 50177

I updated your fiddle with a decent way to accomplish this. Here's what I did:

  • changed << and >> to &lt;&lt; and &gt;&gt;
  • corrected a typo in your CSS for vertical-align
  • added position: relative to the CSS for your tbody td
  • Used the following pure Javascript (no jQuery needed) and CSS to add an absolutely positioned div on hover:

var day = document.getElementsByClassName('day'),
    daymouseover = function(e) {
        var elem = document.getElementById('dayhover'),
            skip = /otherMonth/.test(this.className),
            left, right;
        if (!skip) {
            if (!elem) {
                elem = document.createElement('div');
                left = document.createElement('div');
                right = document.createElement('div');
                elem.id = 'dayhover';
                left.className = 'left';
                right.className = 'right';
                elem.appendChild(left);
                elem.appendChild(right);
            }
            this.appendChild(elem);
            elem.style.display = 'block';
        }
    },
    daymouseout = function(e) {
        document.getElementById('dayhover').style.display = 'none';
    };

for (var i = 0, il = day.length; i < il; i++) {
    day[i].onmouseover = daymouseover;
    day[i].onmouseout = daymouseout;
}

#dayhover {
    width:80px;
    position:absolute; left:20px; top:40px;
}
#dayhover .left, #dayhover .right {
    float:left;
    opacity:0.5;
    padding:15px;
}
#dayhover .left {
    background:lime;
}
#dayhover .right {
    background:pink;
}

You will have to adjust the CSS and hover contents as needed, and also implement a cross-browser version of getElementsByClassName. Good luck!

Again, here's the example implementation.

Upvotes: 1

Related Questions