Прозрачный текст вырезан из фона

92

Есть ли способ вырезать прозрачный текст из фонового эффекта, такого как на следующем изображении, с помощью CSS?
Было бы грустно потерять все драгоценное SEO из-за того, что изображения заменяют текст.

Прозрачный текст вырезан из фона

Сначала я подумал о тенях, но ничего не могу понять ...

Изображение - это фон сайта, <img>тег с абсолютным позиционированием

Любовь Дагер
источник
«потерять все драгоценное SEO из-за того, что изображения заменяют текст». Существуют также существующие методы замены изображений, которые все еще ТАК дружелюбны. Кстати: на самом деле фон за буквами также должен оставаться прозрачным, в чем проблема…
Feela
да, это будет отличная практика, если возможно с css ...
Джессика Лингмн
Я не вижу причины, по которой <h1><img alt="Some Text" /></h1>он менее дружественен к SEO, чем <h1>Some Text</h1>. Традиционно проблема с изображениями заключалась в том, что они просто выгружались на страницу без поддерживающей разметки.
cimmanon
@cimmanon Да, ты прав. Я, вероятно, мог бы использовать изображения без потери SEO-очков, но вы все равно не можете выделить текст, искать на странице, связывание будет более сложным, и будет намного больше работы по обновлению текста ...: /
Love Dager
2
Просто чтобы вы знали, Google совершенно крут с методами замены изображений CSS: mezzoblue.com/archives/2008/05/05/image_replac
cimmanon

Ответы:

47

Это возможно с css3, но поддерживается не во всех браузерах.

С фоновым клипом: текст; вы можете использовать фон для текста, но вам придется выровнять его с фоном страницы

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/


Автоматическое выравнивание

С помощью небольшого javascript вы можете автоматически выровнять фон:

$(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/

Gijs
источник
А вы, люди, слишком быстрые: D
Gijs
О, круто! Я протестирую автоматическое выравнивание, как только вернусь домой! Спасибо! : D
Love Dager
вам, возможно, нужно немного изменить код, в зависимости от ситуации, теперь он может конфликтовать с другими элементами, и этот был написан очень быстро, если у вас есть какие-либо вопросы, я их
выслушаю
3
Чтобы не игнорировать ответ, это действительно хорошее решение, но background-clip:textэто нестандартный вариант только для Webkit. CSS3 не допускает textзначения этого атрибута ( см. ).
tanius
1
Этот метод позволяет увидеть фон элемента там, где обычно находится текст. Я ищу способ увидеть, что находится под элементом с текстом, через то место, где обычно находится текст.
Винс,
49

Хотя это возможно с помощью CSS, лучшим подходом было бы использование встроенного SVG с маскированием SVG . Этот подход имеет некоторые преимущества перед CSS:

Демонстрация CodePen: текстовая маска 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>

Если вы хотите сделать текст доступным для выделения и поиска, вам необходимо включить его вне <defs>тега. В следующем примере показан способ сделать это, сохранив прозрачный текст с <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>

веб-тики
источник
2
Кажется, это единственное решение, которое сегодня работает в кросс-браузере: IE11, FF, Chrome, Safari. И не требует изображения в качестве фона, как многие другие решения этой проблемы в Интернете.
Тимо Кяхконен
1
Вдохновленный этим ответом, я сделал анимацию по ключевым кадрам, в которой прозрачный SVG-текст на белом скругленном прямоугольнике вращается. На заднем плане есть текст и изображения. Иди и посмотри: jsbin.com/nipuqu/3 ( Скоро чемпионат мира :))
Тимо Кяхкёнен
2
Хорошее решение, но поскольку «выделите текст и выполните поиск на странице», похоже, в требованиях OP, вы можете захотеть включить <text>внешнюю часть <defs>части. (кстати, я не уверен, как поисковые роботы SE справляются с SVG-контентом в defs). Вот способ сохранить то, что хочет OP, с помощью ужасной ошибки FF: jsfiddle.net/tfneqxxb
Kaiido
Что делать, если текст динамический? Он не регулирует ширину автоматически.
Имран Бугио,
1
@ImranBughio, нет. Текст SVG не действует как обычный текст HTML. Вы должны его позиционировать. Для получения дополнительной информации см. Здесь
web-tiki
16

Один из способов, который работает в большинстве современных браузеров (кроме Edge), хотя и только с черным фоном, - это использовать

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

в свой текстовый элемент, а затем поместите за ним любой фон, который вы хотите. Умножение в основном преобразует цветовой код 0-255 в 0-1, а затем умножает его на то, что стоит за ним, поэтому черный остается черным, а белый умножается на 1 и фактически становится прозрачным. http://codepen.io/nic_klaassen/full/adKqWX/

Ник
источник
3
Для белого фона с черным использованием цвета color-dodge, lightenили screenнаmix-blend-mode
Имран Bughio
3

это является возможным, но до сих пор только с Webkit на основе браузеров (Chrome, Safari, Rockmelt, что - нибудь на основе проекта Chromium.)

