Existe-t-il un moyen d'utiliser le texte comme arrière-plan avec CSS?

90

Je souhaite utiliser du texte dynamique comme arrière-plan de certains éléments de ma balise. Pour cette raison, je peux utiliser des images (texte dynamique). Comment faire avec juste CSS ou JavaScript?

chustar
la source

Réponses:

81

Vous pouvez avoir un élément positionné de manière absolue à l'intérieur de votre élément positionné relatif:

<div id="container">
    <div id="background">
    Text to have as background
    </div>
    Normal contents
</div>

Et puis le CSS:

#container {
   position: relative;
}

#background {
   position: absolute;
   top: 0;
   left: 0;
   bottom: 0;
   right: 0;
   z-index: -1;
   overflow: hidden;
}

En voici un exemple .

Paolo Bergantino
la source
144

Image de fond de texte SVG

body {
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='50px' width='120px'><text x='0' y='15' fill='red' font-size='20'>I love SVG!</text></svg>");
}
<p>I hate SVG!</p><p>I hate SVG!</p><p>I hate SVG!</p><p>I hate SVG!</p>
<p>I hate SVG!</p><p>I hate SVG!</p><p>I hate SVG!</p><p>I hate SVG!</p>

Voici une version en retrait du CSS pour que vous puissiez mieux comprendre. Notez que cela ne fonctionne pas , vous devez utiliser à la place le SVG de doublure unique de l'extrait de code ci-dessus:

