Przezroczysty tekst wycięty z tła

92

Czy istnieje sposób na utworzenie przezroczystego tekstu z efektu tła , takiego jak na poniższym obrazku, za pomocą CSS?
Szkoda byłoby stracić wszystkie cenne SEO z powodu obrazów zastępujących tekst.

Przezroczysty tekst wycięty z tła

Najpierw pomyślałem o cieniach, ale nic nie mogę zrozumieć ...

Obraz jest tłem witryny, <img>tagiem pozycjonowanym bezwzględnie

Miłość Dager
źródło
„stracić cenne SEO z powodu obrazów zastępujących tekst”. Istnieją również techniki zastępowania obrazu, które nadal są tak przyjazne. BTW: właściwie tło za literami również musi pozostać przezroczyste, co jest problemem tutaj…
feeela
tak, to byłaby świetna praktyka, jeśli to możliwe z css ...
Jessica Lingmn
Nie widzę powodu, dla którego <h1><img alt="Some Text" /></h1>jest mniej przyjazny dla SEO niż <h1>Some Text</h1>. Tradycyjnie problem z obrazami polegał na tym, że zostały one właśnie zrzucone na stronę bez obsługujących je znaczników.
cimmanon
@cimmanon Tak, masz rację. Prawdopodobnie mógłbym używać obrazów bez utraty punktów SEO, ale nadal nie możesz wybierać tekstu, wyszukiwać na stronie, linkowanie będzie bardziej skomplikowane, a aktualizacja tekstu będzie dużo więcej pracy ...: /
Love Dager
2
Tak, żebyś wiedział, Google jest super z technikami zastępowania obrazów CSS: mezzoblue.com/archives/2008/05/05/image_replac
cimmanon,

Odpowiedzi:

47

Jest to możliwe z css3, ale nie jest obsługiwane we wszystkich przeglądarkach

Z klipem w tle: tekst; możesz użyć tła dla tekstu, ale będziesz musiał wyrównać je z tłem strony

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/


Automatyczne wyrównanie

Za pomocą małego javascript możesz automatycznie wyrównać tło:

$(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>
Wcześniejsze

http://jsfiddle.net/JGPuZ/1336/

Gijs
źródło
A wy, ludzie, jesteście ZA szybcy: D
Gijs,
Świetnie! Przetestuję automatyczne wyrównanie tak szybko, jak wrócę do domu! Dziękuję Ci! : D
Love Dager
może trzeba trochę zmienić kod, zależy to od sytuacji, teraz może kolidować z innymi elementami, a ten został napisany bardzo szybko, jeśli masz jakieś pytania, usłyszę je
Gijs
3
Nie lekceważ odpowiedzi, która jest naprawdę fajnym rozwiązaniem, ale background-clip:textjest niestandardową opcją tylko w Webkicie. CSS3 nie zezwala na textwartość tego atrybutu ( zobacz ).
tanius
1
Ta technika pozwala zobaczyć tło elementu, na którym normalnie znajdowałby się tekst. Szukam sposobu, aby zobaczyć, co znajduje się pod elementem z tekstem, przez miejsce, w którym normalnie byłby tekst.
Vince
49

Chociaż jest to możliwe w przypadku CSS, lepszym podejściem byłoby użycie wbudowanego SVG z maskowaniem SVG . To podejście ma kilka zalet w porównaniu z CSS:

CodePen Demo: maska ​​tekstowa SVG

przezroczyste tło przycinania tekstu

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>

Jeśli chcesz, aby tekst był zaznaczalny i możliwy do przeszukiwania, musisz umieścić go poza <defs>znacznikiem. Poniższy przykład pokazuje, jak to zrobić, zachowując przezroczysty tekst ze <use>znacznikiem:

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>

web-tiki
źródło
2
Wydaje się, że jest to jedyne rozwiązanie, które działa dziś na różnych przeglądarkach: IE11, FF, Chrome, Safari. I nie potrzebuje obrazu jako tła, jak wiele innych rozwiązań problemu w całej sieci.
Timo Kähkönen
1
Zainspirowany tą odpowiedzią stworzyłem animację klatek kluczowych, w której przezroczysty tekst SVG na białym zaokrąglonym prostokącie obraca się. Tło zawiera tekst i obrazy. Idź i zobacz: jsbin.com/nipuqu/3 ( Nadchodzą mistrzostwa świata :))
Timo Kähkönen
2
Niezłe rozwiązanie, ale ponieważ „wybierz tekst i wyszukaj na stronie” wydaje się być w wymaganiach OP, możesz chcieć uwzględnić <text>zewnętrzną <defs>część części. (przy okazji nie jestem pewien, jak roboty SE radzą sobie z zawartością SVG w definicjach). Oto sposób na zachowanie tego, czego chce OP, z okropnym exploitem
Kaiido
A co jeśli tekst jest dynamiczny? Dawki nie dostosowują automatycznie szerokości.
Imran Bughio
1
@ImranBughio nie, nie ma. Tekst SVG nie działa jak zwykły tekst HTML. Musisz to ustawić. Aby uzyskać więcej informacji, zobacz tutaj
web-tiki
16

Jednym ze sposobów, który działa w większości nowoczesnych przeglądarek (z wyjątkiem np. Edge), chociaż tylko na czarnym tle, jest użycie

background: black;
color: white;
mix-blend-mode: multiply;

w elemencie tekstowym, a następnie umieść za nim dowolne tło. Pomnóż w zasadzie odwzorowuje kod koloru 0-255 na 0-1, a następnie mnoży go przez to, co jest za nim, więc czarny pozostaje czarny, a biały mnoży się przez 1 i staje się przezroczysty. http://codepen.io/nic_klaassen/full/adKqWX/

