Cách đọc giá trị của kiểu trong hàm CSS

Nov 07 2020

Tôi đang tạo một số div trong Javascript bằng cách chèn một cái gì đó như thế này

'<div style="background-color:' + bgColor + '</div>'

Bây giờ tôi muốn đặt colorvăn bản tự động dựa trên độ sáng của nền thành đen hoặc trắng.

Tôi thấy 2 tùy chọn - tất cả đều được điều khiển từ Javascript hoặc chỉ trong CSS. Tuy nhiên, tôi thích tùy chọn CSS hơn, không biết cách đọc màu nền cho một hàm CSS, ví dụ:

@function set-color($color) { @if (lightness($color) > 40) {
    @return #000;
  }
  @else {
    @return #FFF;
  }
}

Làm cách nào để tôi có thể lấy màu nền để làm một việc như thế này

div { color: set-color(???); }

Làm thế nào về mix-blend-mode?

Trả lời

3 AHaworth Nov 14 2020 at 15:57

Có một số ý tưởng được đưa ra trong câu hỏi về cách chọn giữa màu đen và trắng cho màu văn bản tùy thuộc vào màu nền.

Hầu hết đã được trả lời theo cách này hay cách khác trong các bình luận. Lấy từng ý tưởng một:

Chúng ta có thể sử dụng CSS mix-blend-mode - không. Không có một cài đặt nào cho việc này đảm bảo văn bản có thể đọc được trên tất cả các nền có thể.

Chúng ta có thể sử dụng CSS (phương pháp ưa thích) không - rất tiếc là không vì div yêu cầu màu văn bản phụ thuộc vào màu nền được tạo bởi JS tại thời điểm chạy.

Chúng ta có thể sử dụng JS không - vâng và vì div đang được tạo bởi JS và có bộ màu nền của nó thì nó cũng có thể có bộ màu của nó.

Chuỗi JS như được đưa ra trong câu hỏi với việc bổ sung cài đặt cho màu:

'<div style = "background-color:' + bgColor + '; color:' + textBlackOrWhite (bgColor) + ';"'

Đây là một đoạn mã xác định chức năng. Đoạn mã cũng cho phép bạn chọn màu nền và sau đó đặt màu (đại khái) phụ thuộc vào 'độ sáng' của nền. Xem các câu hỏi SO được tham khảo tại đây để thảo luận thêm vì nhận thức màu sắc của con người là một chủ đề khó.

//from https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
function textBlackOrWhite(hex) {
  // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
  var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, function(m, r, g, b) { return r + r + g + g + b + b; }); let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);//also checks we have a well-formed hex number
  
//from https://stackoverflow.com/questions/596216 the answer by @FranciPenov which gives an approximation: (R+R+G+G+G+B)/6 
  let itsbright = function () { return ((2*parseInt(result[1], 16) + 3*parseInt(result[2], 16) + parseInt(result[3], 16))/6)>127; }
  return result ? (itsbright()) ? '#000000' : '#ffffff' : '#000000';//falls back onto black if bgColor was not a well-formed 3 or 6 digit hex color
}
<div id="div" style="font-family: monospace; box-sizing: border-box; margin: 0; padding: 40px 0; width: 100px; height: 100px; border-style: solid; border-radius: 50%; background-color: black; color: white;text-align:center;">#ffffff</div>
Click to choose background color: <input id="input" placeholder='#00000' type='color' value='#000000'/>
<button onclick="let d = document.getElementById('div'); let i = document.getElementById('input'); d.innerHTML = i.value; d.style.backgroundColor = i.value; d.style.color = textBlackOrWhite(i.value);">Submit</button>

1 Rounin Nov 14 2020 at 17:43

Tôi muốn đặt màu của văn bản tự động dựa trên độ sáng của nền thành đen hoặc trắng.

Tôi nhận ra đây là một cách tiếp cận khác với những gì bạn đang yêu cầu, nhưng một cách tiếp cận chỉ dành cho CSS để có văn bản có thể đọc được trên toàn cầu, bất kể background-colorwhitevăn bản có blackđường viền (hoặc ngược lại).

Bạn có thể sử dụng 4 bóng chữ cho đường viền:

text-shadow: 1px 1px rgb(0, 0, 0), -1px 1px rgb(0, 0, 0), -1px -1px rgb(0, 0, 0), 1px -1px rgb(0, 0, 0);

Ví dụ làm việc

const divs = [...document.getElementsByTagName('div')];

for (div of divs) {

  let redValue = Math.floor(Math.random() * 255);
  let greenValue = Math.floor(Math.random() * 255);
  let blueValue = Math.floor(Math.random() * 255);
  
  div.style.backgroundColor = `rgb(${redValue}, ${greenValue}, ${blueValue})`;
}
div {
  float: left;
  width: 180px;
  height: 40px;
  margin: 0 6px 6px 0;
  line-height: 40px;
  color: rgb(255, 255, 255);
  font-size: 32px;
  text-align: center;
  text-shadow: 1px 1px rgb(0, 0, 0), -1px 1px rgb(0, 0, 0), -1px -1px rgb(0, 0, 0), 1px -1px rgb(0, 0, 0);
  background-color: yellow;
}
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>
<div>Sample Text</div>