body {
  background-image:url("data:image/svg+xml;utf8,
  <svg xmlns='http://www.w3.org/2000/svg' version='1.1'
       height='50px' width='120px'>
    <text x='0' y='15' fill='red' font-size='20'>I love SVG!</text>
  </svg>");
}

Je ne sais pas à quel point cela est portable (fonctionne sur Firefox 31 et Chrome 36), et c'est techniquement une image ... mais la source est en texte brut et en ligne, et elle évolue à l'infini.

@senectus a constaté que cela fonctionne mieux sur IE si vous l'encodez en base64: https://stackoverflow.com/a/25593531/895245

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Intéressant. Je n'ai pu faire fonctionner cela que dans Firefox 31, mais pas dans Chrome 36 ou Safari 7.
JP Richardson
@JPRichardson Vrai, pareil ici. Sur Chrome 36 j'ai l'impression que le fond est là, mais sur des lettres minuscules. Peut-être que j'oublie de définir un paramètre de taille d'arrière-plan / SVG?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Oui, j'expérimente en ce moment ... ça ressemble peut-être à "viewBox"? Je suis toujours en train de jouer avec ça.
JP Richardson
1
Ciro: sur la base de votre réponse, j'ai pu mettre cela ensemble ... a plutôt bien fonctionné! Merci! codepen.io/jprichardson/pen/GnxKr
JP Richardson
2
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功 bonne réponse! Avez-vous des idées pour améliorer le rendu sur Chrome? Ça a l'air vraiment mauvais là-bas. Merci d'avance
Alejandro García Iglesias
46

Cela peut être possible (mais très hackish) avec uniquement CSS utilisant les pseudo éléments: before ou: after:

.bgtext {
  position: relative;
}

.bgtext:after {
  content: "Background text";
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
}
<div class="bgtext">
  Foreground text
</div>

Cela semble fonctionner, mais vous devrez probablement le modifier un peu. Notez également que cela ne fonctionnera pas dans IE6 car il ne prend pas en charge :after.

Chèvre mécontente
la source
Mise à jour: pour l'instant, tous les navigateurs modernes prennent en charge les pseudo éléments. Par exemple, c'est ainsi que FontAwesome fonctionne pour les icônes CSS (en utilisant: before sur les éléments en ligne).
Cédric Françoys
21

La solution de Ciro concernant un arrière-plan URI de données SVG contenant le texte est très intelligente.

Cependant, cela ne fonctionnera pas dans IE si vous ajoutez simplement la source SVG simple à l'URI de données.

Afin de contourner ce problème et de le faire fonctionner dans IE9 et plus, encodez le SVG en base64. C'est un excellent outil.

Donc ça:

background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><text x="5%" y="5%" font-size="30" fill="red">I love SVG!</text></svg>');

Devient ceci:

background:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0ZXh0IHg9IjUlIiB5PSI1JSIgZm9udC1zaXplPSIzMCIgZmlsbD0icmVkIj5JIGxvdmUgU1ZHITwvdGV4dD48L3N2Zz4=');

Testé et fonctionne dans IE9-10-11, WebKit (Chrome 37, Opera 23) et Gecko (Firefox 31).

http://jsfiddle.net/qapp5dLn/

sénectus
la source
1
C'est un meilleur outil: jpillora.com/base64-encoder simpile, pas d'erreurs, remplissage automatique, aperçu d'image. Oui, c'est mieux à pas de géant.
Jack Giffin
9

@Ciro

Vous pouvez casser le code svg en ligne avec une barre oblique inverse "\"

Testé avec le code ci-dessous dans Chrome 54 et Firefox 50

body {
    background: transparent;
    background-attachment:fixed;
    background-image: url(
    "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='170px' height='50px'> \
    <rect x='0' y='0' width='170' height='50' style='stroke:white; fill:gray; stroke-opacity: 0.3; stroke-width: 3px; fill-opacity: 0.7; stroke-dasharray: 10 5; stroke-linecap=round; '/> \
    <text x='85' y='30' style='fill:lightBlue; text-anchor: middle' font-size='16' transform='rotate(10,85,25)'>I love SVG!</text></svg>");
}

J'ai même testé ceci,

background-image: url("\
data:image/svg+xml;utf8, \
  <svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='170px' height='50px'> \
    <rect x='0' y='0' width='170' height='50'\
      style='stroke:white; stroke-width: 3px; stroke-opacity: 0.3; \
             stroke-dasharray: 10 5; stroke-linecap=round; \
             fill:gray;  fill-opacity: 0.7; '/> \
    <text x='85' y='30' \
      style='fill:lightBlue; text-anchor: middle' font-size='16' \
      transform='rotate(10,85,25)'> \
      I love SVG! \
    </text> \
  </svg>\
");

et cela fonctionne (au moins dans Chrome 54 et Firefox 50 ==> utilisation dans NWjs et Electron garantie)

Athmailer
la source
5

En utilisant du CSS pur:

(Mais utilisez ceci en de rares occasions, car la méthode HTML est PREFERRED WAY ).

.container{
	position:relative;
}
.container::before{ 
	content:"";
	width: 100%; height: 100%; position: absolute; background: black; opacity: 0.3; z-index: 1;  top: 0;   left: 0;
	background: black;
}
.container::after{ 
	content: "Your Text"; position: absolute; top: 0; left: 0; bottom: 0; right: 0; z-index: 3; overflow: hidden; font-size: 2em; color: red;    text-align: center; text-shadow: 0px 0px 5px black; background: #0a0a0a8c; padding: 5px;
	animation-name: blinking;
	animation-duration: 1s;
	animation-iteration-count: infinite;
	animation-direction: alternate;
}
@keyframes blinking {
	0% {opacity: 0;}
	100% {opacity: 1;}
}
<div class="container">here is main content, text , <br/> images and other page details</div>

T.Todua
la source
2

Vous pouvez faire en sorte que l'élément contenant le texte bg ait un ordre d'empilement inférieur (z-index, position) et éventuellement définir l'opacité. Ainsi, l'élément dont vous avez besoin en haut aurait besoin d'un ordre d'empilement plus élevé (z-index: 5; position: relative; par exemple) et l'élément derrière aurait besoin de quelque chose de plus bas (par défaut ou simplement d'un z-index inférieur comme 3 et position: relative ;).

meder omuraliev
la source