[SalesForce] Issue changing inline css during Lightning afterRender

I have a simple Lightning component

<aura:component >
    <!-- 100x100 box -->
    <div style="width:100px;height:100px;background-color:blue">
        <!-- 50x50 box -->
        <div id="MOVEME" style="width:50px;height:50px;background-color:red;"/>
    </div>
</aura:component>

which looks like this:

enter image description here

with an afterRender function

({
    afterRender : function(cmp, helper)
    {
        this.superAfterRender();
        document.getElementById('MOVEME').style.marginLeft = '20px';
    }
})

The goal is to have the small red box rendered 20 px to the left, so I set the css margin-left in the afterRender function. But the margin doesn't change.

I am wondering what I am doing wrong. I cannot use a class because the 20px is a dynamically computed value.

For those interested, I was able to get this to work by manipulating an aura:attribute:

<aura:component >

    <aura:attribute name="margin" default="0px" type="String" />

    <!-- 100x100 box -->
    <div style="width:100px;height:100px;background-color:blue">
        <!-- 50x50 box -->
        <div id="MOVEME" style="{!'width:50px;height:50px;background-color:red;margin-left:'+v.margin}"/>
    </div>
</aura:component>

and

({
    afterRender : function(cmp, helper)
    {
        this.superAfterRender();
        cmp.set("v.margin",'20px');
    }
})

which renders as I want:

enter image description here

Why does changing .style.marginLeft not work? Is there a preferred way to do things like this?

Best Answer

Under Lightning Locker, setting .style.attributeName is currently broken. See my other question:

Can't set element.style.properties in JS inside Lightning Locker

However what does currently work is to use the method .style.setProperty, so for example:

document.getElementById('MOVEME').style.setProperty('marginLeft', '20px');

Also note that hard-coding an ID could get you into trouble if you are reusing the component. You could set a class or data attribute since these don't have to be unique, and restrict your DOM search to the scope of your component. For example:

<div data-moveme="true"></div>

And inside your renderer:

cmp.getElement().querySelector("[data-moveme]").style.setProperty('marginLeft', '20px');
Related Topic