Văn bản trong suốt cắt ra khỏi nền


90

Có cách nào để làm cho một văn bản trong suốt cắt ra khỏi hiệu ứng nền như trong hình sau, bằng CSS không?
Sẽ rất buồn nếu mất tất cả SEO quý giá vì hình ảnh thay thế văn bản.

Văn bản trong suốt cắt ra khỏi nền

Lần đầu tiên tôi nghĩ đến bóng tối nhưng tôi không thể hình dung ra được điều gì ...

Hình ảnh là nền của trang web, một <img>thẻ định vị tuyệt đối


"mất tất cả SEO quý giá vì hình ảnh thay thế văn bản." Ngoài ra còn có các kỹ thuật thay thế hình ảnh hiện có, vẫn rất thân thiện. BTW: thực sự là nền phía sau các chữ cái cũng cần phải ở lại trong suốt, đó là vấn đề ở đây ...
feeela

yeap, đây sẽ là một thực tế rất lớn, nếu có thể với css ...
Jessica Lingmn

Tôi không thấy lý do tại sao lại <h1><img alt="Some Text" /></h1>kém thân thiện với SEO hơn <h1>Some Text</h1>. Theo truyền thống, vấn đề với hình ảnh là chúng đã được đặt trên trang mà không có đánh dấu hỗ trợ.
cimmanon

@cimmanon Vâng, bạn nói đúng. Tôi có thể sử dụng hình ảnh mà không làm mất điểm SEO, nhưng bạn vẫn không thể chọn văn bản, tìm kiếm trên trang, liên kết sẽ phức tạp hơn và sẽ tốn nhiều công sức hơn để cập nhật văn bản ...: /
Love Dager

2
Chỉ cần để bạn biết, Google đang hoàn toàn mát với các kỹ thuật thay thế hình ảnh CSS: mezzoblue.com/archives/2008/05/05/image_replac
cimmanon

Câu trả lời:


46

Nó có thể với css3 nhưng nó không được hỗ trợ trong tất cả các trình duyệt

Với background-clip: text; bạn có thể sử dụng nền cho văn bản, nhưng bạn sẽ phải căn chỉnh nó với nền của trang

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/


Căn chỉnh tự động

Với một chút javascript, bạn có thể căn chỉnh nền tự động:

$(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>
Các bác sĩ cho biết:

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


Một người bạn QUÁ nhanh: D
Gijs

Ôi tuyệt! Tôi sẽ kiểm tra căn chỉnh tự động nhanh nhất khi về nhà! Cảm ơn bạn! : D
Love Dager

bạn maby cần phải thay đổi mã một chút, phụ thuộc vào tình hình, bây giờ nó có thể xung đột với các yếu tố khác và điều này đã được viết rất nhanh, nếu bạn có bất cứ thắc mắc tôi sẽ nghe họ
Gijs

3
Không nên bỏ qua câu trả lời, đó là một giải pháp thực sự tốt, nhưng background-clip:textlà một lựa chọn không chuẩn, chỉ dành cho Webkit. CSS3 không cho phép textgiá trị cho thuộc tính này ( xem ).
tanius

1
Kỹ thuật này cho phép bạn xem nền của phần tử mà văn bản thường ở đó. Tôi đang tìm cách để xem những gì bên dưới phần tử có văn bản thông qua vị trí mà văn bản thường ở đó.
Vince

49

Mặc dù điều này có thể thực hiện được với CSS, nhưng cách tiếp cận tốt hơn sẽ là sử dụng SVG nội tuyến với SVG mask . Cách tiếp cận này có một số ưu điểm so với CSS:

  • Hỗ trợ trình duyệt tốt hơn nhiều : IE10 +, chrome, Firefox, safari ...
  • Điều này không ảnh hưởng đến SEO vì trình thu thập thông tin có thể thu thập dữ liệu nội dung SVG ( google lập chỉ mục nội dung SVG từ năm 2010 )

CodePen Demo: Mặt nạ văn bản SVG

văn bản cắt nền trong suốt

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>

Nếu bạn muốn làm cho văn bản có thể chọn được và có thể tìm kiếm được, bạn cần đưa nó vào bên ngoài <defs>thẻ. Ví dụ sau đây cho thấy một cách để giữ văn bản trong suốt với <use>thẻ:

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
Đây dường như là giải pháp duy nhất hoạt động trên nhiều trình duyệt hiện nay: IE11, FF, Chrome, Safari. Và không cần hình ảnh làm nền như nhiều giải pháp khác được cung cấp cho vấn đề trên web.
Timo Kähkönen

1
Lấy cảm hứng từ câu trả lời này, tôi đã tạo một hoạt ảnh khung hình chính, trong đó văn bản SVG trong suốt trên hình chữ nhật tròn màu trắng sẽ xoay. Nền có văn bản và hình ảnh. Truy cập và xem: jsbin.com/nipuqu/3 (Giải vô địch thế giới đang đến :))
Timo Kähkönen

