[css] Inner text shadow with CSS

I am currently playing around with CSS3 and trying to achieve a text effect like this (the black blurry inner shadow):

But I cannot find a way to create text shadows inside the text. I wonder whether it is still possible because the box-shadow element is able to render shadow inside like this:

box-shadow: inset 0px -5px 10px 0px rgba(0, 0, 0, 0.5);

Any ideas?

This question is related to css text shadow

The answer is


Building on the :before :after technique by web_designer, here is something that comes closer to your look:

First, make your text the color of the inner shadow (black-ish in the case of the OP).

Now, use an :after psuedo class to create a transparent duplicate of the original text, placed directly on top of it. Assign a regular text shadow to it with no offset. Assign the original text color to the shadow, and adjust alpha as needed.

http://dabblet.com/gist/2499892

You don't get complete control over spread, etc. of the shadow like you do in PS, but for smaller blur values it is quite passable. The shadow goes past the bounds of the text, so if you are working in an environment with a high contrast background-foreground, it will be obvious. For lower contrast items, especially ones with the same hue, it's not too noticeable. For example, I've been able to make very nice looking etched text in metal backgrounds using this technique.


I've seen many of the proposed solutions, but none were quite what I was hoping.

Here's my best hack at this, where the color is transparent, the background and the top text-shadow are the same color with varying opacities, simulating the mask, and the second text-shadow is a darker, more saturated version of the color you actually want (pretty easy to do with HSLA).

enter image description here

