Keep in mind: After experimenting, it appears there may not be a universal solution for achieving this effect across all browsers. It seems that support is limited to WebKit-based browsers only.
In this particular method, a gradient transitioning from transparent to semi-transparent black is utilized as the background for a pseudo-element responsible for creating the reflection effect. The key here is using WebKit's -webkit-background-clip
property to clip the background within the text boundaries.
Unfortunately, the challenge lies in the fact that other browsers do not offer an equivalent property. In those cases, we can set a linear-gradient background for the element and make the text color transparent. However, unlike WebKit browsers, there isn't a way to clip the background solely within the text, as it will cover the entire element.
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
div {
position: relative;
display: inline-block;
font-size: 24px;
}
div:after,
div:before {
position: absolute;
width: 100%;
height: 100%;
bottom: 0px;
left: 0px;
transform: scaleY(-1);
transform-origin: bottom;
}
div:after {
content: attr(data-content);
background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0.5) 80%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div data-content='Reflected Text'>Reflected Text</div>
A Solution Across Browsers:
The following represents my best attempt at finding a cross-browser solution. It involves manually truncating the reflected text by utilizing overflow: hidden
on the parent container, albeit resulting in a less elegant fade effect.
body {
background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
div {
position: relative;
display: inline-block;
font-size: 24px;
height: 1em;
padding-bottom: .5em;
overflow: hidden;
}
div:after {
position: absolute;
content: attr(data-content);
width: 100%;
height: 1em;
top: 0px;
left: 0px;
transform: scaleY(-1);
transform-origin: bottom;
opacity: 0.3;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div data-content='Reflected Text'>Reflected Text</div>
The Original Suggestion:
To achieve this effect, one approach suggested is overlaying a :before
pseudo-element with a gradient background above the existing :after
pseudo-element.
This method is effective when the background is a solid color, as it entails adjusting the gradient colors accordingly. However, the technique may not seamlessly integrate with image or gradient backgrounds.
div {
position: relative;
display: inline-block;
font-size: 24px;
}
div:after,
div:before {
position: absolute;
width: 100%;
height: 100%;
bottom: 0px;
left: 0px;
transform: scaleY(-1);
transform-origin: bottom;
}
div:after {
content: attr(data-content);
}
div:before {
content: '';
background: linear-gradient(to bottom, rgba(0, 128, 0, 1) 30%, rgba(0, 128, 0, 0.7) 70%);
z-index: 2;
}
body {
background: rgb(0, 128, 0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div data-content='Reflected Text'>Reflected Text</div>