Javascript: найти на странице черный текст на черном фоне

1,00
р.
Как с помощью Javascript найти на странице все элементы, в которых текст написан черным цветом по черному фону? При этом черный фон/цвет может быть прописан не у самого элемента, а у далекого родителя, но после всех наследований в результате получается черный по черному.
Поставили задачу: сделать на сайте версию для слабовидящих. Один из пунктов - инверсия цвета, то есть выводим белый текст на черном фоне. Я прописал черный background у body, поправил css для прочих контейнеров, все хорошо, за исключением одного но. В админке у некоторых страниц в редакторе WYSIWYG явно прописан черный цвет для текста (в атрибуте style). В результате этот текст не виден на странице.
Я хочу найти решение, которое позволит решить проблему, не изменяя код страниц.
Например, чтобы javascript автоматически находил такой текст и менял его цвет на белый. Вопрос в том, как найти такие элементы.
Пока я вижу только вариант рекурсивного прохода по всем элементам DOM с запоминанием background родителя и проверкой цвета самого элемента.
Но может, есть способ проще, какое-нибудь решение в пару строк на jquery?
Иными словами, нужно добиться, чтобы в примере во втором div > p текст был виден:


.orig { background-color: #fff } .invert { background-color: #000 }

Оригинал

Текст

Инверсия

Текст




Ответ
Пришла в голову мысль, что стили, заданные в редакторе, совсем не обязательно будут задавать тексту черный цвет — это может быть и темно-серый и какой-нибудь коричневый. Текст такого цвета на инвертированном фоне слабовидящим людям будет по-прежнему тяжело прочесть, потому надо определять контрастность текста и фона.
Код частично скопипастил с определителя контрастности Лии Веру.
Что происходит в этом коде: функция 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 }

Оригинал

Текст


Инверсия

Обычный текст без инлайновых стилей


Черный Текст


Коричневый Текст


Синий Текст


Желтый Текст


Оранжевый Текст