diff --git a/lib/mixins/property-effects.js b/lib/mixins/property-effects.js
index b36c620f87..ac85472154 100644
--- a/lib/mixins/property-effects.js
+++ b/lib/mixins/property-effects.js
@@ -2543,6 +2543,11 @@ export const PropertyEffects = dedupingMixin(superClass => {
// Initialize attribute bindings with any literal parts
let literal = literalFromParts(parts);
if (literal && kind == 'attribute') {
+ // Ensure a ShadyCSS template scoped style is not removed
+ // when a class$ binding's initial literal value is set.
+ if (name == 'class' && node.hasAttribute('class')) {
+ literal += ' ' + node.getAttribute(name);
+ }
node.setAttribute(name, literal);
}
// Clear attribute before removing, since IE won't allow removing
diff --git a/test/unit/styling-scoped.html b/test/unit/styling-scoped.html
index bd3f4e21e7..227de37ce0 100644
--- a/test/unit/styling-scoped.html
+++ b/test/unit/styling-scoped.html
@@ -153,6 +153,18 @@
+
+
+ Trivial
+
+
+
+
@@ -993,6 +1005,17 @@
assertComputed(e, '5px', 'padding-top');
});
+ test('initial literal values in class are preserved when a class$ binding is present', function() {
+ var e = document.createElement('x-class-literal');
+ document.body.appendChild(e);
+ var el = e.$.scope;
+ assert.equal(el.classList.length, 4);
+ assert.isTrue(el.classList.contains('a'));
+ assert.isTrue(el.classList.contains('c'));
+ assert.isTrue(el.classList.contains('d'));
+ assert.isTrue(el.classList.contains('e'));
+ });
+
});
suite('double including style sheets', function() {