0

I would like to render a border over an image on mouseover, but accomplish it solely with CSS.

My structure is very simple:

<div class="outer">
    <div class="overlay"></div>
    <img />
</div>

The idea is that .overlay gets a 5px border and becomes visible when the mouse hovers over .outer

The image can be of any width / height - it is not known and cannot be specified exclusively.

The only problem is that due to box-model laws i end up with the right and bottom border being rendered outside of .outer because 100% width / height on .overlay already cover the full width of outer.

In order to fully understand what i am trying to explain, please refer to my jsFiddle.

How can i make .overlay be exactly as wide and high as required in order to display the border fully above my image? I am looking for a cross-browser compatible solution, so modifying box-model behaviour for the problematic element does not appear to be an option.

SquareCat
  • 5,699
  • 9
  • 41
  • 75

2 Answers2

1

As opposed to overlaying divs, just use the pseudo element :after. It works for dynamic content and only requires a parent element.

Basically, just set the parent div to display:inline-block to be the same size as the child. Then set the :after content to width:100%/height:100% - thus taking the size of any dynamic image. The HTML is simple, as it only requires a single parent div, no need for an extra overlay class.

jsFiddle here

HTML - extremely simple - no redundancy.

<div>
    <img src="https://si0.twimg.com/profile_images/2704840564/ace6835dc7c12861b013a8f1ac3b1041.png">
</div>

CSS

div {
    display: inline-block;
    background: red;
    position: relative;
}

img {
    vertical-align: top;
}

div:hover:after {
    content: "\A";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: 5px solid black;
    opacity: 0.75;
    background: red;
    z-index: 2;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • 1
    Splendid! Works like a charm as it seems! Thanks! – SquareCat Oct 20 '13 at 00:48
  • I like it, but i fear it may be problematic because of the box-sizing stuff. Its what i meant when saying i didn't want to modify box-model behaviour. I mean, generally i am not entirely closed up to using this solution but.. i don't know, it feels "unsafe". What's your take on this? – SquareCat Oct 20 '13 at 00:52
  • @CummanderCheckov It's completely safe. No drawbacks at all. In fact, this is the most common method of achieving such a thing. But, if you don't like it, that's fine. – Josh Crozier Oct 20 '13 at 00:54
  • @CummanderCheckov Here is the support on box sizing. http://caniuse.com/css3-boxsizing .. If it isn't supported, it isn't a noticeable issue anyways. It works on **all** major browsers. – Josh Crozier Oct 20 '13 at 00:58
1

Instead of width:100%; and height:100%, set the right and bottom positions to 0px.

http://jsfiddle.net/hTECe/3/

Note that by default there will be a small margin below the image. This can be solved by any one of these solutions:

  • Set the image to display:block. (See this question)
  • Set the vertical-align of the image to top, middle, or bottom
  • Set the line-height of the outer frame to 0

CSS

.outer img
{
   display:block;
}

.outer:hover .overlay {
    position: absolute;
    top: 0px;
    left: 0px;
    right:0px;
    bottom:0px;
    border: 5px solid white;
    opacity: 0.75;
}
Community
  • 1
  • 1
Andrew Shepherd
  • 44,254
  • 30
  • 139
  • 205
  • Thanks. I came across this thing as well, as i use the same procedures for creating a full page overlay. But i don't know either why images seem to create a bottom margin or padding by default? Where does this come from? – SquareCat Oct 20 '13 at 00:53
  • @Cummander Checkox - see my edit and the new jsFiddle. The problem was that there was already invisible padding inside the outer frame. – Andrew Shepherd Oct 20 '13 at 00:54
  • Yes, but that shouldn't be the case, right? I wonder, how can one get rid of that padding altogether? – SquareCat Oct 20 '13 at 00:57
  • @Cummander Checkov - I've figured out how to get rid of the padding. See the updated answer – Andrew Shepherd Oct 21 '13 at 01:50