Nic
źródło
3
Na białym tle z czarnym użycia koloru color-dodge, lightenlub screennamix-blend-mode
Imran Bughio
3

Jest to możliwe, ale jak dotąd tylko z przeglądarkami opartymi na Webkit (Chrome, Safari, Rockmelt, wszystko oparte na projekcie Chromium).

Sztuczka polega na tym, aby mieć element w kolorze białym, który ma to samo tło co ciało, a następnie użyć -webkit- background-clip: text;na elemencie wewnętrznym, co w zasadzie oznacza „nie rozciągaj tła poza tekst” i użyć przezroczystego tekstu.

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/

Kyle
źródło
Fajna sztuczka! Ale teraz, żeby wszystko właściwie wyrównać, będzie dziwką ... -.-
Love Dager,
Tak, to kolejny problem. Nadal jest w fazie rozwoju i mam szczerą nadzieję, że wkrótce zobaczymy coś takiego! :)
Kyle
Ponadto zawsze możesz nałożyć warstwę na przezroczysty tekst na obrazie, aby nadal można go było wybrać. Ale jestem pewien, że to zła praktyka dla SEO. Ukryte wiadomości / słowa kluczowe i tym podobne.
Kyle,
Jestem pewien, że wygląda bardzo ładnie w przeglądarkach Webkit, ale dla wszystkich innych jest to półprzezroczyste białe pudełko na trawie.
cimmanon
1
Ach, dajcie spokój ... Tak, planuję użyć tego w produkcji. Ale oczywiście nie bez rozwiązania awaryjnego! @cimmanon
Love Dager,
2

Właśnie odkryłem nowy sposób na zrobienie tego podczas zabawy, nie jestem do końca pewien, jak to działa (jeśli ktoś inny chce wyjaśnić, zrób).

Wydaje się, że działa bardzo dobrze i nie wymaga podwójnego tła ani JavaScript.

Oto kod: 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>

ChrisBrownie55
źródło
1

Możesz użyć czcionki odwróconej / negatywnej / odwróconej i zastosować ją z font-face="…"regułą CSS. Być może będziesz musiał bawić się odstępami między literami, aby uniknąć małych białych przerw między literami.

Jeśli nie potrzebujesz określonej czcionki, jest to proste. Pobierz sympatyczny, na przykład z tej kolekcji odwróconych czcionek .

Jeśli potrzebujesz określonej czcionki (np. „Open Sans”), jest to trudne. Musisz przekonwertować istniejącą czcionkę na odwróconą wersję. Jest to możliwe ręcznie za pomocą Font Creator, FontForge itp., Ale oczywiście chcemy zautomatyzowanego rozwiązania. Nie mogłem jeszcze znaleźć instrukcji, ale kilka wskazówek:

taniusz
źródło
1

Możesz użyć wtyczki Patternizer jQuery firmy myadzel, aby osiągnąć ten efekt w różnych przeglądarkach. W tej chwili nie można tego zrobić w różnych przeglądarkach za pomocą samego CSS.

Używasz Patternizera, dodając class="background-clip"do elementów HTML, w których chcesz, aby tekst był malowany jako wzorzec obrazu, i określ obraz w dodatkowym data-pattern="…"atrybucie. Zobacz źródło demo . Patternizer utworzy obraz SVG z tekstem wypełnionym wzorami i umieści go na przezroczystym renderowanym elemencie HTML.

Jeśli, jak na przykładowym obrazku pytania, wzór wypełnienia tekstu powinien być częścią obrazu tła wykraczającego poza element „wzorzysty”, widzę dwie opcje (nieprzetestowane, najpierw moja ulubiona):

  • Użyj maskowania zamiast obrazu tła w SVG. Jak w odpowiedzi web-tiki , do której użycie Patternizera nadal będzie dodawało automatyczne generowanie SVG i niewidoczny element HTML na górze, który umożliwia zaznaczanie tekstu i kopiowanie.
  • Lub użyj automatycznego wyrównania obrazu wzoru. Można to zrobić za pomocą kodu JavaScript podobnego do tego w odpowiedzi Gijsa .
taniusz
źródło
1

po prostu umieść ten 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;

    }
Rashed
źródło
1

Zrzut ekranu demonstracyjnego

Musiałem stworzyć tekst, który wyglądałby dokładnie tak, jak w oryginalnym poście, ale nie mogłem go po prostu udawać, ustawiając tła, ponieważ za elementem jest jakaś animacja. Wygląda na to, że nikt jeszcze tego nie zasugerował, więc oto co zrobiłem: (Starałem się, aby było jak najłatwiejsze do odczytania.)

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

Po prostu wrzuć to do swojego okna. Załaduj, ustaw tło ciała na swój obraz i patrz, jak dzieje się magia!

Pecacheu
źródło
0

Obawiam się, że teraz nie jest to możliwe z CSS.

Najlepszym rozwiązaniem jest po prostu użycie obrazu (prawdopodobnie PNG) i umieszczenie na nim dobrego tekstu alternatywnego / tytułu.

Alternatywnie możesz użyć SPAN lub DIV i mieć obraz jako tło do tego z tekstem, który chcesz do celów SEO, w środku, ale z wcięciem tekstu poza ekranem.

Billy Fosa
źródło
Tak, masz rację. Prawdopodobnie mógłbym używać obrazów bez utraty punktów SEO, ale nadal nie możesz wybierać tekstu, wyszukiwać na stronie, linkowanie będzie bardziej skomplikowane, a aktualizacja tekstu będzie dużo więcej pracy ...: /
Love Dager
0

mix-blend-mode jest też możliwość uzyskania takiego efektu.

Właściwość mix-blend-modeCSS określa, w jaki sposób zawartość elementu powinna mieszać się z zawartością elementu nadrzędnego elementu i tłem elementu.

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>

G-Cyrillus
źródło