Is there any way to make a transparent text cut out of a background effect like the one in the following image, with CSS?
It would be sad to lose all precious SEO because of images replacing text.
I first thought of shadows but I can't figure anything out...
The image is the site background, an absolute positioned <img> tag
It's possible with css3 but it's not supported in all browsers
With background-clip: text; you can use a background for the text, but you will have to align it with the background of the page
body {
background: url(http://www.color-hex.com/palettes/26323.png) repeat;
margin:10px;
}
h1 {
background-color:#fff;
overflow:hidden;
display:inline-block;
padding:10px;
font-weight:bold;
font-family:arial;
color:transparent;
font-size:200px;
}
span {
background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat;
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
display:block;
}
<h1><span>ABCDEFGHIKJ</span></h1>
http://jsfiddle.net/JGPuZ/1337/
Automatic Alignment
With a little javascript you can align the background automatically:
$(document).ready(function(){
//Position of the header in the webpage
var position = $("h1").position();
var padding = 10; //Padding set to the header
var left = position.left + padding;
var top = position.top + padding;
$("h1").find("span").css("background-position","-"+left+"px -"+top+"px");
});
body {
background: url(http://www.color-hex.com/palettes/26323.png) repeat;
margin:10px;
}
h1 {
background-color:#fff;
overflow:hidden;
display:inline-block;
padding:10px;
font-weight:bold;
font-family:arial;
color:transparent;
font-size:200px;
}
span {
background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat;
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><span>ABCDEFGHIKJ</span></h1>
http://jsfiddle.net/JGPuZ/1336/
Although this is possible with CSS, a better approach would be to use an inline SVG with SVG masking. This approach has some advantages over CSS :
Much better browser support: IE10+, chrome, Firefox, safari...
This doesn't impact SEO as spiders can crawl SVG content (google indexes SVG content since 2010)
CodePen Demo : SVG text mask
body,html{height:100%;margin:0;padding:0;}
body{
background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');
background-size:cover;
background-attachment:fixed;
}
svg{width:100%;}
<svg viewbox="0 0 100 60">
<defs>
<mask id="mask" x="0" y="0" width="100" height="50">
<rect x="0" y="0" width="100" height="40" fill="#fff"/>
<text text-anchor="middle" x="50" y="18" dy="1">SVG</text>
<text text-anchor="middle" x="50" y="30" dy="1">Text mask</text>
</mask>
</defs>
<rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/>
</svg>
If you aim on making the text selectable and searchable, you need to include it outside the <defs> tag. The following example shows a way to do that keeping the transparent text with the <use> tag:
body,html{height:100%;margin:0;padding:0;}
body{
background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');
background-size:cover;
background-attachment:fixed;
}
svg{width:100%;}
<svg viewbox="0 0 100 60">
<defs>
<g id="text">
<text text-anchor="middle" x="50" y="18" dy="1">SVG</text>
<text text-anchor="middle" x="50" y="30" dy="1">Text mask</text>
</g>
<mask id="mask" x="0" y="0" width="100" height="50">
<rect x="0" y="0" width="100" height="40" fill="#fff"/>
<use xlink:href="#text" />
</mask>
</defs>
<rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/>
<use xlink:href="#text" mask="url(#mask)" />
</svg>
There is a simple way to do this with just CSS:
background: black;
color: white;
mix-blend-mode: multiply;
for transparent text on a black background, or
background: white;
color: black;
mix-blend-mode: screen;
for transparent text on a white background.
Put these styles on your text element with whichever background you want behind it.
Example CodePen
Read up on mix-blend-mode and experiment with it to use different colours.
Caveats:
For this to work in chrome, you also need to explicitly set a background colour on the html element.
This works on basically all modern browsers except IE.
It is possible, but so far only with Webkit based browsers (Chrome, Safari, Rockmelt, anything based on the Chromium project.)
The trick is to have an element within the white one that has the same background as the body, then use -webkit- background-clip: text; on the inner element which basically means "don't extend the background beyond the text" and use transparent text.
section
{
background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
width: 100%;
height: 300px;
}
div
{
background: rgba(255, 255, 255, 1);
color: rgba(255, 255, 255, 0);
width: 60%;
heighT: 80%;
margin: 0 auto;
font-size: 60px;
text-align: center;
}
p
{
background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
-webkit-background-clip: text;
}
http://jsfiddle.net/BWRsA/
just put that css
.banner-sale-1 .title-box .title-overlay {
font-weight: 900;
overflow: hidden;
margin: 0;
padding-right: 10%;
padding-left: 10%;
text-transform: uppercase;
color: #080404;
background-color: rgba(255, 255, 255, .85);
/* that css is the main think (mix-blend-mode: lighten;)*/
mix-blend-mode: lighten;
}
I just discovered a new way to do this while messing around, I'm not entirely sure how it works ( if someone else wants to explain please do ).
It seems to work very well, and requires no double backgrounds or JavaScript.
Here's the code:
JSFIDDLE
body {
padding: 0;
margin: 0;
}
div {
background: url(http://www.color-hex.com/palettes/26323.png) repeat;
width: 100vw;
height: 100vh;
}
body::before {
content: '$ALPHABET';
left: 0;
top: 0;
position: absolute;
color: #222;
background-color: #fff;
padding: 1rem;
font-family: Arial;
z-index: 1;
mix-blend-mode: screen;
font-weight: 800;
font-size: 3rem;
letter-spacing: 1rem;
}
<div></div>
In the near future we can use element() to achieve this
The element() function allows an author to use an element in the document as an image. As the referenced element changes appearance, the image changes as well ref
The trick is to create a common div with text then use element() combined with mask.
Here is a basic example that works only on the latest version Firefox for now.
#text {
font-size:35px;
font-weight:bold;
color:#000;
font-family:sans-serif;
text-transform: uppercase;
white-space:nowrap;
/* we hide it */
position:fixed;
right:200vw;
bottom:200vh
}
body {
background:url(https://picsum.photos/id/1018/800/800) center/cover;
}
.main {
margin:50px;
height:100px;
background:red;
-webkit-mask:
-moz-element(#text) center/contain no-repeat, /* this behave like a background-image*/
linear-gradient(#fff 0 0);
mask-composite:exclude;
}
<div id="text">
You can put your text here
</div>
<div class="main">
</div>
It will produce the following:
It's reponsive since we rely on basic background properties and we can easily update the text using basic CSS.
We can consider any kind of content and also create patterns:
#text {
font-size:30px;
font-weight:bold;
color:#000;
font-family:sans-serif;
text-transform: uppercase;
white-space:nowrap;
padding:20px;
/* we hide it */
position:fixed;
right:200vw;
bottom:200vh
}
#text span {
font-family:cursive;
font-size:35px;
}
body {
background:url(https://picsum.photos/id/1018/800/800) center/cover;
}
.main {
margin:50px;
height:100px;
background:red;
-webkit-mask:
-moz-element(#text) 0 0/20% auto, /* this behave like a background-image*/
linear-gradient(#fff 0 0);
mask-composite:exclude;
}
<div id="text">
Your <span>text</span> here 👍
</div>
<div class="main">
</div>
And why not some animation to create an infinite scrolling text:
#text {
font-size:30px;
font-weight:bold;
color:#000;
font-family:sans-serif;
text-transform: uppercase;
white-space:nowrap;
padding:20px 5px;
/* we hide it */
position:fixed;
right:200vw;
bottom:200vh
}
body {
background:url(https://picsum.photos/id/1018/800/800) center/cover;
}
.main {
margin:50px;
height:100px;
padding-right:calc(50% - 50px);
background:red;
-webkit-mask:
-moz-element(#text) 0 50%/200% auto content-box, /* this behave like a background-image*/
linear-gradient(#fff 0 0);
mask-composite:exclude;
animation:m 5s linear infinite;
}
#keyframes m{
to {-webkit-mask-position:200% 50%}
}
<div id="text">
Srolling repeating text here
</div>
<div class="main">
</div>
I guess you could achieve something like that using background-clip, but I haven't tested that yet.
See this example:
http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html
(Webkit only, I don't know yet how to change the black background to a white one)
You can use an inverted / negative / reverse font and apply it with the font-face="…" CSS rule. You might have to play with letter spacing to avoid small white gaps between letters.
If you do not require a specific font, it's simple. Download a likeable one, for example from this collection of inverted fonts.
If you require a specific font (say, "Open Sans"), it's difficult. You have to convert your existing font into an inverted version. This is possible manually with Font Creator, FontForge etc., but of course we want an automated solution. I could not find instructions for that yet, but some hints:
How to convert a bitmap font into a TrueType font (plus yet another way to do that). One would first use ImageMagick commands to render the font glyphs into high-resolution raster images and to invert them, then convert them back to a TrueType font with the above instructions.
Is it possible to invert a font with FontForge or another PGM?
Creating a reverse (white on black) font
You can use myadzel's Patternizer jQuery plugin to achieve this effect across browsers. At this time, there is no cross-browser way to do this with just CSS.
You use Patternizer by adding class="background-clip" to HTML elements where you want the text to be painted as an image pattern, and specify the image in an additional data-pattern="…" attribute. See the source of the demo. Patternizer will create an SVG image with pattern-filled text and underlay it to the transparently rendered HTML element.
If, as in the question's example image, the text fill pattern should be a part of a background image extending beyond the "patternized" element, I see two options (untested, my favourite first):
Use masking instead of a background image in the SVG. As in web-tiki's answer, to which using Patternizer will still add automatic generation of the SVG and an invisible HTML element on top that allows text selection and copying.
Or use automatic alignment of the pattern image. Can be done with JavaScript code similar to the one in Gijs's answer.
I needed to make text that looked exactly like it does in the original post, but I couldn't just fake it by lining up backgrounds, because there's some animation behind the element. Nobody seems to have suggested this yet, so here's what I did: (Tried to make it as easy to read as possible.)
var el = document.body; //Parent Element. Text is centered inside.
var mainText = "THIS IS THE FIRST LINE"; //Header Text.
var subText = "THIS TEXT HAS A KNOCKOUT EFFECT"; //Knockout Text.
var fontF = "Roboto, Arial"; //Font to use.
var mSize = 42; //Text size.
//Centered text display:
var tBox = centeredDiv(el), txtMain = mkDiv(tBox, mainText), txtSub = mkDiv(tBox),
ts = tBox.style, stLen = textWidth(subText, fontF, mSize)+5; ts.color = "#fff";
ts.font = mSize+"pt "+fontF; ts.fontWeight = 100; txtSub.style.fontWeight = 400;
//Generate subtext SVG for knockout effect:
txtSub.innerHTML =
"<svg xmlns='http://www.w3.org/2000/svg' width='"+stLen+"px' height='"+(mSize+11)+"px' viewBox='0 0 "+stLen+" "+(mSize+11)+"'>"+
"<rect x='0' y='0' width='100%' height='100%' fill='#fff' rx='4px' ry='4px' mask='url(#txtSubMask)'></rect>"+
"<mask id='txtSubMask'>"+
"<rect x='0' y='0' width='100%' height='100%' fill='#fff'></rect>"+
"<text x='"+(stLen/2)+"' y='"+(mSize+6)+"' font='"+mSize+"pt "+fontF+"' text-anchor='middle' fill='#000'>"+subText+"</text>"+
"</mask>"+
"</svg>";
//Relevant Helper Functions:
function centeredDiv(parent) {
//Container:
var d = document.createElement('div'), s = d.style;
s.display = "table"; s.position = "relative"; s.zIndex = 999;
s.top = s.left = 0; s.width = s.height = "100%";
//Content Box:
var k = document.createElement('div'), j = k.style;
j.display = "table-cell"; j.verticalAlign = "middle";
j.textAlign = "center"; d.appendChild(k);
parent.appendChild(d); return k;
}
function mkDiv(parent, tCont) {
var d = document.createElement('div');
if(tCont) d.textContent = tCont;
parent.appendChild(d); return d;
}
function textWidth(text, font, size) {
var canvas = window.textWidthCanvas || (window.textWidthCanvas = document.createElement("canvas")),
context = canvas.getContext("2d"); context.font = size+(typeof size=="string"?" ":"pt ")+font;
return context.measureText(text).width;
}
Just throw that in your window.onload, set the body's background to your image, and watch the magic happen!
mix-blend-mode is also a possibility for that kind of effect .
The mix-blend-mode CSS property sets how an element's content should blend with the content of the element's parent and the element's background.
h1 {
background:white;
mix-blend-mode:screen;
/* demo purpose from here */
padding:0.25em;
mix-blend-mode:screen;
}
html {
background:url(https://i.picsum.photos/id/1069/367/267.jpg?hmac=w5sk7UQ6HGlaOVQ494mSfIe902cxlel1BfGUBpEYoRw)center / cover ;
min-height:100vh;
display:flex;
}
body {margin:auto;}
h1:hover {border:dashed 10px white;background-clip:content-box;box-shadow:inset 0 0 0 2px #fff, 0 0 0 2px #fff}
<h1>ABCDEFGHIJKLMNOPQRSTUVWXYZ</h1>
This worked for me mix-blend-mode: color-dodge on the container with opposite colors.
.main{
background: url('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg');
height: 80vh;
width: 100vw;
padding: 40px;
}
.container{
background-color: white;
width: 80%;
height: 50px;
padding: 40px;
font-size: 3em;
font-weight: 600;
mix-blend-mode: color-dodge;
}
.container span{
color: black;
}
<div class="main">
<div class="container">
<span>This is my text</span>
</div>
</div>
Not possible with CSS just now I'm afraid.
Your best bet is to simply use an image (probably a PNG) and and place good alt/title text on it.
Alternatively you could use a SPAN or a DIV and have the image as a background to that with your text you want for SEO purposes inside it but text-indent it off screen.
Related
CSS color has no transparent input that is they are all solid. So I tried to set opacity using rgba for the color property but the image background is not showing through the text. Is there a way to do this? So there a background image and heavy text on top that needs to be transparent only showing the letters outline.
I wish to have result like on example dank.sh
Try this:
element.style {
color: rgba(0,0,0,0.0); /* for transparent color */
-webkit-text-stroke: 1px rgba(0,0,0,1.0); /* for solid black outline */
}
UPDATED
If you need background image though the text:
.bg-though-text {
font-size: 50px;
font-weight: 700;
text-transform: uppercase;
background: linear-gradient(45deg, #0B2349 33%, #0D61BC 66%, #8AA9D6); /* Here you can use an image bg */
/* This will start the magic */
-webkit-background-clip: text; /* This will bring bg shape according to text*/
-webkit-text-fill-color: transparent; /* This will make text color transparent */
color: rgba(0,0,0,0.0); /* This will make text color transparent for sure */
}
<p class="bg-though-text">Gradient bg</p>
UPDATE 2
Transparent text, white bg and image behind.
.bg {
background-image: linear-gradient(90deg, #a50026, #d3322b, #f16d43, #fcab64, #fedc90, #faf8c0, #dcf1ec, #abd6e8, #76abd0, #4a74b4, #4a74b4);
padding:20px;
text-align: center;
}
.transparent-text {
font-size: 50px;
text-transform: uppercase;
display: inline-block;
border-radius: 5px;
padding: 5px 10px;
/* Here we go */
background: #fff;
color: #000;
mix-blend-mode: screen;
}
<div class="bg">
<p class="transparent-text">Transparent text</p>
</div>
UPDATE 3
An SVG solution, IE11 supports:
.bg {
background-image: linear-gradient(90deg, #a50026, #d3322b, #f16d43, #fcab64, #fedc90, #faf8c0, #dcf1ec, #abd6e8, #76abd0, #4a74b4, #4a74b4);
padding:20px;
text-align: center;
}
<div class="bg">
<svg viewbox="0 0 100 60">
<defs>
<g id="text">
<text text-anchor="middle" x="50" y="23" font-size="12">Transtarent text</text>
</g>
<mask id="mask" x="0" y="0" width="100" height="50">
<rect x="0" y="0" width="100" height="40" fill="#fff"/>
<use xlink:href="#text" />
</mask>
</defs>
<rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill="#fff" fill-opacity="1"/>
</svg>
</div>
Opacity is your friend:
#id {
opacity: 0.5; // For 50% opacity
}
.text {
opacity: 0.7; /* Can be varied to the transparency you want */
}
The opacity will change the text transparency.
Is there any way to make a transparent text cut out of a background effect like the one in the following image, with CSS?
It would be sad to lose all precious SEO because of images replacing text.
I first thought of shadows but I can't figure anything out...
The image is the site background, an absolute positioned <img> tag
It's possible with css3 but it's not supported in all browsers
With background-clip: text; you can use a background for the text, but you will have to align it with the background of the page
body {
background: url(http://www.color-hex.com/palettes/26323.png) repeat;
margin:10px;
}
h1 {
background-color:#fff;
overflow:hidden;
display:inline-block;
padding:10px;
font-weight:bold;
font-family:arial;
color:transparent;
font-size:200px;
}
span {
background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat;
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
display:block;
}
<h1><span>ABCDEFGHIKJ</span></h1>
http://jsfiddle.net/JGPuZ/1337/
Automatic Alignment
With a little javascript you can align the background automatically:
$(document).ready(function(){
//Position of the header in the webpage
var position = $("h1").position();
var padding = 10; //Padding set to the header
var left = position.left + padding;
var top = position.top + padding;
$("h1").find("span").css("background-position","-"+left+"px -"+top+"px");
});
body {
background: url(http://www.color-hex.com/palettes/26323.png) repeat;
margin:10px;
}
h1 {
background-color:#fff;
overflow:hidden;
display:inline-block;
padding:10px;
font-weight:bold;
font-family:arial;
color:transparent;
font-size:200px;
}
span {
background: url(http://www.color-hex.com/palettes/26323.png) -20px -20px repeat;
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><span>ABCDEFGHIKJ</span></h1>
http://jsfiddle.net/JGPuZ/1336/
Although this is possible with CSS, a better approach would be to use an inline SVG with SVG masking. This approach has some advantages over CSS :
Much better browser support: IE10+, chrome, Firefox, safari...
This doesn't impact SEO as spiders can crawl SVG content (google indexes SVG content since 2010)
CodePen Demo : SVG text mask
body,html{height:100%;margin:0;padding:0;}
body{
background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');
background-size:cover;
background-attachment:fixed;
}
svg{width:100%;}
<svg viewbox="0 0 100 60">
<defs>
<mask id="mask" x="0" y="0" width="100" height="50">
<rect x="0" y="0" width="100" height="40" fill="#fff"/>
<text text-anchor="middle" x="50" y="18" dy="1">SVG</text>
<text text-anchor="middle" x="50" y="30" dy="1">Text mask</text>
</mask>
</defs>
<rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/>
</svg>
If you aim on making the text selectable and searchable, you need to include it outside the <defs> tag. The following example shows a way to do that keeping the transparent text with the <use> tag:
body,html{height:100%;margin:0;padding:0;}
body{
background:url('https://farm9.staticflickr.com/8760/17195790401_94fcf60556_c.jpg');
background-size:cover;
background-attachment:fixed;
}
svg{width:100%;}
<svg viewbox="0 0 100 60">
<defs>
<g id="text">
<text text-anchor="middle" x="50" y="18" dy="1">SVG</text>
<text text-anchor="middle" x="50" y="30" dy="1">Text mask</text>
</g>
<mask id="mask" x="0" y="0" width="100" height="50">
<rect x="0" y="0" width="100" height="40" fill="#fff"/>
<use xlink:href="#text" />
</mask>
</defs>
<rect x="5" y="5" width="90" height="30" mask="url(#mask)" fill-opacity="0.5"/>
<use xlink:href="#text" mask="url(#mask)" />
</svg>
There is a simple way to do this with just CSS:
background: black;
color: white;
mix-blend-mode: multiply;
for transparent text on a black background, or
background: white;
color: black;
mix-blend-mode: screen;
for transparent text on a white background.
Put these styles on your text element with whichever background you want behind it.
Example CodePen
Read up on mix-blend-mode and experiment with it to use different colours.
Caveats:
For this to work in chrome, you also need to explicitly set a background colour on the html element.
This works on basically all modern browsers except IE.
It is possible, but so far only with Webkit based browsers (Chrome, Safari, Rockmelt, anything based on the Chromium project.)
The trick is to have an element within the white one that has the same background as the body, then use -webkit- background-clip: text; on the inner element which basically means "don't extend the background beyond the text" and use transparent text.
section
{
background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
width: 100%;
height: 300px;
}
div
{
background: rgba(255, 255, 255, 1);
color: rgba(255, 255, 255, 0);
width: 60%;
heighT: 80%;
margin: 0 auto;
font-size: 60px;
text-align: center;
}
p
{
background: url(http://norcaleasygreen.com/wp-content/uploads/2012/11/turf-grass1.jpg);
-webkit-background-clip: text;
}
http://jsfiddle.net/BWRsA/
just put that css
.banner-sale-1 .title-box .title-overlay {
font-weight: 900;
overflow: hidden;
margin: 0;
padding-right: 10%;
padding-left: 10%;
text-transform: uppercase;
color: #080404;
background-color: rgba(255, 255, 255, .85);
/* that css is the main think (mix-blend-mode: lighten;)*/
mix-blend-mode: lighten;
}
I just discovered a new way to do this while messing around, I'm not entirely sure how it works ( if someone else wants to explain please do ).
It seems to work very well, and requires no double backgrounds or JavaScript.
Here's the code:
JSFIDDLE
body {
padding: 0;
margin: 0;
}
div {
background: url(http://www.color-hex.com/palettes/26323.png) repeat;
width: 100vw;
height: 100vh;
}
body::before {
content: '$ALPHABET';
left: 0;
top: 0;
position: absolute;
color: #222;
background-color: #fff;
padding: 1rem;
font-family: Arial;
z-index: 1;
mix-blend-mode: screen;
font-weight: 800;
font-size: 3rem;
letter-spacing: 1rem;
}
<div></div>
In the near future we can use element() to achieve this
The element() function allows an author to use an element in the document as an image. As the referenced element changes appearance, the image changes as well ref
The trick is to create a common div with text then use element() combined with mask.
Here is a basic example that works only on the latest version Firefox for now.
#text {
font-size:35px;
font-weight:bold;
color:#000;
font-family:sans-serif;
text-transform: uppercase;
white-space:nowrap;
/* we hide it */
position:fixed;
right:200vw;
bottom:200vh
}
body {
background:url(https://picsum.photos/id/1018/800/800) center/cover;
}
.main {
margin:50px;
height:100px;
background:red;
-webkit-mask:
-moz-element(#text) center/contain no-repeat, /* this behave like a background-image*/
linear-gradient(#fff 0 0);
mask-composite:exclude;
}
<div id="text">
You can put your text here
</div>
<div class="main">
</div>
It will produce the following:
It's reponsive since we rely on basic background properties and we can easily update the text using basic CSS.
We can consider any kind of content and also create patterns:
#text {
font-size:30px;
font-weight:bold;
color:#000;
font-family:sans-serif;
text-transform: uppercase;
white-space:nowrap;
padding:20px;
/* we hide it */
position:fixed;
right:200vw;
bottom:200vh
}
#text span {
font-family:cursive;
font-size:35px;
}
body {
background:url(https://picsum.photos/id/1018/800/800) center/cover;
}
.main {
margin:50px;
height:100px;
background:red;
-webkit-mask:
-moz-element(#text) 0 0/20% auto, /* this behave like a background-image*/
linear-gradient(#fff 0 0);
mask-composite:exclude;
}
<div id="text">
Your <span>text</span> here 👍
</div>
<div class="main">
</div>
And why not some animation to create an infinite scrolling text:
#text {
font-size:30px;
font-weight:bold;
color:#000;
font-family:sans-serif;
text-transform: uppercase;
white-space:nowrap;
padding:20px 5px;
/* we hide it */
position:fixed;
right:200vw;
bottom:200vh
}
body {
background:url(https://picsum.photos/id/1018/800/800) center/cover;
}
.main {
margin:50px;
height:100px;
padding-right:calc(50% - 50px);
background:red;
-webkit-mask:
-moz-element(#text) 0 50%/200% auto content-box, /* this behave like a background-image*/
linear-gradient(#fff 0 0);
mask-composite:exclude;
animation:m 5s linear infinite;
}
#keyframes m{
to {-webkit-mask-position:200% 50%}
}
<div id="text">
Srolling repeating text here
</div>
<div class="main">
</div>
I guess you could achieve something like that using background-clip, but I haven't tested that yet.
See this example:
http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html
(Webkit only, I don't know yet how to change the black background to a white one)
You can use an inverted / negative / reverse font and apply it with the font-face="…" CSS rule. You might have to play with letter spacing to avoid small white gaps between letters.
If you do not require a specific font, it's simple. Download a likeable one, for example from this collection of inverted fonts.
If you require a specific font (say, "Open Sans"), it's difficult. You have to convert your existing font into an inverted version. This is possible manually with Font Creator, FontForge etc., but of course we want an automated solution. I could not find instructions for that yet, but some hints:
How to convert a bitmap font into a TrueType font (plus yet another way to do that). One would first use ImageMagick commands to render the font glyphs into high-resolution raster images and to invert them, then convert them back to a TrueType font with the above instructions.
Is it possible to invert a font with FontForge or another PGM?
Creating a reverse (white on black) font
You can use myadzel's Patternizer jQuery plugin to achieve this effect across browsers. At this time, there is no cross-browser way to do this with just CSS.
You use Patternizer by adding class="background-clip" to HTML elements where you want the text to be painted as an image pattern, and specify the image in an additional data-pattern="…" attribute. See the source of the demo. Patternizer will create an SVG image with pattern-filled text and underlay it to the transparently rendered HTML element.
If, as in the question's example image, the text fill pattern should be a part of a background image extending beyond the "patternized" element, I see two options (untested, my favourite first):
Use masking instead of a background image in the SVG. As in web-tiki's answer, to which using Patternizer will still add automatic generation of the SVG and an invisible HTML element on top that allows text selection and copying.
Or use automatic alignment of the pattern image. Can be done with JavaScript code similar to the one in Gijs's answer.
I needed to make text that looked exactly like it does in the original post, but I couldn't just fake it by lining up backgrounds, because there's some animation behind the element. Nobody seems to have suggested this yet, so here's what I did: (Tried to make it as easy to read as possible.)
var el = document.body; //Parent Element. Text is centered inside.
var mainText = "THIS IS THE FIRST LINE"; //Header Text.
var subText = "THIS TEXT HAS A KNOCKOUT EFFECT"; //Knockout Text.
var fontF = "Roboto, Arial"; //Font to use.
var mSize = 42; //Text size.
//Centered text display:
var tBox = centeredDiv(el), txtMain = mkDiv(tBox, mainText), txtSub = mkDiv(tBox),
ts = tBox.style, stLen = textWidth(subText, fontF, mSize)+5; ts.color = "#fff";
ts.font = mSize+"pt "+fontF; ts.fontWeight = 100; txtSub.style.fontWeight = 400;
//Generate subtext SVG for knockout effect:
txtSub.innerHTML =
"<svg xmlns='http://www.w3.org/2000/svg' width='"+stLen+"px' height='"+(mSize+11)+"px' viewBox='0 0 "+stLen+" "+(mSize+11)+"'>"+
"<rect x='0' y='0' width='100%' height='100%' fill='#fff' rx='4px' ry='4px' mask='url(#txtSubMask)'></rect>"+
"<mask id='txtSubMask'>"+
"<rect x='0' y='0' width='100%' height='100%' fill='#fff'></rect>"+
"<text x='"+(stLen/2)+"' y='"+(mSize+6)+"' font='"+mSize+"pt "+fontF+"' text-anchor='middle' fill='#000'>"+subText+"</text>"+
"</mask>"+
"</svg>";
//Relevant Helper Functions:
function centeredDiv(parent) {
//Container:
var d = document.createElement('div'), s = d.style;
s.display = "table"; s.position = "relative"; s.zIndex = 999;
s.top = s.left = 0; s.width = s.height = "100%";
//Content Box:
var k = document.createElement('div'), j = k.style;
j.display = "table-cell"; j.verticalAlign = "middle";
j.textAlign = "center"; d.appendChild(k);
parent.appendChild(d); return k;
}
function mkDiv(parent, tCont) {
var d = document.createElement('div');
if(tCont) d.textContent = tCont;
parent.appendChild(d); return d;
}
function textWidth(text, font, size) {
var canvas = window.textWidthCanvas || (window.textWidthCanvas = document.createElement("canvas")),
context = canvas.getContext("2d"); context.font = size+(typeof size=="string"?" ":"pt ")+font;
return context.measureText(text).width;
}
Just throw that in your window.onload, set the body's background to your image, and watch the magic happen!
mix-blend-mode is also a possibility for that kind of effect .
The mix-blend-mode CSS property sets how an element's content should blend with the content of the element's parent and the element's background.
h1 {
background:white;
mix-blend-mode:screen;
/* demo purpose from here */
padding:0.25em;
mix-blend-mode:screen;
}
html {
background:url(https://i.picsum.photos/id/1069/367/267.jpg?hmac=w5sk7UQ6HGlaOVQ494mSfIe902cxlel1BfGUBpEYoRw)center / cover ;
min-height:100vh;
display:flex;
}
body {margin:auto;}
h1:hover {border:dashed 10px white;background-clip:content-box;box-shadow:inset 0 0 0 2px #fff, 0 0 0 2px #fff}
<h1>ABCDEFGHIJKLMNOPQRSTUVWXYZ</h1>
This worked for me mix-blend-mode: color-dodge on the container with opposite colors.
.main{
background: url('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg');
height: 80vh;
width: 100vw;
padding: 40px;
}
.container{
background-color: white;
width: 80%;
height: 50px;
padding: 40px;
font-size: 3em;
font-weight: 600;
mix-blend-mode: color-dodge;
}
.container span{
color: black;
}
<div class="main">
<div class="container">
<span>This is my text</span>
</div>
</div>
Not possible with CSS just now I'm afraid.
Your best bet is to simply use an image (probably a PNG) and and place good alt/title text on it.
Alternatively you could use a SPAN or a DIV and have the image as a background to that with your text you want for SEO purposes inside it but text-indent it off screen.
I wanted to ask if there is a way I can add color to the icon I linked down below if I hover over it?
https://www.google.ch/search?q=linkedin&source=lnms&tbm=isch&sa=X&ved=0ahUKEwilrciPwpPVAhUEWhQKHYX7CxcQ_AUICigB&biw=1920&bih=949#tbm=isch&q=linkedin+black+icon&imgrc=eCztS3qV_QYT9M
For example how can I make the color only of the text "in" red if I hover over it? I think you have to do it in combination with a photo editor but I dont really know how. Thanks for help
This is my code I tried.
<section id="icons">
<img src="youtube.png" class="youtube" alt="">
</section>
.youtube {
background-image: url(youtube.png);
width: 5vw;
position: absolute;
}
.youtube:hover {
background-image: url(youtubehover.png);
width: 5vw;
position: absolute;
}
The best way to do this is to create two seperate images. One for when the icon is in its default state, and the other for when it is in its hover state. In the hover state, change the color to whatever you like, in your case red, so that when the user puts their mouse over it, they see that color.
Here is an example of some CSS to do this:
#icon {
background-image: url(../images/example_default.png)
width: 150px;
height: 150px;
position: absolute;
}
#icon: hover {
background-image: url(../images/example_hover.png)
width: 150px;
height: 150px;
position: absolute;
cursor: pointer;
}
:hover changes what the image will look like when the user hovers over the icon. Notice the background images are different, one for each state the icon could be in. I also added cursor: pointer assuming this icon will be a button of some sort.
You can use a svg (no problems with resizing) and change the fill color at hover.
The svg the path must have the id="linkedin" to change the color.
svg:hover #linkedin {
fill: red; //or #ff0000
}
<svg enable-background="new 0 0 56.693 56.693" height="56.693px" id="Layer_1" version="1.1" viewBox="0 0 56.693 56.693" width="56.693px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<path d="M30.071,27.101v-0.077c-0.016,0.026-0.033,0.052-0.05,0.077H30.071z"/>
<path id="linkedin" fill="#000" d="M49.265,4.667H7.145c-2.016,0-3.651,1.596-3.651,3.563v42.613c0,1.966,1.635,3.562,3.651,3.562h42.12 c2.019,0,3.654-1.597,3.654-3.562V8.23C52.919,6.262,51.283,4.667,49.265,4.667z M18.475,46.304h-7.465V23.845h7.465V46.304z M14.743,20.777h-0.05c-2.504,0-4.124-1.725-4.124-3.88c0-2.203,1.67-3.88,4.223-3.88c2.554,0,4.125,1.677,4.175,3.88 C18.967,19.052,17.345,20.777,14.743,20.777z M45.394,46.304h-7.465V34.286c0-3.018-1.08-5.078-3.781-5.078 c-2.062,0-3.29,1.389-3.831,2.731c-0.197,0.479-0.245,1.149-0.245,1.821v12.543h-7.465c0,0,0.098-20.354,0-22.459h7.465v3.179 c0.992-1.53,2.766-3.709,6.729-3.709c4.911,0,8.594,3.211,8.594,10.11V46.304z"/>
</g>
</svg>
<path id="linkedin" fill="#000" d="M49.265,[...],10.11V46.304z" />
Since the image is black and white, you can use this.
.red:hover {
filter: contrast(50%) sepia(100%) saturate(100) hue-rotate(-10deg);
}
<img class="red" src="https://www.gravatar.com/avatar/034851bd177962980fdc2f79b08c7639?s=48&d=identicon&r=PG&f=1">
I had to make the text inside the icon blank using magic wand with paint.net. I also deleted the white color of the edges. With the following code I changed the color from the text or the content inside the icon from white to red when I hover over it.
<section id="icons">
<img src="yourimage.png" alt="">
</section>
CSS:
#icons img {
width: 5vw;
padding: 0;
}
#icons img:hover {
background-color: red;
border-radius: 100%;
overflow: hidden;
}
This can be easily accomplished by placing a colored div behind the image, and then using the following simple jQuery to automatically hide the div and show it when the mouse is over:
$(document).ready(function() {
$("#divColor").hide();
$("#imgLogo").mouseover(function() {
$("#divColor").show();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img id="imgLogo" src="https://www.iconsdb.com/icons/preview/black/linkedin-4-xxl.png" alt="icon" height="100" width="100" style="position:absolute:top:-100px;">
<div id="divColor" style="background-color:red;width:60px;height:60px;position:absolute;left:30px;top:28px;z-index:-1;"></div>
I would like to use HTML + CSS to draw a arc sector with fixed radix and length (e.g. 30px radius and 70% length).
I found so far most of the solution is to combined two pictures with position:absoulte. Unfortunately, my html codes will be embedded as an email template to send out, and I found that Gmail does not support absolute position. And that is also the reason why I would like to use inline style rather than header css.
Related question here:
HTML5 / CSS3 Circle with Partial Border
The similar output I am looking for.
http://dabblet.com/gist/3949571
Any help for it?
I'd use an SVG.
svg {
width: 150px;
height: 150px;
}
circle.inner {
stroke: rebeccapurple;
stroke-width: 3;
stroke-dasharray: 39% 139%;
stroke-dashoffset: 78%;
fill: pink;
}
<svg viewbox="0 0 100 100">
<circle class="inner" cx="40" cy="40" r="25" />
</svg>
you can use transparent borders and inset shadow to draw bg color :
/*demo*/
div {
display:flex;
align-items:center;
justify-content:center;/* center content not text */
text-align:center;
}
<div style="
box-sizing:border-box;
padding:1px;
margin:5px;
height:200px;
width:200px;
border:solid 20px transparent;
border-top-color:blue;
box-shadow:inset 0 0 0 100px lightblue;
border-radius:100%;"
>Some text <br/> too?</div>
Is it possible to create the shape produced by this Fiddle. But then with no JavaScript but CSS3 (with <div>) ?
Basically this:
for(var i = 0; i < coords.length; i += 1) {
if(coords[(i + 1)] != undefined) {
ctx.beginPath();
ctx.moveTo(coords[i].x, coords[i].y);
ctx.lineTo(coords[(i + 1)].x, coords[(i + 1)].y);
ctx.stroke();
} else {
ctx.beginPath();
ctx.moveTo(coords[i].x, coords[i].y);
ctx.lineTo(coords[0].x, coords[0].y);
ctx.stroke();
}
}
So you have points that needs to connect to each other?
Use svg, if you don't want to use canvas.
<svg width="100" height="100">
<path d="M0 0 l100 10 l-40 90z" fill="none" stroke="black" stroke-width="2" />
</svg>
Path command for 8,8,10,10,30,30,49,10 would be M8 8 L10 10 L30 40 L49 10z.
<svg width="49" height="40" viewBox="0 0 50 41">
<path d="M8 8 L10 10 L30 40 L49 10z" fill="none" stroke="black" stroke-width="2" />
</svg>
To apply a click event to the shape, you could use pointer-events: all on #test.
#test {
pointer-events: all;
}
<svg width="49" height="40" viewBox="0 0 50 41">
<path id="test" d="M8 8 L10 10 L30 40 L49 10z" fill="none" onclick="alert('Works')" stroke="black" stroke-width="2" />
</svg>
Note: Posting this answer just because you asked with CSS3, but the complexity and possible calculation overhead involved in this approach is proof enough why CSS shouldn't be used for this. Please do not use this approach.
A bit of explanation on how this was achieved:
A div is created with top and right border (1px black) and the other two borders are set to none.
This div is then skewed a bit to make it appear as though the edge on the right side is a bit slanted.
Inside the shape, a pseudo-element with only a right border is created and it is also skewed to produce the diagonal line from the right-bottom to the left-top. Transform origin is set as right-bottom to avoid positioning overhead.
An anchor tag is added within the parent div and the overflow is set to hidden so that only the portion within the shape is clickable.
The user select on the anchor tag are disabled to prevent a double click from selecting a blank space within the div.
Finally the whole container div is rotated a bit to make it look as though the triangle is not parallel to x-axis.
document.getElementById("clickme").onclick = function() {
alert('Hi! I work alright.');
}
div {
position: relative;
height: 50px;
width: 45px;
border: 1px solid black;
border-left: none;
border-bottom: none;
-webkit-transform: skew(-10deg) rotate(5deg);
-moz-transform: skew(-10deg) rotate(5deg);
transform: skew(-10deg) rotate(5deg);
overflow: hidden;
}
a {
display: block;
content: '';
margin-left: 0px;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
height: 100%;
width: 100%;
}
div:after {
position: absolute;
top: 0px;
left: 0px;
content: '';
height: 50px;
width: 45px;
-webkit-transform: skew(42deg);
-webkit-transform-origin: left bottom;
-moz-transform: skew(42deg);
-moz-transform-origin: left bottom;
transform: skew(42deg);
transform-origin: left bottom;
border-right: 1px solid black;
}
<div>
</div>
Another option to create a skewed triangle shape would be to use clip-path like in below snippet. The shape is created by applying the same clip-path on the main container element and a pseudo-element which is smaller than the container.
document.getElementById("clickme").onclick = function() {
alert('Hi! I work alright.');
}
div {
position: relative;
height: 150px;
width: 150px;
background: black;
-webkit-clip-path: polygon(0% 0%, 100% 20%, 70% 100%);
}
div:after{
position: absolute;
content: '';
height: calc(100% - 5px);
width: calc(100% - 5px);
top: 2px;
left: 3px;
background: white;
-webkit-clip-path: polygon(0% 0%, 100% 20%, 70% 100%);
}
/* Just for demo */
div{
transition: all 1s;
}
div:hover{
height: 250px;
width: 250px;
}
<div id="clickme"></div>
You can do it by embeding SVG as CSS. Quote from:
http://css-tricks.com/using-svg/
"Another way to use SVG's is to convert them into Data URI's. Data URI's might not save you actual file size, but can be more efficient because the data is right there. It doesn't require an additional HTTPRequest.
Mobilefish.com has an online conversion tool for that (http://www.mobilefish.com/services/base64/base64.php). Simply paste in the contents of your SVG file and fill out the form and it will display the results in a textarea for you to copy. Remember to remove line breaks in the data it gives you back.
...
You can use that anywhere we've talked about so far (except inline because that just doesn't make sense) Just put the gibberish where it says [data] in these examples.
As CSS
.logo {
background: url(data:image/svg+xml;base64,[data]);
}
"