2
Giải pháp tốt, nhưng vì "chọn văn bản và tìm kiếm trên trang" dường như nằm trong yêu cầu của OP, bạn có thể muốn bao gồm phần <text>bên ngoài của <defs>phần này. (btw Tôi không chắc trình thu thập dữ liệu SE xử lý như thế nào với nội dung SVG trong độ phân giải). Đây là một cách để giữ những gì OP muốn, với một lỗi FF khủng khiếp khai thác: jsfiddle.net/tfneqxxb
Kaiido

Điều gì sẽ xảy ra nếu văn bản là động? Nó không tự động điều chỉnh chiều rộng.
Imran Bughio

1
@ImranBughio không nó không. Văn bản SVG không hoạt động giống như văn bản HTML thuần túy. Bạn cần xác định vị trí của nó. Để biết thêm trong để biết nhìn thấy ở đây
web-tiki

16

Một cách hoạt động trên hầu hết các trình duyệt hiện đại (ngoại trừ edge), mặc dù chỉ có nền đen, là sử dụng

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

trong phần tử văn bản của bạn và sau đó đặt bất kỳ nền nào bạn muốn đằng sau đó. Về cơ bản, nhân đôi ánh xạ mã màu 0-255 thành 0-1 và sau đó nhân mã màu đó với bất kỳ thứ gì đằng sau nó, vì vậy màu đen vẫn là màu đen và màu trắng nhân với 1 và thực sự trở nên trong suốt. http://codepen.io/nic_klaassen/full/adKqWX/


3
Đối với nền trắng với việc sử dụng màu đen color-dodge, lightenhoặc screentrênmix-blend-mode
Imran Bughio

3

có thể, nhưng cho đến nay chỉ với trình duyệt Webkit dựa (Chrome, Safari, RockMelt, bất cứ điều gì dựa trên các dự án Chromium.)

Mẹo là để một phần tử bên trong màu trắng có cùng nền với phần thân, sau đó sử dụng -webkit- background-clip: text;phần bên trong, về cơ bản có nghĩa là "không mở rộng nền ra ngoài văn bản" và sử dụng văn bản trong suốt.

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/


Mẹo hay! Nhưng bây giờ tất cả mọi thứ để class đúng cách sẽ là một chó cái .. -.-
Tình yêu Dager

Vâng, đó là một vấn đề khác với nó. Nó vẫn đang trong quá trình phát triển và tôi thực sự hy vọng chúng ta sẽ sớm thấy những thứ như thế này! :)
Kyle

Ngoài ra, bạn luôn có thể xếp lớp trên văn bản trong suốt trên hình ảnh để nó vẫn có thể chọn được. Nhưng tôi chắc chắn rằng đó là thực hành xấu cho SEO .. Tin nhắn / từ khóa ẩn và những thứ như vậy.
Kyle

Tôi chắc chắn rằng nó trông rất đẹp trong trình duyệt Webkit, nhưng đối với những người khác, nó là một hộp màu trắng bán trong suốt nằm trên một số cỏ.
cimmanon

1
Ah, thôi nào các bạn ... Vâng, tôi dự định sử dụng nó trong sản xuất. Nhưng tất nhiên không phải là không có dự phòng! @cimmanon
Love Dager

2

Tôi đoán bạn có thể đạt được điều gì đó như vậy bằng cách sử dụngbackground-clip , nhưng tôi chưa thử nghiệm điều đó.

Xem ví dụ này:
http://www.css3.info/wp-content/uploads/2008/03/webkit-backgroundcliptext_color.html
(Chỉ dành cho Webkit, tôi chưa biết cách thay đổi nền đen thành nền trắng)


Vâng, điều đó có thể hiệu quả! Cảm ơn, bây giờ tất cả mọi thứ một cách chính xác class .. Chết tiệt .. -.-
Tình yêu Dager

2

