So after some digging, I found a discussion of the problem on the polymer github page: https://github.com/Polymer/polymer/issues/270.
Basically, this is an unsupported feature in the ShadowDOMPolyfill for the time being, and the authors are unsure whether or not they will implement this functionality for performance reasons. The programmer assigned to the issue suggests the following workaround:
<style>
div {
border: 1px solid black;
width: {{width}}px;
}
/* polyfill specific rule */
/* @polyfill-rule
@host[id={{id}}] div {
border: 1px solid black;
width: {{width}}px;
}
*/
</style>
...
<script type="text/javascript">
Polymer('x-foo', {
...
registerCallback: function(declaration) {
// add shimmedStyles to this instance
if (window.ShadowDOMPolyfill) {
var content = declaration.templateContent();
content.insertBefore(content.shimmedStyle, content.firstChild);
}
}
});
</script>
For whatever reason, my own implementation of this method failed. In lieu of this, I wrote a workaround that, while being a little ugly, works quite well in unsupported browsers:
<script type="text/javascript">
(function() {
Polymer('impress-slide', {
entrance: 'bounceIn',
exit: 'fadeOutRightBig',
animation: "",
animateIn: function() {
this.animation = this.entrance;
// Fallback for polyfill
if (window.ShadowDOMPolyfill &&
((this.style.animationName != this.entrance) ||
(this.style.webkitAnimationName != this.entrance))) {
this.style.webkitAnimation =
this.style.animation = this.entrance + " 1s both";
}
},
animateOut: function() {
this.animation = this.entrance;
// Fallback for polyfill
if (window.ShadowDOMPolyfill &&
((this.style.animationName != this.exit) ||
(this.style.webkitAnimationName != this.exit))) {
this.style.webkitAnimation =
this.style.animation = this.exit;
}
},
ready: function() {
}
})
})();
</script>
Essentially, these modifications test the browser for the presence of the polyfill and for the incorrect assignment of the animation style properties. If these are found, the function will manually apply them to the slide using inline insertion (e.g. this.style.animation = this.entrance + " 1s both";
).
The downsides of this approach are that it exposes the inner workings of the element to the end user in the event of the polyfill, undermining the goal of encapsulation within the custom element. However, under normal circumstances within a supported browser, the element will transition as expected, with the encapsulation intact.