Javascript: найти на странице черный текст на черном фоне
1,00
р.
р.
Как с помощью Javascript найти на странице все элементы, в которых текст написан черным цветом по черному фону? При этом черный фон/цвет может быть прописан не у самого элемента, а у далекого родителя, но после всех наследований в результате получается черный по черному. Поставили задачу: сделать на сайте версию для слабовидящих. Один из пунктов - инверсия цвета, то есть выводим белый текст на черном фоне. Я прописал черный background у body, поправил css для прочих контейнеров, все хорошо, за исключением одного но. В админке у некоторых страниц в редакторе WYSIWYG явно прописан черный цвет для текста (в атрибуте style). В результате этот текст не виден на странице. Я хочу найти решение, которое позволит решить проблему, не изменяя код страниц. Например, чтобы javascript автоматически находил такой текст и менял его цвет на белый. Вопрос в том, как найти такие элементы. Пока я вижу только вариант рекурсивного прохода по всем элементам DOM с запоминанием background родителя и проверкой цвета самого элемента. Но может, есть способ проще, какое-нибудь решение в пару строк на jquery? Иными словами, нужно добиться, чтобы в примере во втором div > p текст был виден:
Ответ Пришла в голову мысль, что стили, заданные в редакторе, совсем не обязательно будут задавать тексту черный цвет — это может быть и темно-серый и какой-нибудь коричневый. Текст такого цвета на инвертированном фоне слабовидящим людям будет по-прежнему тяжело прочесть, потому надо определять контрастность текста и фона. Код частично скопипастил с определителя контрастности Лии Веру. Что происходит в этом коде: функция getLuminance() возвращает relative luminance функция getContrastRatio() возвращает contrast ratio из введенных туда данных о цвете фона и текста. Проходим по каждому параграфу внутри блока .invert, определяем contrast ratio и если он меньше 7 (таково требование WCAG) — делаем текст белым, а если больше 7, то оставляем как есть. UPD: переписал код для определения цвета фона не у родителя, а у самого элемента, для этого надо прописать параграфу в CSS background-color: inherit и переменной bg присваивать значение собственного цвета фона: bg = $(item).css('background-color'). UPD: итоговый вариант, позволяющий делать что угодно с элементами, имеющими недостаточную контрастность и без использования background-color: inherit. Источники: Lea Verou, contrast ratio. Формула подсчёта relative luminance: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef. Формула подсчета contrast ratio: https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef.
$(function() { var color, bg, textLuminance, parentLuminance, cr $('.invert p').each(function(index, item) { color = $(item).css('color'), bg = $(item).css('background-color') textLuminance = getLuminance(color) parentLuminance = getLuminance(bg) cr = getContrastRatio(textLuminance, parentLuminance) if(cr <= 7) $(item).css('color', '#fff') }) <br> function getContrastRatio(l1, l2) { l1 += .05, l2 += .05 var ratio = l1 / l2 if (l2 > l1) { ratio = 1 / ratio } return ratio = Math.round(ratio, 1) } function getLuminance(color) { var rgb = color.slice(4, -1).split(',').map(Number) for (var i = 0 i < 3 i++) { var rgbI = rgb[i] rgbI /= 255 rgbI = rgbI < .03928 ? rgbI / 12.92 : Math.pow((rgbI + .055) / 1.055, 2.4) rgb[i] = rgbI } return .2126 * rgb[0] + .7152 * rgb[1] + 0.0722 * rgb[2] } }) .orig { background-color: #fff } .invert { background-color: #000 } .invert p { padding: 5px background-color: inherit }