¿Hay alguna forma de usar texto como fondo con CSS?

92

Me gustaría usar texto dinámico como fondo de ciertos elementos en mi etiqueta. Por eso, puedo usar imágenes (texto dinámico). ¿Cómo lo hago solo con CSS o JavaScript?

chustar
fuente

Respuestas:

81

Puede tener un elemento absolutamente posicionado dentro de su elemento posicionado relativo:

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

Y luego el CSS:

#container {
   position: relative;
}

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

He aquí un ejemplo de ello .

Paolo Bergantino
fuente
146

Imagen de fondo de texto 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>

Aquí hay una versión con sangría del CSS para que pueda comprender mejor. Tenga en cuenta que esto no funciona , debe usar el SVG de una sola línea del fragmento anterior en su lugar:

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>");
}

No estoy seguro de cuán portátil es esto (funciona en Firefox 31 y Chrome 36), y técnicamente es una imagen ... pero la fuente es texto en línea y sin formato, y se escala infinitamente.

@senectus descubrió que funciona mejor en IE si lo codifica en base64: https://stackoverflow.com/a/25593531/895245

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Interesante. Solo pude hacer que esto funcione en Firefox 31, pero no en Chrome 36 o Safari 7.
JP Richardson
@JPRichardson Es cierto, lo mismo aquí. En Chrome 36 tengo la impresión de que el fondo está ahí, pero en letras muy pequeñas. ¿Quizás me estoy olvidando de establecer algún parámetro de tamaño de fondo / SVG?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Sí, estoy experimentando con él en este momento ... ¿parece que tal vez "viewBox"? Todavía estoy jugando con eso.
JP Richardson
1
Ciro: Basándome en tu respuesta, pude armar esto ... ¡funcionó bastante bien! ¡Gracias! codepen.io/jprichardson/pen/GnxKr
JP Richardson
2
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功 ¡gran respuesta! ¿Tiene alguna idea sobre cómo mejorar el renderizado en Chrome? Se ve muy mal ahí. Gracias de antemano
Alejandro García Iglesias
47

Puede ser posible (pero muy pirateado) con solo CSS usando los pseudo elementos: before o: after:

.bgtext {
  position: relative;
}

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

Esto parece funcionar, pero probablemente debas modificarlo un poco. También tenga en cuenta que no funcionará en IE6 porque no es compatible con :after.

Cabra descontento
fuente
Actualización: por ahora, todos los navegadores modernos admiten pseudo elementos. Por ejemplo, así es como funciona FontAwesome para los iconos CSS (usando: before en elementos en línea).
Cédric Françoys
Solo tenga en cuenta que Firefox no permite: antes y: después en elementos que no pueden tener contenido interno, como campos de entrada. Esto respeta la especificación oficial de CSS.
Nicolas Bouliane
21

La solución de Ciro sobre un fondo URI de datos SVG que contiene el texto es muy inteligente.

Sin embargo, no funcionará en IE si solo agrega la fuente SVG simple al URI de datos.

Para solucionar esto y hacerlo funcionar en IE9 y versiones posteriores, codifique el SVG en base64. Esta es una gran herramienta.

Así que esto:

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>');

Se convierte en esto:

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

Probado y funciona en IE9-10-11, WebKit (Chrome 37, Opera 23) y Gecko (Firefox 31).

http://jsfiddle.net/qapp5dLn/

senectus
fuente
1
Esta es una herramienta mejor: jpillora.com/base64-encoder simple, sin errores, autocompletado, vista previa de la imagen. Sí, es mejor a pasos agigantados.
Jack Giffin
9

@Ciro

Puede romper el código svg en línea con barra invertida "\"

Probado con el siguiente código en Chrome 54 y 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>");
}

Incluso probé esto

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>\
");

y funciona (al menos en Chrome 54 y Firefox 50 ==> uso en NWjs y Electron garantizado)

Athmailer
fuente
5

Usando CSS puro:

(Pero use esto en raras ocasiones, porque el método HTML es la FORMA PREFERIDA ).

.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
fuente
2

Puede hacer que el elemento que contiene el texto bg tenga un orden de apilamiento más bajo (índice z, posición) y posiblemente incluso establecer la opacidad. Entonces, el elemento que necesita en la parte superior necesitaría un orden de apilamiento más alto (índice z: 5; posición: relativa; por ejemplo) y el elemento detrás necesitaría algo más bajo (predeterminado o simplemente un índice z más bajo como 3 y posición: relativa ;).

meder omuraliev
fuente
0

Espero que esto te ayude

<!DOCTYPE html>
<html>
<head>
<style>

 :root:after { 
         
            content: "Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark   Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark Watermark "; 
            position: fixed; 
            transform: rotate(300deg); 
            -webkit-transform: rotate(300deg); 
            color: rgb(187, 182, 182); 
            top:0;                     
            z-index: -1; 
        } 
</style>
</head>
<body>
<p>hey my name is JHM</p>
</body>
</html>

JHM16
fuente