LESS CSS parametric mixin default null value does not work - css

I have lesscss mixin for box-shadow like this :
.box-shadow(#x, #y, #blur, #color, #addit: ''){
-webkit-box-shadow: #x #y #blur #color #addit;
-moz-box-shadow: #x #y #blur #color #addit;
box-shadow: #x #y #blur #color #addit;
}
As you seen, There is a parameter #addit that set to '' as default.
It's work fine when I give #addit a value like : .box-shadow(0, 0, 2px, #1361aa, inset), But why if parameter for #addit not filled, then it doesn't work? And how to fix it?
Help, thanks for advance.

Escape the empty string as your default
You need to set the default value to ~'' so it is an escaped string.
LESS
.box-shadow(#x, #y, #blur, #color, #addit: ~''){
-webkit-box-shadow: #x #y #blur #color #addit;
-moz-box-shadow: #x #y #blur #color #addit;
box-shadow: #x #y #blur #color #addit;
}
.test{
.box-shadow(0, 0, 2px, #1361aa)
}
CSS
.test {
-webkit-box-shadow: 0 0 2px #1361aa ;
-moz-box-shadow: 0 0 2px #1361aa ;
box-shadow: 0 0 2px #1361aa ;
}

You can't use '' as it will add an invalid parameter to box-shadow. This is the generated output for .box-shadow(2px, 2px, 5px, #F00);
#myDiv {
-webkit-box-shadow:2px 2px 5px #ff0000 '';
-moz-box-shadow:2px 2px 5px #ff0000 '';
box-shadow:2px 2px 5px #ff0000 '';
}
As you can see, LESS CSS supports strings and empty strings as parameters, however, CSS does not recognize this, and discards this as an invalid style.
One way you could do it is simply using two mixins with same name but different number of parameters (similar to overloading):
.box-shadow(#x, #y, #blur, #color) {
-webkit-box-shadow: #x #y #blur #color;
-moz-box-shadow: #x #y #blur #color;
box-shadow: #x #y #blur #color;
}
.box-shadow(#x, #y, #blur, #color, #addit) {
-webkit-box-shadow: #x #y #blur #color #addit;
-moz-box-shadow: #x #y #blur #color #addit;
box-shadow: #x #y #blur #color #addit;
}
Tested this and works with the following:
.box-shadow(2px, 2px, 5px, #F00);
.box-shadow(2px, 2px, 5px, #F00, inset);

Related

SASS Mixin Arguments with specific values

Is there any way to check argument in mixins.
For example, I have a shadow mixin and want to include it (call it) different way in case of its argument.
#mixin shadow($shadow, $position, $color) {
.....
}
If I pass Top2 it should change only first parameter
.box { #include shadow(inset, Top2, #000); } => `box-shadow: inset, 2px 0 0 0, #000`
If I pass Bottom2 it should change the parameter to -2px
.box { #include shadow(inset, Bottom2, #000); } => `box-shadow: inset, -2px 0 0 0, #000`
I think you should use this type.
#mixin box-shadow($values) {
-webkit-box-shadow: $values;
-moz-box-shadow: $values;
box-shadow: $values;
}
#mixin box-shadow-inset($inset) {
-webkit-box-shadow: $inset;
-moz-box-shadow: $inset;
box-shadow: $inset;
}

How to create a #mixin for CSS dropshadow

I am having trouble creating a #mixin for a drop shadow. The drop shadow I want in regular CSS is as follows
-webkit-box-shadow: 0px 2px 3px 2px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0px 2px 3px 2px rgba(0, 0, 0, 0.2);
box-shadow: 0px 2px 3px 2px rgba(0, 0, 0, 0.2);
The #mixin I have created is as such
#mixin box-shadow(
$top, $left, $blur, $size, $color) {
}
Then to use this I have added the below to my scss file
#include box-shadow(0, 2px, 3px, 2px, rgba(0, 0, 0, 0.2));
However, it is broken as I do not see any drop shadow CSS being applied once the SCSS is compiled.
Try this: Fiddle
#mixin box-shadow($top, $left, $blur, $size, $color) {
-webkit-box-shadow: $top $left $blur $size $color;
-moz-box-shadow: $top $left $blur $size $color;
box-shadow: $top $left $blur $size $color;
}
.box{
width:150px;
height:150px;
background:blue;
#include box-shadow(2px,2px,5px,0, rgba(0,0,0,0.6));
}
It looks like you've left out declaring the box-shadow rules in your mixin.
It should look like this:
#mixin box-shadow($top, $left, $blur, $size, $color) {
box-shadow: $top $left $blur $size $color
}
Add the vendor prefixes as you need.
fiddle
I use this
/* BOXSHADOW */
#mixin boxshadow(#x: 0, #y: 0, #blur: 0, #spread: 0, #rgba: rgba(0, 0, 0, 1.0)) {
-webkit-box-shadow: #x*#rem #y*#rem #blur*#rem #spread*#rem #rgba;
-moz-box-shadow: #x*#rem #y*#rem #blur*#rem #spread*#rem #rgba;
box-shadow: #x*#rem #y*#rem #blur*#rem #spread*#rem #rgba;
}
#include boxshadow(0, 0, 10, -5, rgba(220, 220, 220, 1.0));
You could try to use Compass. It provides a lot of mixins for the most common CSS rules, including box-shadow. It also transparently add cross-browser prefixes while using its mixins.