(btw, text and styling based upon a dupe thread's OP)


This is easily the best example I have seen. http://lab.simurai.com/carveme/

The source is on gitthub https://github.com/simurai/lab/tree/gh-pages/carveme


Here's my best try:

_x000D_
_x000D_
    .inner_shadow {_x000D_
    color:transparent;_x000D_
    background-color:white;_x000D_
    text-shadow: 0 0 20px rgba(198,28,39,0.8), 0 0 0 black;_x000D_
    font-family:'ProclamateHeavy';  // Or whatever floats your boat_x000D_
    font-size:150px;_x000D_
    }
_x000D_
   _x000D_
    <span class="inner_shadow">Inner Shadow</span>_x000D_
   
_x000D_
_x000D_
_x000D_

The problem is how to clip the shadow that bleeds around the edges!!! I tried in webkit using background-clip:text, but webkit renders the shadow above the background so it doesn't work.

Making a Text Mask with CSS?

Without a top mask layer it is impossible to do a true inner shadow on text.

Perhaps someone should recommend that the W3C add background-clip: reverse-text, that would cut a mask through the background instead of cutting the background to fit inside the text.

Either that or render the text-shadow as part of the background and clip it with background-clip: text.

I tried absolutely positioning an identical text element above it, but the problem is background-clip: text crops the background to fit inside the text, but we need the reverse of that.

I tried using text-stroke: 20px white; on both this element and the one above it, but the text stroke goes in as well as out.

Alternate Methods

Since there is currently no way to make an inverted-text mask in CSS, you could turn to SVG or Canvas and make a text replacement image with the three layers to get your effect.

Since SVG is a subset of XML, SVG text would still be select-able and searchable, and the effect can be produced with less code than Canvas.

It would be harder to achieve this with Canvas because it doesn't have a dom with layers like SVG does.

You could produce the SVG either server-side, or as a javascript text-replacement method in the browser.

Further Reading:

SVG versus Canvas:

http://dev.opera.com/articles/view/svg-or-canvas-choosing-between-the-two/

Clipping and Masking with SVG Text:

http://www.w3.org/TR/SVG/text.html#TextElement


Here is a link talking about how to do this, it should be what you are looking for:

http://sixrevisions.com/css/how-to-create-inset-typography-with-css3/


There's a much simpler way to achieve this

.inner{color: red; text-shadow: 0 -1px 0 #666;} // #666 is the color of the inner shadow

VoilĂ 


There's no need for multiple shadows or anything fancy like that, you just have to offset your shadow in the negative y-axis.

For dark text on a light background:

text-shadow: 0px -1px 0px rgba(0, 0, 0, .75);

If you have a dark background then you can simply invert the color and y-position:

text-shadow: 0px 1px 0px rgba(255, 255, 255, 0.75);

Play around with the rgba values, the opacity, and the blur to get the effect just right. It will depend a lot on what color font and background you have, and the weightier the font, the better.


Try this little gem of a variation:

text-shadow:0 1px 1px rgba(255, 255, 255, 0.5);

I usually take "there's no answer" as a challenge


An elegant example without the need for a positioned wrapper or duplicative content in the markup:

_x000D_
_x000D_
:root {_x000D_
  background: #f2f2f2;_x000D_
}_x000D_
h1 {_x000D_
  background-color: #565656;_x000D_
  font: bold 48px 'Futura';_x000D_
  color: transparent;_x000D_
  text-shadow: 0px 2px 3px rgba(255, 255, 255, 0.8);_x000D_
  -webkit-background-clip: text;_x000D_
  -moz-background-clip: text;_x000D_
  background-clip: text;_x000D_
}
_x000D_
<center>_x000D_
  <h1>Text With Inner Shadow</h1>_x000D_
</center>
_x000D_
_x000D_
_x000D_

Looks good on dark backgrounds as well:

_x000D_
_x000D_
:root {_x000D_
  --gunmetal-gray: #2a3439;_x000D_
  background: var(--gunmetal-gray);_x000D_
}_x000D_
_x000D_
h1[itemprop="headline"] {_x000D_
  font-family: 'Futura';_x000D_
  font-size: 48px;_x000D_
  padding-bottom: 0.35rem;_x000D_
  font-variant-caps: all-small-caps;_x000D_
  background-color: var(--gunmetal-gray);_x000D_
  color: transparent;_x000D_
  text-shadow: 0px 2px 3px rgba(255, 255, 255, 0.1);_x000D_
  -webkit-background-clip: text;_x000D_
  -moz-background-clip: text;_x000D_
  background-clip: text;_x000D_
  filter: brightness(3);_x000D_
}
_x000D_
<center>_x000D_
  <h1 itemprop="headline">Text With Inner Shadow</h1>_x000D_
</center>
_x000D_
_x000D_
_x000D_

AND ME LINK AND ME2 LINK


You can kind of do this. Unfortunately there's no way to use an inset on text-shadow, but you can fake it with colour and position. Take the blur right down and arrange the shadow along the top right. Something like this might do the trick:

background-color:#D7CFBA;
color:#38373D;
font-weight:bold;
text-shadow:1px 1px 0 #FFFFFF;

... but you'll need to be really, really careful about which colours you use otherwise it will look off. It is essentially an optical illusion so won't work in every context. It also doesn't really look great at smaller font sizes, so be aware of that too.


You should be able to do it using the text-shadow, erm somethink like this:

.inner_text_shadow
{
    text-shadow: 1px 1px white, -1px -1px #444;
}

here's an example: http://jsfiddle.net/ekDNq/


I've had a few instances where I've needed inner shadows on text, and the following has worked out well for me:

.inner {
    color: rgba(252, 195, 67, 0.8);
    font-size: 48px;
    text-shadow: 1px 2px 3px #fff, 0 0 0 #000;
}

This sets the opacity of the text to 80%, and then creates two shadows:

  • The first is a white shadow (assuming the text is on a white background) offset 1px from the left and 2px from the top, blurred 3px.
  • The second is a black shadow which is visible through the 80% opacity text but not through the first shadow, which means it's visible inside the text letters only where the first shadow is displaced (1px from the left and 2px from the top). To change the blur of the this visible shadow, modify the blur parameter for the first layer shadow.

Caveats

  • This will only work if the desired color of the text can be achieved without it having to be at 100% opacity.
  • This will only work if the background color is solid (so, it won't work for the questioner's specific example where the text sits on a textured background).

Here's a great solution for TRUE inset text shadow using the background-clip CSS3 property:

.insetText {
    background-color: #666666;
    -webkit-background-clip: text;
    -moz-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: rgba(255,255,255,0.5) 0px 3px 3px;
}

This looks like it's working: http://tips4php.net/2010/08/nice-css-text-shadow-effects/

He's using multiple shadows to achieve that effect as explained here: http://www.w3.org/Style/Examples/007/text-shadow#multiple


I'm using it from this site, also it looks good. Have a look at it Inner shadow


Here's what I came up with after looking at some of the ideas here. The main idea is that the color of the text blends with both shadows, and note that this is being used on a grey background (otherwise the white won't show up well).

.inset {
    color: rgba(0,0,0, 0.6);
    text-shadow: 1px 1px 1px #fff, 0 0 1px rgba(0,0,0,0.6);
}

More precise explanation of the CSS in kendo451's answer.

There's another way to get a fancy-hacky inner shadow illusion,
which I'll explain in three simple steps. Say we have this HTML:

<h1>Get this</h1>

and this CSS:

h1 {
  color: black;
  background-color: #cc8100;
}

It's a good slogan

Step 1

Let's start by making the text transparent:

h1 {
  color: transparent;
  background-color: #cc8100;
}

It's a box

Step 2

Now, we crop that background to the shape of the text:

h1 {
  color: transparent;
  background-color: #cc8100;
  background-clip: text;
}

The background is the text!

Step 3

Now, the magic: we'll put a blurred text-shadow, which will be in front of the background, thus giving the impression of an inner shadow!

h1 {
  color: transparent;
  background-color: #cc8100;
  background-clip: text;
  text-shadow: 0px 2px 5px #f9c800;
}

We got it! Yay!

See the final result.

Downsides?

  • Only works in Webkit (background-clip can't be text).
  • Multiple shadows? Don't even think.
  • You get an outer glow too.

For normal-sized text on small-ish buttons

I found the other ideas on this page to lose their efficacy when used on small buttons with small text lettering. This answer expands on RobertPitt's answer.

Here is the minor tweak:

text-shadow: 1px 1px transparent, -1px -1px black;

_x000D_
_x000D_
$('button').click(function(){
  $('button').removeClass('btnActive');
  $(this).addClass('btnActive');
});
_x000D_
body{background:#666;}
.btnActive{
  border: 1px solid #aaa;
  border-top: 1px solid #333;
  border-left: 1px solid #333;
  color: #ecf0f8;
  background-color: #293d70;
  background-image: none;
  text-shadow: 1px 1px transparent, -1px -1px black;
  outline:none;
}

button{
  border: 1px solid #446;
  border-radius: 3px;
  color: white;
  background-color: #385499;
  background-image: linear-gradient(-180deg,##7d94cf,#1c294a 90%);
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  padding: 6px 12px;
  xxtext-shadow: 1px 1px 2px navy;
}
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btnActive">Option One</button>
<button>Option Two</button>
_x000D_
_x000D_
_x000D_

Note:

I used this site to finesse the color shades.


Here's a little trick I discovered using the :before and :after pseudo-elements:

.depth {
    color: black;
    position: relative;
}
.depth:before, .depth:after {
    content: attr(title);
    color: rgba(255,255,255,.1);
    position: absolute;
}
.depth:before { top: 1px; left: 1px }
.depth:after  { top: 2px; left: 2px }

The title attribute needs to be the same as the content. Demo: http://dabblet.com/gist/1609945


Try this example for inset text shadow. Here's the HTML

<h1 class="inset-text-shadow">Inset text shadow trick</h1>

and the CSS

body {
    background: #f8f8f8;
}
h1 {
    font-family: Helvetica, Arial, sans-serif;
    font-weight: bold;
    font-size: 6em;
    line-height: 1em;
}
.inset-text-shadow {
    /* Shadows are visible under slightly transparent text color */
    color: rgba(0,0,0,0.6);
    text-shadow: 2px 8px 6px rgba(0,0,0,0.2), 0px -5px 35px rgba(255,255,255,0.3);

}

Demo on Jsfiddle


text-shadow: 4px 4px 2px rgba(150, 150, 150, 1);

for box shadow:

-webkit-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
-moz-box-shadow:    7px 7px 5px rgba(50, 50, 50, 0.75);
box-shadow:         7px 7px 5px rgba(50, 50, 50, 0.75);

you can see online text and box shadow: online text and box shadow

for more example you can go to this address : more example code freeclup


Seems everyone's got an answer to this one. I like the solution from @Web_Designer. But it doesn't need to be as complex as that and you can still get the blurry inner shadow you're looking for.

http://dabblet.com/gist/3877605

.depth {
    display: block;
    padding: 50px;
    color: black;
    font: bold 7em Arial, sans-serif;
    position: relative;
 }

.depth:before {
    content: attr(title);
    color: transparent;
    position: absolute;
    text-shadow: 2px 2px 4px rgba(255,255,255,0.3);
}

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to text

Difference between opening a file in binary vs text How do I center text vertically and horizontally in Flutter? How to `wget` a list of URLs in a text file? Convert txt to csv python script Reading local text file into a JavaScript array Python: How to increase/reduce the fontsize of x and y tick labels? How can I insert a line break into a <Text> component in React Native? How to split large text file in windows? Copy text from nano editor to shell Atom menu is missing. How do I re-enable

Examples related to shadow

How to remove button shadow (android) Android "elevation" not showing a shadow Android View shadow box-shadow on bootstrap 3 container How to provide shadow to Button What's the best way to add a drop shadow to my UIView How can I add a box-shadow on one side of an element? Shadow Effect for a Text in Android? Inner text shadow with CSS iPhone UILabel text soft shadow