This is impossible with pure CSS. We can only work around the situation only when we can recreate the background (and perhaps foreground) with pure CSS, meaning a solid color or maybe a gradient. This is because using opacity
affects the entire element, and cannot go in a direction like you want it to
As a result, I opted to use a pseudo element and some gradients. Since, in my case, the base element is black and the background is white, I created a gradient that fades from black to white for the bottom half then stays white for the top half. You can then make the pseudo element twice as large tall as the original element, place it at top:-200%
, and use transform:translateY(100%)
to essentially fade the element from the top. In reality this is just covering it up in a way that deceives our eyes. All of this is made possible by overflow:hidden
on the element
Demo (webkit & unprefixed only at the moment)
.elem {
width:50px;
height:50px;
background:black;
margin:20px;
overflow:hidden;
position:relative;
}
.elem:before {
content:'';
position:absolute;
height:200%;
width:100%;
top:-200%;
background:white;
background: linear-gradient(to bottom, #ffffff 0%, #ffffff 50%, #000000 100%);
transition:all 0.5s ease;
left:0;
}
.elem:hover:before {
transform:translateY(100%);
}
This tool may help you generate the gradients you need
There is likely a way to do it without pseudo elements using javascript