Text shadow outline not complete in corners

I'm trying to add an outline to text using the CSS text-shadow property here.
The problem is that the shadow corners don't always meet. If you look below, you can see the problem on the upper right corner of the Y.
It doesn't look too bad with this font but with some fonts that my code uses it makes a big difference.
Is there a way to have the text completely surrounded by the box-shadow, especialy in the cornerns?
.shadowOutline {
font: normal 200pt Arial;color: #fff;
text-shadow:
-1px 1px #ff0000,
-1px -1px #ff0000,
1px 1px #ff0000,
1px -1px #ff0000,
-2px 2px #ff0000,
-2px -2px #ff0000,
2px 2px #ff0000,
2px -2px #ff0000;
-webkit-font-smoothing: antialiased;
}
<div class="shadowOutline">My</div>
You can do it with svg ,and you have a perfect resault
text{font-size:100px;
fill: none;
stroke: red;
stroke-width:2px;
stroke-linejoin: round;
}
<svg height="120" width="480">
<text x="0" y="90" >I love SVG!</text>
</svg>
or you can use it directly with inline css like this :
<svg height="100" width="480">
<text x="0" y="80" fill="white" stroke="red" style="font-size:100px;stroke-width:2px;">I love SVG!</text>
</svg>
I managed to get it a little better using :
.shadowOutline {
font: normal 200pt Arial;color: #fff;
text-shadow:
-2px -2px 0 #ff0000,
2px -2px 0 #ff0000,
-2px 2px 0 #ff0000,
2px 2px 0 #ff0000,
2px 0px 0 #ff0000,
-2px 0px 0 #ff0000,
0px 2px 0 #ff0000,
0px -2px 0 #ff0000;
-webkit-font-smoothing: antialiased;
}
<div class="shadowOutline">My</div>
The point is to offset the text-shadow in all directions :
left
right
top
bottom
But also
top-left
top-right
bottom-left
bottom-right
Keep in mind, that for values greater than one pixel you'll have to fill the gaps of sharp corner shadows. See for example letter "X" with (attempt of) ten pixels thick outline, first made by eight, second by twenty four shadows:
See this example
span {
font: normal 200pt Arial;
color: #fff;
letter-spacing: 20px
}
.eight-shadows {
text-shadow:
-10px -10px 0 #f00,
00px -10px 0 #f00,
10px -10px 0 #f00,
10px 00px 0 #f00,
10px 10px 0 #f00,
00px 10px 0 #f00,
-10px 10px 0 #f00,
-10px 00px 0 #f00;
}
.twenty-four-shadows {
text-shadow:
-10px -10px 0 #f00,
00px -10px 0 #f00,
10px -10px 0 #f00,
10px 00px 0 #f00,
10px 10px 0 #f00,
00px 10px 0 #f00,
-10px 10px 0 #f00,
-10px 00px 0 #f00,
-05px -10px 0 #f00,
00px -10px 0 #f00,
05px -10px 0 #f00,
05px 00px 0 #f00,
05px 10px 0 #f00,
00px 10px 0 #f00,
-05px 10px 0 #f00,
-05px 00px 0 #f00,
-10px -05px 0 #f00,
00px -05px 0 #f00,
10px -05px 0 #f00,
10px 00px 0 #f00,
10px 05px 0 #f00,
00px 05px 0 #f00,
-10px 05px 0 #f00,
-10px 00px 0 #f00
}
<span class="eight-shadows">X</span>
<span class="twenty-four-shadows">X</span>
(In fact the middle "horizontal" shadows chunk could be omitted for this sample, because it contains no sharp vertical corner, but I left it there for clarity.)
To get "solid" 10px corner outlines you'd have to use 288 (= 4×9×8) shadows, and even then the result will be vertical or horizontal lines near the sharp corners instead of sharp ones.
If you're okay wit a little more "blur" to your outline, using the third, optional property on text-shadow could help close those gaps you're seeing on the "Y".
From the MDN article for text-shadow:
Values
<color>
Optional. Can be specified either before or after the offset
values. If the color is not specified, a UA-chosen color will be used.
Note: If you want to ensure consistency across browsers, explicitly
specify a color.
<offset-x> <offset-y> Required. These length values
specify the shadow's offset from the text. <offset-x> specifies the
horizontal distance; a negative value places the shadow to the left of
the text. <offset-y> specifies the vertical distance; a negative value
places the shadow above the text. If both values are 0, then the
shadow is placed behind the text (and may generate a blur effect when
is set). To find out what units you can use, see
.
<blur-radius> Optional. This is a value. If not
specified, it defaults to 0. The higher this value, the bigger the
blur; the shadow becomes wider and lighter.
.shadowOutline {
font: normal 200pt Arial;color: #fff;
text-shadow:
-1px 1px 4px #ff0000,
-1px -1px 4px #ff0000,
1px 1px 4px #ff0000,
1px -1px 4px #ff0000,
-2px 2px 4px #ff0000,
-2px -2px 4px #ff0000,
2px 2px 4px #ff0000,
2px -2px 4px #ff0000;
-webkit-font-smoothing: antialiased;
}
<div class="shadowOutline">My</div>
Headsup: for this purpose you can use -webkit-text-stroke (preferably in combination with -webkit-text-fill-color and it will work in current Firefox (49+) as well:
.shadowOutline {
font: normal 200pt Arial;
color: red;
-webkit-text-fill-color: transparent;
-webkit-text-stroke: 2px red;
}
<div class="shadowOutline">My</div>
Capable browsers will render outline around transparent letters, others opaque (red) letter, so this is somewhat more reliable than white text on white background in browsers without text-shadow support.

How to simplify this LESS CSS Box-shadow mixin? (multiple shadows with "directions")

How to reduce this code (probably with a loop ?), to have a "function" which takes direction and number?
#dir = the wanted "direction"
#number = how many times I need a shadow (here 10 times)
#color = color of the shadow
Example (working, but not very easy to use) :
.perspective-box(#dir, #number, #color) when (#dir = se){
-webkit-box-shadow:1px 1px 0 0 #color,
2px 2px 0 0 #color,
3px 3px 0 0 #color,
4px 4px 0 0 #color,
5px 5px 0 0 #color,
6px 6px 0 0 #color,
7px 7px 0 0 #color,
8px 8px 0 0 #color,
9px 9px 0 0 #color,
10px 10px 0 0 #color;
}
I have a #dir param which change the direction of shadows.
In this example, I put #dir = se, where se = South East. This is the same thing for North West, North East, South West and South East.
How to avoid this…?
.perspective-box(#dir, #number, #color) when (#dir = ne){
-webkit-box-shadow:10x North East shadow…
}
.perspective-box(#dir, #number, #color) when (#dir = nw){
-webkit-box-shadow:10x North West shadow…
}
.perspective-box(#dir, #number, #color) when (#dir = sw){
-webkit-box-shadow:10x South West shadow…
}
.perspective-box(#dir, #number, #color) when (#dir = se){
-webkit-box-shadow:10x South East shadow…
}
No problem:
.text-shadow-3d(#x, #y, #index) when (#index > 0) {
// Loop-de-loop.
.text-shadow-3d(#x, #y, #index - 1);
// The '+' after 'text-shadow' concatenates with comma.
text-shadow+: #x*#index #y*#index 0 black;
}
.text-shadow-3d(1px, 1px, 5);
Result:
text-shadow: 1px 1px 0 #000000, 2px 2px 0 #000000, 3px 3px 0 #000000, 4px 4px 0 #000000, 5px 5px 0 #000000;
Docs:
http://lesscss.org/features/#loops-feature
http://lesscss.org/features/#merge-feature
I am almost positive this is impossible with LESS because it lacks the language constructs to do so (it's been a while since I used LESS, so I could be wrong). Sass, on the other hand, might be able to do it because it does have loops and things like lists (though looking at the options there, it looks like it might be pretty ugly handling the variable number of shadows).

Outline effect to text

Are there any ways in CSS to give outlines to text with different colors ? I want to highlight some parts of my text to make it more intuitive - like the names, links, etc. Changing the link colors etc. are common nowadays, so I want something new.
There is an experimental webkit property called text-stroke in CSS3, I've been trying to get this to work for some time but have been unsuccessful so far.
What I have done instead is used the already supported text-shadow property (supported in Chrome, Firefox, Opera, and IE 9 I believe).
Use four shadows to simulate a stroked text:
.strokeme {
color: white;
background-color: white;
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
}
<div class="strokeme">
This text should have a stroke in some browsers
</div>
I have made a demo for you here
And a hovered example is available here
As Jason C has mentioned in the comments, the text-shadow CSS property is now supported by all major browsers, with the exception of Opera Mini. Where this solution will work for backwards compatibility (not really an issue regarding browsers that auto-update) I believe the text-stroke CSS should be used.
Easy! SVG to the rescue.
This is a simplified method:
svg{
font : bold 70px Century Gothic, Arial;
width : 100%;
height : 120px;
}
text{
fill : none;
stroke : black;
stroke-width : .5px;
stroke-linejoin : round;
animation : 2s pulsate infinite;
}
#keyframes pulsate {
50%{ stroke-width:5px }
}
<svg viewBox="0 0 450 50">
<text y="50">Scalable Title</text>
</svg>
Here's a more complex demo.
CSS-only:
h1 {
font: 800 40px Arial;
-webkit-text-fill-color: transparent;
-webkit-text-stroke: 1px;
}
<h1>I am outlined</h1>
💡 Note that as of writing, the -webkit-text-stroke property cannot be transitioned/animated.
Edit: text-stroke is now fairly mature and implemented in most browsers. It is easier, sharper and more precise. If your browser audience can support it, you should now use text-stroke first, instead of text-shadow.
You can and should do this with just the text-shadow effect without any offsets:
.outline {
color: #fff;
text-shadow: #000 0px 0px 1px;
-webkit-font-smoothing: antialiased;
}
Why? When you offset multiple shadow effects, you’ll begin to notice ungainly, jagged corners:
Having text-shadow effects in just one position eliminates the offsets, meaning
If you feel that’s too thin and would prefer a darker outline instead, no problem — you can repeat the same effect (keeping the same position and blur), several times. Like so:
text-shadow: #000 0px 0px 1px, #000 0px 0px 1px, #000 0px 0px 1px,
#000 0px 0px 1px, #000 0px 0px 1px, #000 0px 0px 1px;
Here’s a sample of just one effect (top), and the same effect repeated 14 times (bottom):
Also note: Because the lines become so thin, it’s a very good idea to turn off sub-pixel rendering using-webkit-font-smoothing: antialiased.
Just adding this answer. "Stroking" the text is not the same as "Outlining".
Outlining looks great. Stroking looks horrid.
The SVG solution listed elsewhere has the same issue. If you want an outline you need to put the text twice. Once stroked and again not stroked.
Stroking IS NOT Outlining
body {
font-family: sans-serif;
margin: 20px;
}
.stroked {
color: white;
-webkit-text-stroke: 1px black;
}
.thickStroked {
color: white;
-webkit-text-stroke: 10px black;
}
.outlined {
color: white;
text-shadow:
-1px -1px 0 #000,
0 -1px 0 #000,
1px -1px 0 #000,
1px 0 0 #000,
1px 1px 0 #000,
0 1px 0 #000,
-1px 1px 0 #000,
-1px 0 0 #000;
}
.thickOutlined {
color: white;
text-shadow: 0.0px 10.0px 0.02px #000, 9.8px 2.1px 0.02px #000, 4.2px -9.1px 0.02px #000, -8.0px -6.0px 0.02px #000, -7.6px 6.5px 0.02px #000, 4.8px 8.8px 0.02px #000, 9.6px -2.8px 0.02px #000, -0.7px -10.0px 0.02px #000, -9.9px -1.5px 0.02px #000, -3.5px 9.4px 0.02px #000, 8.4px 5.4px 0.02px #000, 7.1px -7.0px 0.02px #000, -5.4px -8.4px 0.02px #000, -9.4px 3.5px 0.02px #000, 1.4px 9.9px 0.02px #000, 10.0px 0.8px 0.02px #000, 2.9px -9.6px 0.02px #000, -8.7px -4.8px 0.02px #000, -6.6px 7.5px 0.02px #000, 5.9px 8.0px 0.02px #000, 9.1px -4.1px 0.02px #000, -2.1px -9.8px 0.02px #000, -10.0px -0.1px 0.02px #000, -2.2px 9.8px 0.02px #000, 9.1px 4.2px 0.02px #000, 6.1px -8.0px 0.02px #000, -6.5px -7.6px 0.02px #000, -8.8px 4.7px 0.02px #000, 2.7px 9.6px 0.02px #000, 10.0px -0.6px 0.02px #000, 1.5px -9.9px 0.02px #000, -9.3px -3.6px 0.02px #000, -5.5px 8.4px 0.02px #000, 7.0px 7.2px 0.02px #000, 8.5px -5.3px 0.02px #000, -3.4px -9.4px 0.02px #000, -9.9px 1.3px 0.02px #000, -0.8px 10.0px 0.02px #000, 9.6px 2.9px 0.02px #000, 4.9px -8.7px 0.02px #000, -7.5px -6.7px 0.02px #000, -8.1px 5.9px 0.02px #000, 4.0px 9.2px 0.02px #000, 9.8px -2.0px 0.02px #000, 0.2px -10.0px 0.02px #000, -9.7px -2.3px 0.02px #000, -4.3px 9.0px 0.02px #000, 7.9px 6.1px 0.02px #000
}
svg {
font-size: 40px;
font-weight: bold;
width: 450px;
height: 70px;
fill: white;
}
.svgStroke {
fill: white;
stroke: black;
stroke-width: 20px;
stroke-linejoin: round;
}
<h1 class="stroked">Properly stroked!</h1>
<h1 class="outlined">Properly outlined!</h1>
<h1 class="thickStroked">Thickly stroked!</h1>
<h1 class="thickOutlined">Thickly outlined!</h1>
<svg viewBox="0 0 450 70">
<text class="svgStroke" x="10" y="45">SVG Thickly Stroked!</text>
</svg>
<svg viewBox="0 0 450 70">
<text class="svgStroke" x="10" y="45">SVG Thickly Outlined!</text>
<text class="svgText" x="10" y="45">SVG Thickly Outlined!</text>
</svg>
PS: I'd love to know how to make the SVG be the correct size of any arbitrary text. I have a feeling it's fairly complicated involving generating the SVG, querying it with Javascript to get the extents, then applying the results. If there is an easier non-JS way, I'd love to know.
Update: As #12me21 points out, in SVG you can use paint-order="stroke" to make it stroke before filling and then you don't have to repeat the text
svg {
font-size: 40px;
font-weight: bold;
width: 450px;
height: 70px;
fill: white;
}
.svgText {
fill: white;
stroke: black;
stroke-width: 15px;
stroke-linejoin: round;
paint-order: stroke;
}
<svg viewBox="0 0 450 70">
<text class="svgText" x="10" y="45">SVG Thickly Outlined!</text>
</svg>
You could try stacking multiple blured shadows until the shadows look like a stroke, like so:
.shadowOutline {
text-shadow: 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black;
}
Here's a fiddle: http://jsfiddle.net/GGUYY/
I mention it just in case someone's interested, although I wouldn't call it a solution because it fails in various ways:
it doesn't work in old IE
it renders quite differently in every browser
applying so many shadows is very heavy to process :S
I was looking for a cross-browser text-stroke solution that works when overlaid on background images. think I have a solution for this that doesn't involve extra mark-up, js and works in IE7-9 (I haven't tested 6), and doesn't cause aliasing problems.
This is a combination of using CSS3 text-shadow, which has good support except IE (http://caniuse.com/#search=text-shadow), then using a combination of filters for IE. CSS3 text-stroke support is poor at the moment.
IE Filters
The glow filter (http://www.impressivewebs.com/css3-text-shadow-ie/) looks terrible, so I didn't use that.
David Hewitt's answer involved adding dropshadow filters in a combination of directions. ClearType is then removed unfortunately so we end up with badly aliased text.
I then combined some of the elements suggested on useragentman with the dropshadow filters.
Putting it together
This example would be black text with a white stroke. I'm using conditional html classes by the way to target IE (http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/).
#myelement {
color: #000000;
text-shadow:
-1px -1px 0 #ffffff,
1px -1px 0 #ffffff,
-1px 1px 0 #ffffff,
1px 1px 0 #ffffff;
}
html.ie7 #myelement,
html.ie8 #myelement,
html.ie9 #myelement {
background-color: white;
filter: progid:DXImageTransform.Microsoft.Chroma(color='white') progid:DXImageTransform.Microsoft.Alpha(opacity=100) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=1,offY=1) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=-1,offY=1) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=1,offY=-1) progid:DXImageTransform.Microsoft.dropshadow(color=#ffffff,offX=-1,offY=-1);
zoom: 1;
}
I got better results with 6 different shadows:
.strokeThis{
text-shadow:
-1px -1px 0 #ff0,
0px -1px 0 #ff0,
1px -1px 0 #ff0,
-1px 1px 0 #ff0,
0px 1px 0 #ff0,
1px 1px 0 #ff0;
}
This mixin for SASS will give smooth results, using 8-axis:
#mixin stroke($size: 1px, $color: #000) {
text-shadow:
-#{$size} -#{$size} 0 $color,
0 -#{$size} 0 $color,
#{$size} -#{$size} 0 $color,
#{$size} 0 0 $color,
#{$size} #{$size} 0 $color,
0 #{$size} 0 $color,
-#{$size} #{$size} 0 $color,
-#{$size} 0 0 $color;
}
And normal CSS:
text-shadow:
-1px -1px 0 #000,
0 -1px 0 #000,
1px -1px 0 #000,
1px 0 0 #000,
1px 1px 0 #000,
0 1px 0 #000,
-1px 1px 0 #000,
-1px 0 0 #000;
h1 {
color: black;
-webkit-text-fill-color: white; /* Will override color (regardless of order) */
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: black;
}
<h1>Properly stroked!</h1>
Working with thicker strokes gets a bit messy, if you have the pleasure of sass try this mixin, not perfect and depending on stroke weight it generates a fair amount of css.
#mixin stroke($width, $colour: #000000) {
$shadow: 0 0 0 $colour; // doesn't do anything but I couldn't work out how to create a blank string and maintain commas
#for $i from 0 through $width {
$shadow: $shadow,
-$i + px -$width + px 0 $colour,
$i + px -$width + px 0 $colour,
-$i + px $width + px 0 $colour,
$i + px $width + px 0 $colour,
-$width + px -$i + px 0 $colour,
$width + px -$i + px 0 $colour,
-$width + px $i + px 0 $colour,
$width + px $i + px 0 $colour,
}
text-shadow: $shadow;
}
We can use text-stroke
HTML
<h1>Sample Text</h1>
CSS
h1{
-webkit-text-stroke: 2px red;
text-stroke: 2px red;
}
Just piece of cake. Try this instead of using text-shadow
I had this issue as well, and the text-shadow wasn't an option because the corners would look bad (unless I had many many shadows), and I didn't want any blur, therefore my only other option was to do the following: Have 2 divs, and for the background div, put a -webkit-text-stroke on it, which then allows for as big of an outline as you like.
div {
font-size: 200px;
position: absolute;
white-space: nowrap;
}
.front {
color: blue;
}
.outline {
-webkit-text-stroke: 30px red;
user-select: none;
}
<div class="outline">
outline text
</div>
<div class="front">
outline text
</div>
Using this, I was able to achieve an outline, because the stroke-width method was not an option if you want your text to remain legible with a very large outline (because with stroke-width the outline will start inside the lettering which makes it not legible when the width gets larger than the letters.
Note: the reason I needed such a fat outline was I was emulating the street labels in "google maps" and I wanted a fat white halo around the text. This solution worked perfectly for me.
Here is a fiddle showing this solution
Text Shadow Generator
There are lots of great answers here. It would appear the text-shadow is probably the most reliable way to do this. I won't go into detail about how to do this with text-shadow since others have already done that, but the basic idea is that you create multiple text shadows around the text element. The larger the text outline, the more text shadows you need.
All of the answers submitted (as of this posting) provide static solutions for the text-shadow. I have taken a different approach and have written this JSFiddle that accepts outline color, blur, and width values as inputs and generates the appropriate text-shadow property for your element. Just fill in the blanks, check the preview, and click to copy the css and paste it into your stylesheet.
Needless Appendix
Apparently, answers that include a link to a JSFiddle cannot be posted unless they also contain code. You can completely ignore this appendix if you want to. This is the JavaScript from my fiddle that generates the text-shadow property. Please note that you do not need to implement this code in your own works:
function computeStyle() {
var width = document.querySelector('#outline-width').value;
width = (width === '') ? 0 : Number.parseFloat(width);
var blur = document.querySelector('#outline-blur').value;
blur = (blur === '') ? 0 : Number.parseFloat(blur);
var color = document.querySelector('#outline-color').value;
if (width < 1 || color === '') {
document.querySelector('.css-property').innerText = '';
return;
}
var style = 'text-shadow: ';
var indent = false;
for (var i = -1 * width; i <= width; ++i) {
for (var j = -1 * width; j <= width; ++j) {
if (! (i === 0 && j === 0 && blur === 0)) {
var indentation = (indent) ? '\u00a0\u00a0\u00a0\u00a0' : '';
style += indentation + i + "px " + j + "px " + blur + "px " + color + ',\n';
indent = true;
}
}
}
style = style.substring(0, style.length - 2) + '\n;';
document.querySelector('.css-property').innerText = style;
var exampleBackground = document.querySelector('#example-bg');
var exampleText = document.querySelector('#example-text');
exampleBackground.style.backgroundColor = getOppositeColor(color);
exampleText.style.color = getOppositeColor(color);
var textShadow = style.replace(/text-shadow: /, '').replace(/\n/g, '').replace(/.$/, '').replace(/\u00a0\u00a0\u00a0\u00a0/g, '');
exampleText.style.textShadow = textShadow;
}
Simple outline behind the letters.
Works with any font. With any outline width.
<style>
text {
stroke-linejoin: round;
text-anchor: middle;
fill: black;
stroke: white;
stroke-width: 12px;
paint-order: stroke;
}
</style>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<text x="50%" y="50%" dominant-baseline="central" text-anchor="middle">Text</text>
</svg>
Codepen: https://codepen.io/RilDev/pen/vYeOjgj?editors=1000
I'm sorry, but if you've gotten this far, you'll realise that all the other answers are inadequate or require SVG.
Note: This beautiful outlining will cost you the small price of maintaining a copy of the text in a data-content attribute, which is used by a layered CSS3 ::before element that renders the fill text over the actual outline.
.outline {
color: black;
-webkit-text-stroke: 0.15em black;
}
.outline::before {
content: attr(data-content);
-webkit-text-fill-color: white;
-webkit-text-stroke: 0;
position: absolute;
}
.outline-wrapper {
font-family: "DaytonaW01-CondensedBold", Impact, Times, serif;
font-size: 50px;
}
<div class="outline-wrapper">
<div class="outline" data-content="Take-Two v Anderson">Take-Two v Anderson
</div>
</div>
<link href="https://db.onlinewebfonts.com/c/998b5de3cda797387727724405beb7d4?family=DaytonaW01-CondensedBold" rel="stylesheet" type="text/css"/>
The external style link is just to include the font, and is not required -- though using a thin font may require adjustment to the stroking parameter.
Multiple text-shadows..
Something like this:
var steps = 10,
i,
R = 0.6,
x,
y,
theStyle = '1vw 1vw 3vw #005dab';
for (i = -steps; i <= steps; i += 1) {
x = (i / steps) / 2;
y = Math.sqrt(Math.pow(R, 2) - Math.pow(x, 2));
theStyle = theStyle + ',' + x.toString() + 'vw ' + y.toString() + 'vw 0 #005dab';
theStyle = theStyle + ',' + x.toString() + 'vw -' + y.toString() + 'vw 0 #005dab';
theStyle = theStyle + ',' + y.toString() + 'vw ' + x.toString() + 'vw 0 #005dab';
theStyle = theStyle + ',-' + y.toString() + 'vw ' + x.toString() + 'vw 0 #005dab';
}
document.getElementsByTagName("H1")[0].setAttribute("style", "text-shadow:" + theStyle);
Demo: http://jsfiddle.net/punosound/gv6zs58m/
Try Following:
<!DOCTYPE html>
<html>
<head>
<style>
h1 {
text-shadow: 2px 2px;
}
h1.m1 {
text-shadow: 2px 2px red;
}
h1.m2 {
text-shadow: 2px 2px 5px red;
}
h1.m3 {
color: white;
text-shadow: 2px 2px 4px #000000;
}
h1.m4 {
text-shadow: 0 0 3px #FF0000;
}
h1.m5{
color: #FFFFFF;
background: #232323;
text-shadow: 0 0 5px #FFF, 0 0 10px #FFF, 0 0 15px #FFF, 0 0 20px #49ff18, 0 0 30px #49FF18, 0 0 40px #49FF18, 0 0 55px #49FF18, 0 0 75px #49ff18;
}
h1.m6{
color: #FFFFFF;
background: #FFFFFF;
text-shadow: 2px 2px 0 #4074b5, 2px -2px 0 #4074b5, -2px 2px 0 #4074b5, -2px -2px 0 #4074b5, 2px 0px 0 #4074b5, 0px 2px 0 #4074b5, -2px 0px 0 #4074b5, 0px -2px 0 #4074b5;
}
h1.m7
{
color: #444444;
background: #FFFFFF;
text-shadow: 1px 0px 1px #CCCCCC, 0px 1px 1px #EEEEEE, 2px 1px 1px #CCCCCC, 1px 2px 1px #EEEEEE, 3px 2px 1px #CCCCCC, 2px 3px 1px #EEEEEE, 4px 3px 1px #CCCCCC, 3px 4px 1px #EEEEEE, 5px 4px 1px #CCCCCC, 4px 5px 1px #EEEEEE, 6px 5px 1px #CCCCCC, 5px 6px 1px #EEEEEE, 7px 6px 1px #CCCCCC;
}
</style>
</head>
<body>
<h1 class="m6">Text-shadow effect!</h1>
<h1 class="m7">Text-shadow effect!</h1>
<h1>Text-shadow effect!</h1>
<h1 class="m1">Text-shadow effect!</h1>
<h1 class="m2">Text-shadow effect!</h1>
<h1 class="m3">Text-shadow effect!</h1>
<h1 class="m4">Text-shadow effect!</h1>
<h1 class="m5">Text-shadow effect!</h1>
</body>
</html>

Resources