# Blog

## Reflecting text with pure CSS3

While designing some new site, I’ve decided to use some text reflections on the header in my designs… I’ve already created the header using @font-face and I didn’t want to create an header image, so I thought… hey, just try to imitate the reflection with CSS only.

The HTML code is very straight forward and semantic:

<!-- HTML code -->
<h1 class="reflected">Reflected Text!</h1>


### Flipping the text vertically

I used the :after and :before pseudo-elements to insert the reflection. The tricky part is where you have to flip the reflection-text vertically. This can be done with a CSS 2D transformation. One could write a transformation matrix which does the flipping. However this requires knowledge of Linear Algebra and too difficult for us to handle. The trick is simply using a negative value for scaleY.

For the mathematically challenged who are reading my blog: Here’s an excellent article how those transformation matrices work → and how to create them.

/* CSS code */

.reflected {
position: relative;
}
.reflected:after {
content: 'Reflected Text!';
display: block;
position: absolute;
bottom: -.55em; /* You should change this value to fit your font */
left: 0;
right: 0;
opacity: .5;

/* This is how the text is flipped vertically */
-webkit-transform: scaleY(-1);
-moz-transform: scaleY(-1);
-o-transform: scaleY(-1);
}


Now we have to fade the reflection out. One could use a fade-out png image with alpha transparency, but what’s the fun in that? I researched on cross-browser CSS gradients and found an interesting article at WebDesignerWall →.

/* CSS code */

.reflected:after {
/* Don't forget to change the colors to your background color */
background: -webkit-gradient(linear, left top, left center, from(rgba(255,255,255,0)), to(rgb(255,255,255)));
/* I left out the filter property,
because IE doesn't know :before and :after pseudo-elements anyway */

content: ' ';
display: block;
height: 1em;
position: absolute;
bottom: -.8em;
left: 0;
right: 0;
}


And finally you can simplify the whole CSS by grouping common properties together:

/* CSS code */

.reflected {
position: relative;
}
.reflected:before, .reflected:after {
display: block;
position: absolute;
bottom: -.8em; /* You should change this value to fit your font */
left: 0;
right: 0;
}
.reflected:before {
content: 'Reflected Text!';
opacity: .3;
/* This is how the text is flipped vertically */
-webkit-transform: scaleY(-1);
-moz-transform: scaleY(-1);
-o-transform: scaleY(-1);
}
.reflected:after {
/* Don't forget to change the colors to your background color */
background: -webkit-gradient(linear, left top, left center, from(rgba(255,255,255,0)), to(rgb(255,255,255)));
/* I left out the filter property,
because IE doesn't know :before and :after pseudo-elements anyway */
content: ' ';
height: 1em;
}


### Some inconveniences

As you can see, one can actually make a text reflection with CSS3 only. It just comes with some inflexibleness.

• It only works on a non-changing plain-color background.
• The reflection text is generated using CSS. Which means you have to change the CSS file if you change the corresponding text in the HTML file.
• It doesn’t work on all browsers (e.g. Opera)
• It looks differently on different browsers (see figure below)

### Try it out

2. jean says:

There’s so many cool things happening in webdesign now. Including your site. Thanks!

3. Bryce says:

This is great, not clear on how I can turn off for IE… looks terrible but commenting it out would work, can you provide any update for this?

4. steph says:

YOU ARE A GENIUS! Been looking and looking. Other sites really need to look up the word “mirror” before posting solutions. If I wanted vertical or 90 degrees, that’s what i would say! Mirror is THIS and it works perfectly!!!!

NOW-as Bryce asked, how to turn off for IE?? thanks!

5. Gareth says:

How to turn it off? You can probably use Modenizr to detect the reflection feature and fork your css depending on whether the feature is supported or not.

http://modernizr.com/

6. Jason says:

Thank you very much for this! I looked for this a few months back and couldn’t find it. Looks like you’ve had it out for a while, though.

About backgrounds – To overcome a textured background, I wrapped “.reflected” in a div with a solid background to match the “.reflected:after” color (#color), gave it an over-sized border-radius, and used

box-shadow: 0px 0px 10px 5px #color;

This gave a relatively decent “bubble” to frame my reflected text. #color was just a tad off from my textured background and provided decent relief.

@ steph ~ for IE, use a conditional statement and add a short stylesheet for IE after your other stylesheets with:

.reflected:before  { display:none; }
.reflected:after  { display:none; }

I’ve not used Modernizr, so I can’t comment. When the client isn’t paying extra for IE perfection, I just degrade the experience. Nothing says the web must be consistent for all browsers; some reputable sources even suggest otherwise…

7. Allen Hartwig says:

Works great!

To have it be a bit more dynamic, and keep the content in the HTML, try this:

Reflected Text!

.reflected:before { content: attr(data-value); }

8. Allen Hartwig says:

It ate my HTML…

<. h1 class=”reflected” data-value=”Reflected Text!”>Reflected Text!<. /h1>

9. Allen Hartwig says:

Also, to keep the reflection gradient from interfering with other page content, add this:

.reflected:before { z-index: -10; } .reflected:after { z-index: -5; }

10. JP Hellemons says:

Nice article, I have added the suggestions of Allen Hartwig to my code, but somehow my padding-left and line-height give me strange issues…

11. Mia says:

I love this effect but am struggling with a way to suppress it in IE. I tried adding a second stylesheet for IE and using Jason’s suggestion but cannot get it to work. Would appreciate any advice! .reflected:before { display:none; } .reflected:after { display:none; }