JSFiddle - React, Tailwind, and code Playground
HTML
<button id="toggleHighlight">Toggle Highlight</button>
<div id="a" class="aClass"><p>This paragraph is in div A.</p>
<div id="b" class="bClass"><blockquote><p>This paragraph is in div B, which is a descendant of A. We apply a highlight style to it however we'd really like that highlight style to not be propagated into certain children.</p>
<div id="x" class="xClass"><blockquote><p>Here is a random descendant of div B which we want the highlighting to still apply to.</p></blockquote></div>
<div id="c" class="cClass"><blockquote><p>This content is inside a div of type C. These kinds of children we'd like to ideally look as close to the way they looked before the highlight as possible.</p></blockquote></div>
</blockquote>
</div>
</div>
CSS
.aClass {
background-image: url('http://hostilefork.com/shared/stackoverflow/parchment.jpg');
background-repeat: repeat;
}
.aClass, .bClass, .cClass, .xClass {
border : 2px solid #000;
margin: 20px;
padding: 20px;
}
JavaScript
$('#toggleHighlight').click(function(){
$('#b').toggleHighlight('div:not(.xClass)');
});
jQuery.fn.toggleHighlight = function(ignore){
var highlightStyle = {
background:'url(http://hostilefork.com/shared/stackoverflow/cc-by-nc-nd.png) repeat',
color:'red'
};
if (!this.data('highlighted')){
var descendants = this.find(ignore || ''),
bgImage = 'none',
bgRepeat = 'repeat',
rootPosition = '0',
next = this;
while(next = next.parent()){
var bg = next.css('background-image');
if (bg && bg !== 'none'){
bgImage = bg;
bgRepeat = next[0].style.backgroundRepeat;
rootPosition = next.offset();
rootPosition.x += next[0].style.backgroundPositionX || 0;
rootPosition.y += next[0].style.backgroundPositionY || 0;
break;
}
};
if (bgImage == 'none'){
bgImage = undefined;
}
descendants.cacheStyles();
this.cacheStyles();
this.css(highlightStyle);
descendants.recoverStyles().each(function(){
if (bgImage && (
this.style.backgroundColor === 'rgba(0, 0, 0, 0)'
|| this.style.backgroundColor === 'transparent'
)){
var pos = $(this).offset();
this.style.backgroundImage = bgImage;
this.style.backgroundRepeat = bgRepeat;
var x = rootPosition.left - pos.left;
var y = rootPosition.top - pos.top;
this.style.backgroundPosition = x + 'px ' + y + 'px';
}
});
this.data('highlighted', true);
} else {
this.recoverStyles();
this.data('highlighted', false);
}
return this.each(function(){
});
};
jQuery.fn.cacheStyles =...