Хитрость заключается в том, чтобы иметь элемент внутри белого, который имеет тот же фон, что и тело, а затем использовать его -webkit- background-clip: 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/

Кайл
источник
Классный трюк! Но теперь выровнять все как следует будет сука .. -.-
Love Dager
Да, это еще одна проблема. Он все еще в разработке, и я искренне надеюсь, что мы скоро увидим что-то подобное! :)
Кайл
Кроме того, вы всегда можете наложить слой поверх прозрачного текста на изображение, чтобы его можно было выбрать. Но я уверен, что это плохая практика для SEO .. Скрытые сообщения / ключевые слова и тому подобное.
Кайл
Я уверен, что в браузерах Webkit это выглядит очень красиво, но для всех остальных это полупрозрачный белый квадрат на траве.
cimmanon
1
Да ладно, ребята ... Да, я планирую использовать его в продакшене. Но, конечно, не обошлось и без запасного варианта! @cimmanon
Love Dager
2

Я думаю, вы могли бы добиться чего-то подобного, используяbackground-clip , но я еще не тестировал это.

См. Этот пример:
http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html
(только для Webkit, я пока не знаю, как изменить черный фон на белый)

Feela
источник
Да, это может сработать! Спасибо, теперь все правильно выровнял .. Блин .. -.-
Love Dager
2

Я только что открыл новый способ сделать это, пока бездельничал, я не совсем уверен, как это работает (если кто-то еще хочет объяснить, пожалуйста, сделайте это).

Кажется, он работает очень хорошо и не требует двойного фона или JavaScript.

Вот код: 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>

КрисБрауни55
источник
1

Вы можете использовать инвертированный / отрицательный / обратный шрифт и применить его с font-face="…"помощью правила CSS. Возможно, вам придется поиграть с интервалом между буквами, чтобы избежать небольших белых промежутков между буквами.

Если вам не нужен конкретный шрифт, это просто. Скачайте понравившийся, например, из этой коллекции инвертированных шрифтов .

Если вам нужен конкретный шрифт (скажем, «Open Sans»), это сложно. Вам необходимо преобразовать существующий шрифт в инвертированную версию. Это возможно вручную с помощью Font Creator, FontForge и т. Д., Но, конечно, нам нужно автоматическое решение. Инструкций по этому поводу пока найти не удалось, но есть подсказки:

Таниус
источник
1

Вы можете использовать Мядельского в Patternizer JQuery плагин для достижения этого эффекта во всех браузерах. В настоящее время нет кросс-браузерного способа сделать это с помощью только CSS.

Вы используете Patternizer, добавляя class="background-clip"к элементам HTML, где вы хотите, чтобы текст был нарисован как шаблон изображения, и указываете изображение в дополнительном data-pattern="…"атрибуте. Посмотреть исходный код демонстрации . Patternizer создаст изображение SVG с текстом, заполненным узором, и разместит его под прозрачно отображаемым элементом HTML.

Если, как в образце изображения вопроса, образец заливки текста должен быть частью фонового изображения, выходящего за пределы элемента с рисунком, я вижу два варианта (непроверенные, сначала мой любимый):

  • Используйте маску вместо фонового изображения в SVG. Как и в ответе веб-тики , к которому использование Patternizer по-прежнему добавит автоматическое создание SVG и невидимый элемент HTML сверху, который позволяет выбирать и копировать текст.
  • Или воспользуйтесь автоматическим выравниванием изображения выкройки. Может быть выполнено с помощью кода JavaScript, аналогичного тому, что был в ответе Gijs .
Таниус
источник
1

просто поставь этот 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;

    }
Сыпь
источник
1

Демо Скриншот

Мне нужно было создать текст, который выглядел бы точно так же, как в исходном посте, но я не мог просто подделать его, выровняв фон, потому что за элементом есть некоторая анимация. Похоже, что этого еще никто не предлагал, поэтому вот что я сделал: (Пытался сделать это как можно проще для чтения.)

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

Просто вставьте это в свой window.onload, установите фон тела на свое изображение и наблюдайте, как происходит волшебство!

Pecacheu
источник
0

Боюсь, сейчас это невозможно с CSS.

Лучше всего просто использовать изображение (возможно, PNG) и разместить на нем хороший текст alt / title.

В качестве альтернативы вы можете использовать SPAN или DIV и использовать изображение в качестве фона для вашего текста, который вы хотите для целей SEO, внутри него, но с отступом за пределами экрана.

Билли Моут
источник
Да, ты прав. Я, вероятно, мог бы использовать изображения без потери SEO-очков, но вы все равно не можете выделить текст, искать на странице, связывание будет более сложным, и будет намного больше работы по обновлению текста ...: /
Love Dager
0

mix-blend-mode также есть возможность для такого эффекта.

Свойство mix-blend-modeCSS устанавливает, как содержимое элемента должно сливаться с содержимым родительского элемента и фоном элемента.

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
источник