Tôi vừa khám phá ra một cách mới để thực hiện việc này trong khi đang lộn xộn, tôi không hoàn toàn chắc chắn về cách nó hoạt động (nếu ai đó muốn giải thích, vui lòng làm).

Nó dường như hoạt động rất tốt và không yêu cầu nền kép hoặc JavaScript.

Đây là mã: 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>


1

Bạn có thể sử dụng phông chữ đảo ngược / phủ định / đảo ngược và áp dụng nó với font-face="…"quy tắc CSS. Bạn có thể phải chơi với khoảng cách giữa các chữ cái để tránh những khoảng trắng nhỏ giữa các chữ cái.

Nếu bạn không yêu cầu một phông chữ cụ thể, thật đơn giản. Tải xuống một phông chữ dễ thích, chẳng hạn từ bộ sưu tập phông chữ đảo ngược này .

Nếu bạn yêu cầu một phông chữ cụ thể (giả sử, "Open Sans"), thì thật khó. Bạn phải chuyển đổi phông chữ hiện có của mình thành một phiên bản đảo ngược. Điều này có thể thực hiện theo cách thủ công với Font Creator, FontForge, v.v., nhưng tất nhiên chúng tôi muốn có một giải pháp tự động. Tôi chưa thể tìm thấy hướng dẫn cho điều đó, nhưng một số gợi ý:


1

Bạn có thể sử dụng plugin Patternizer jQuery của myadzel để đạt được hiệu ứng này trên các trình duyệt. Tại thời điểm này, không có cách nào trên nhiều trình duyệt để thực hiện việc này chỉ với CSS.

Bạn sử dụng Patternizer bằng cách thêm class="background-clip"vào các phần tử HTML nơi bạn muốn văn bản được vẽ dưới dạng mẫu hình ảnh và chỉ định hình ảnh trong một data-pattern="…"thuộc tính bổ sung . Xem nguồn của bản demo . Patternizer sẽ tạo một hình ảnh SVG với văn bản đầy mẫu và đặt nó vào phần tử HTML được hiển thị trong suốt.

Nếu, như trong hình ảnh ví dụ của câu hỏi, mẫu điền văn bản phải là một phần của hình nền mở rộng ra ngoài phần tử "có hoa văn", tôi thấy hai tùy chọn (chưa được kiểm tra, yêu thích của tôi trước):

  • Sử dụng mặt nạ thay vì hình nền trong SVG. Như trong câu trả lời của web-tiki , việc sử dụng Patternizer sẽ vẫn thêm tự động tạo SVG và một phần tử HTML ẩn trên đầu cho phép lựa chọn và sao chép văn bản.
  • Hoặc sử dụng căn chỉnh tự động của hình ảnh mẫu. Có thể được thực hiện với mã JavaScript tương tự như trong câu trả lời của Gijs .

1

chỉ cần đặt 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

Ảnh chụp màn hình Demo

Tôi cần tạo văn bản giống hệt như trong bài viết gốc, nhưng tôi không thể giả mạo nó bằng cách xếp các hình nền, vì có một số hoạt ảnh đằng sau phần tử. Dường như chưa ai đề xuất điều này, vì vậy đây là những gì tôi đã làm: (Cố gắng làm cho nó dễ đọc nhất có thể.)

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

Chỉ cần ném nó vào window.onload của bạn, đặt nền của cơ thể thành hình ảnh của bạn và xem điều kỳ diệu xảy ra!


0

Tôi e rằng không thể với CSS ngay bây giờ.

Đặt cược tốt nhất của bạn là chỉ cần sử dụng một hình ảnh (có thể là PNG) và đặt văn bản alt / tiêu đề tốt lên đó.

Ngoài ra, bạn có thể sử dụng SPAN hoặc DIV và có hình ảnh làm nền cho văn bản của bạn mà bạn muốn cho mục đích SEO bên trong nó nhưng hãy thụt lề văn bản ngoài màn hình.


Uh, đúng vậy. Tôi có thể sử dụng hình ảnh mà không làm mất điểm SEO, nhưng bạn vẫn không thể chọn văn bản, tìm kiếm trên trang, liên kết sẽ phức tạp hơn và sẽ tốn nhiều công sức hơn để cập nhật văn bản ...: /
Love Dager

0

mix-blend-mode cũng là một khả năng cho loại hiệu ứng đó.

Các mix-blend-modebộ thuộc tính CSS như thế nào nội dung của một nguyên tố nên pha trộn với các nội dung của công ty mẹ của phần tử và nền của phần tử.

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>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.