Existe-t-il un moyen de créer un texte transparent découpé dans un effet d’arrière-plan comme celui de l’image suivante, avec CSS?
Il serait triste de perdre tout précieux référencement en raison du remplacement du texte par des images.
J'ai d'abord pensé aux ombres mais je n'arrive pas à comprendre quoi que ce soit ...
L'image est l'arrière-plan du site, une balise <img>
positionnée de manière absolue.
C'est possible avec css3 mais ce n'est pas supporté par tous les navigateurs
Avec clip de fond: texte; vous pouvez utiliser un arrière-plan pour le texte, mais vous devrez l'aligner sur l'arrière-plan de la 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/
Alignement automatique
avec un peu de javascript vous pouvez aligner le fond automatique:
$(document).ready(function(){
var position = $("h1").position(); //Position of the header in the webpage
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>
Bien que cela soit possible avec CSS, une meilleure approche consisterait à utiliser un masquage SVG inline with SVG masking . Cette approche présente certains avantages par rapport à CSS:
Démo CodePen: Masque de texte SVG
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>
Si vous souhaitez rendre le texte sélectionnable et consultable, vous devez l'inclure en dehors de la balise <defs>
. L'exemple suivant montre une façon de le faire en conservant le texte transparent avec la balise <use>
:
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>
Une façon qui fonctionne sur la plupart des navigateurs modernes (sauf Edge), bien que seulement avec un fond noir, consiste à utiliser
background: black;
color: white;
mix-blend-mode: multiply;
dans votre élément de texte et mettez ensuite l’arrière-plan de votre choix. Multiply fait essentiellement correspondre le code de couleur 0-255 à 0-1, puis multiplie ce qui est derrière, ainsi le noir reste noir et blanc multiplié par 1 et devient effectivement transparent . http://codepen.io/ nic_klaassen/full/adKqWX/
Cela est possible, mais uniquement avec les navigateurs Webkit (Chrome, Safari, Rockmelt, tout ce qui est basé sur le projet Chromium.)
L'astuce consiste à avoir un élément dans l'élément blanc qui a le même arrière-plan que le corps, puis utilisez -webkit- background-clip: text;
sur l'élément interne, ce qui signifie fondamentalement "ne prolongez pas l'arrière-plan au-delà du texte" et utilisez du texte transparent.
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;
}
Je suppose que vous pourriez obtenir quelque chose comme ça en utilisant background-clip
, mais je ne l’ai pas encore testé.
Voir cet exemple:
http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html
(Webkit uniquement, je ne sais pas encore comment changer le fond noir en blanc)
Je viens de découvrir une nouvelle façon de faire tout en déconnant, je ne suis pas tout à fait sûr de savoir comment cela fonctionne (si quelqu'un d'autre veut expliquer s'il vous plaît faites-le).
Il semble fonctionner très bien et ne nécessite pas de double arrière-plan ou JavaScript.
Voici le 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>
Je devais créer un texte qui ressemblait exactement à celui du message d'origine, mais je ne pouvais pas simplement le simuler en alignant des arrière-plans, car il y avait une animation derrière l'élément. Personne ne semble l'avoir suggéré encore, alors voici ce que j'ai fait: (J'ai essayé de le rendre aussi facile à lire que 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;
}
Il suffit de jeter cela dans le chargement de votre fenêtre, de définir le fond du corps à votre image et de regarder la magie se produire!
Vous pouvez utiliser une police inversée/négative/inverse et l'appliquer à l'aide de la règle CSS font-face="…"
. Vous devrez peut-être jouer avec l'espacement des lettres pour éviter les petits espaces blancs entre les lettres.
Si vous n'avez pas besoin d'une police spécifique, c'est simple. Téléchargez un fichier sympathique, par exemple, à partir de cette collection de polices inversées .
Si vous avez besoin d'une police spécifique (par exemple, "Open Sans"), c'est difficile. Vous devez convertir votre police existante en une version inversée. Ceci est possible manuellement avec Font Creator, FontForge, etc., mais nous souhaitons bien sûr une solution automatisée. Je n'ai pas encore trouvé d'instructions à ce sujet, mais quelques astuces:
Vous pouvez utiliser Patternizer jQuery plugin de myadzel pour obtenir cet effet sur tous les navigateurs. À l'heure actuelle, il n'y a pas de moyen de navigation croisée entre les navigateurs pour le faire uniquement avec CSS.
Vous utilisez Patternizer en ajoutant class="background-clip"
aux éléments HTML à l'endroit où vous souhaitez que le texte soit peint en tant que motif d'image et en spécifiant l'image dans un attribut data-pattern="…"
supplémentaire. Voir la source de la demo . Patternizer créera une image SVG avec du texte rempli de motifs et la superposera à l'élément HTML restitué de manière transparente.
Si, comme dans l'exemple d'image de la question, le motif de remplissage de texte doit faire partie d'une image d'arrière-plan s'étendant au-delà de l'élément "modelé", je vois deux options (non testé, mon préféré en premier):
il suffit de mettre ce 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;
}
Pas possible avec CSS tout à l'heure, j'ai bien peur.
Votre meilleur choix est simplement d’utiliser une image (probablement un fichier PNG) et d’y placer un bon texte alt/titre.
Sinon, vous pouvez utiliser un SPAN ou un DIV et avoir l’image en arrière-plan avec le texte que vous voulez, à des fins de référencement, mais en la mettant en retrait à l’écran.