Как получить вычисленный стиль цвета фона, унаследованный от родительского элемента

У меня есть эта HTML-страница:

document.addEventListener("DOMContentLoaded", function (event) {
  var inner_div = document.getElementById("innerDiv");
  console.log(getComputedStyle(inner_div, null)["backgroundColor"]);
});
#outterDiv {
  background-color: papayawhip;
}
<div id="outterDiv">
  <div id="innerDiv">
    I am an inner div
  </div>
</div>

Я хочу узнать вычисленный цвет фона внутреннего div, не заглядывая в вычисленный стиль родительского элемента. Это возможно?


person user4617883    schedule 21.09.2017    source источник
comment
comment
Нет, вы не можете сделать это, не заглянув в вычисляемый стиль родительского элемента. как вы упомянули. Было бы здорово, если бы в DOM это было.   -  person Vamsidhar Muggulla    schedule 21.09.2017
comment
@VamsidharMuggulla Я не знаю, что вы имеете в виду, было бы здорово, если бы это было в DOM. Это не имеет ничего общего с DOM. Это просто естественный результат процесса рисования.   -  person    schedule 21.09.2017


Ответы (3)


Вы, видимо, хотели спросить

Как мне найти цвет фона для некоторого элемента, который используется в силу того, что этот цвет установлен в качестве цвета фона некоторого предка, который просвечивает, потому что все промежуточные элементы имеют прозрачный цвет фона?

Однако ваш вопрос сбивает с толку, потому что вы используете слово «унаследованный», которое имеет очень специфическое значение в CSS, которое здесь не имеет значения.

Свойство background-color не наследуется в смысле CSS. Каждый элемент имеет свой цвет фона, который по умолчанию равен transparent.

Причина, по которой ваш внутренний div выглядит так, как будто он имеет фон из папайи, заключается в том, что на самом деле он имеет прозрачный фон, который позволяет просвечивать фон из папайи из внешнего div. Во внутреннем div нет ничего, что знало бы или заботилось о папайявип, или что можно было бы запросить, чтобы вернуть папайавхип.

Единственный способ узнать, что внутренний div будет иметь фон папайи, — пройтись по дереву DOM и найти ближайшего родителя с непрозрачным цветом фона. Это объясняется в вопросе, предложенном в качестве цели дублирования.

Кстати, в чем здесь основная проблема? Почему вы пытаетесь это сделать? Наверняка есть лучшие способы.

person Community    schedule 21.09.2017

Решение

Вот некоторые ванильные js, которые получат эффективный цвет фона для данного элемента:

function getInheritedBackgroundColor(el) {
  // get default style for current browser
  var defaultStyle = getDefaultBackground() // typically "rgba(0, 0, 0, 0)"
  
  // get computed color for el
  var backgroundColor = window.getComputedStyle(el).backgroundColor
  
  // if we got a real value, return it
  if (backgroundColor != defaultStyle) return backgroundColor

  // if we've reached the top parent el without getting an explicit color, return default
  if (!el.parentElement) return defaultStyle
  
  // otherwise, recurse and try again on parent element
  return getInheritedBackgroundColor(el.parentElement)
}

function getDefaultBackground() {
  // have to add to the document in order to use getComputedStyle
  var div = document.createElement("div")
  document.head.appendChild(div)
  var bg = window.getComputedStyle(div).backgroundColor
  document.head.removeChild(div)
  return bg
}

Затем вы можете назвать это так:

var myEl = document.getElementById("a")
var bgColor = getInheritedBackgroundColor(myEl)

Демо в jsFiddle

Объяснение

Решение работает путем проверки разрешенного значения для определенного элемента. Если фон прозрачен, он начнется снова с родительского элемента, пока не найдет определенный цвет или не достигнет вершины.

Есть два основных понятия, с которыми следует ознакомиться:

  1. Как устанавливается background-color?
  2. Как работают разрешенные значения?

Согласно MDN, background-color имеет начальный значение transparent и не унаследованное свойство. Это означает, что даже если к родительскому div применен цвет, любой нестилизованный дочерний div будет иметь background-color из transparent. Большинство браузеров преобразуют это в цветовое пространство rgb, поэтому возвращают значение rgba(0,0,0,0) с альфа-каналом/прозрачностью, установленными на 0%.

Это различие может показаться тривиальным, но важно понимать, что большинство разделов на странице, вероятно, прозрачны. Они не окрашивают никакие цвета, они просто не маскируют родительские элементы. Если бы фоновые значения были унаследованы, цвета с прозрачностью складывались и усиливались на дочерних элементах

Согласно MDN, разрешенные значения это то, что браузер возвращает из .getComputedStyle(), включая вычисленные значения и используемые значения. Использование разрешенного значения помогает обрабатывать специальные значения, такие как inherit, initial и т. д., и превращает любые относительные значения в абсолютные значения. Плюс также предоставляет согласованный API для получения информации о стилях из атрибутов по сравнению с теми, которые применяются через таблицы стилей.

Таким образом, window.getComputedStyle() не используется для определения цвета фона; это просто, чтобы получить фактическое значение для div. А затем мы пройдемся по дереву DOM, пока не найдем фактическое значение.

Дальнейшее чтение

person KyleMit    schedule 29.06.2020
comment
Этот ответ отлично сработал для меня. Я думаю, что это должно быть помечено как ответ на вопрос ОП. Я пытался сделать то же самое, что и ОП. - person Michael; 19.07.2021

добавьте background-color: inherit; к вашему #innerDiv

document.addEventListener("DOMContentLoaded", function (event) {
  var inner_div = document.getElementById("innerDiv");
  console.log(getComputedStyle(inner_div, null)["backgroundColor"]);
});
#outterDiv {
  background-color: papayawhip;
}
#innerDiv {
  background-color: inherit;
}
<div id="outterDiv">
  <div id="innerDiv">
    I am an inner div
  </div>
</div>

person Znaneswar    schedule 21.09.2017
comment
Это будет своего рода работой в конкретном случае, когда внутренний div окрашивается его родительским цветом, но не поможет, если он окрашивается фоновым цветом какого-то более удаленного предка, что, я думаю, является проблемой OP. пытаясь решить. - person ; 21.09.2017