adamos42 adamos42 - 5 months ago 62
CSS Question

CSS Variable trough Polymer (dynamically loaded) elements

I have multiple custom elements in my projects and I have a problem with css variables. In my parent element I have multiple item element with status classes. I want to manipulate the background and border color using that status classes, but I want to define the values in my parent element but somehow it not want to work.

Here my parent element:

<link rel="import" href="app-task.html" />
<dom-module id="app-task-grid">
<template>
<style>
:host {
display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%;
overflow:hidden; background: #eee;

--column-1-width: 80px;
--column-3-width: 120px;
--column-4-width: 180px;
--column-5-width: 220px;
--column-6-width: 100px;

--task-background-color: #eee;
--task-border-color: #ccc;
}

:host table.header {
position: absolute; top: 0; left: 0; width: 100%; height: 40px; background: #DDD;
}

:host table.header th {
letter-spacing: 2px; font-weight: normal; text-transform: uppercase;
font-size: 80%; border-left: 1px solid #aaa;

margin: 0; padding: 0 10px;
}

:host th.column1 {
width: var(--column-1-width);
}

:host th.column2 {
text-align: left;
}

:host th.column3 {
width: var(--column-3-width);
}

:host th.column4 {
width: var(--column-4-width);
}

:host th.column5 {
width: var(--column-5-width);
}

:host th.column6 {
width: var(--column-6-width);
text-align: left;
}

:host th.hide, :host td.hide {
display: none;
}

:host th.show, :host td.show {
display: table-cell;
}

:host table.header .scrollbar {
width: 20px; border-left: none;
padding: 0;
}

:host .items {

position: absolute; left: 0; top: 40px; right: 0; bottom: 0;
overflow:hidden; overflow-y: scroll;

margin: 0; padding: 0;
}

:host .items::-webkit-scrollbar {
width:22px; border-left: 6px solid #ddd;
background-color:#ddd;
}

:host .items::-webkit-scrollbar-thumb {
background-color:#aaa;
border-left: 6px solid #ddd;
min-height: 80px;
}

.waiting {
--task-background-color: #e9d32c;
--task-border-color: #b0a030;
}

.assigned {
--task-background-color: #1b7eee;
--task-border-color: #1357a4;
}

.started {
--task-background-color: #EF6207;
--task-border-color: #c05d1d;
}

.working {
--task-background-color: #e99c2c;
--task-border-color: #c48222;
}

.aborted {
--task-background-color: #E34126;
--task-border-color: #b72d15;
}
</style>

<table class="header">
<tr>
<th class="column1"></th>
<th class="column2">Column#2</th>
<th class="column3">Column#3</th>
<th class="column4">Column#4</th>
<th class="column5">Column#5</th>
<th class="column6">Column#6</th>
<th class="scrollbar"></th>
</tr>
</table>

<div class="items">
<app-task id="task0" class="waiting"></app-task>
</div>

</template>
<script>
Polymer({
is:"app-task-grid",
loadItems: function()
{
let statuses = ['waiting','assigned','started','working','aborted'];
for(var i = 1; i<=30; i++)
{
let itemStatus = statuses[Math.floor(Math.random()*statuses.length)];

let itemElement = document.createElement('APP-TASK');
itemElement.id = 'task'+i;
itemElement.classList.add(itemStatus);

console.debug( itemElement );

this.querySelector('.items').appendChild( itemElement );
}
}
});
</script>
</dom-module>


My children element:

<dom-module id="app-task">
<template>
<style>
:host {
display: block; margin: 8px 0; padding: 0;
}

:host table {
width: 100%; height: 80px;

background-color: var(--task-background-color, #fff);

border-bottom: 5px solid var(--task-background-color, #fff);
border-top: 5px solid var(--task-background-color, #fff);

box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.07),
0 1px 5px 0 rgba(0, 0, 0, 0.06),
0 3px 1px -2px rgba(0, 0, 0, 0.1);
}

:host table td {
border-left: 1px solid var(--task-border-color, #ccc);
margin: 0; padding: 0 10px;
}

:host td.column1 {
width: var(--column-1-width);
}

:host td.column2 {

}

:host td.column3 {
width: var(--column-3-width);
}

:host td.column4 {
width: var(--column-4-width);
}

:host td.column5 {
width: var(--column-5-width);
}

:host td.column6 {
width: var(--column-6-width);
}
</style>

<table>
<tr>
<td class="column1">C#1</td>
<td class="column2">C#2</td>
<td class="column3">C#3</td>
<td class="column4">C#4</td>
<td class="column5">C#5</td>
<td class="column6">C#6</td>
</tr>
</table>

</template>
<script>
Polymer({
is:"app-task"
});
</script>
</dom-module>


I tried already:


  • :host .waiting { ... }

  • :host app-task.waiting { ... }

  • app-task.waiting { ... }

  • :root .waiting { ... }

  • :root app-task.waiting { ... }

  • :root { .waiting { ... } }

  • :root { app-task.waiting { ... } }

  • parent element for the app-task for the classes

  • style is="custom-style" inside the app-grid template

  • style is="custom-style" outside the template but inside the app-grid element html file



but none of them seems working.

If I define the css variables in the :host then it's working, only not working with classes somehow. Where did made a mistake?




UPDATE#1:

Something weird hapening with the style-scope, if I add the "style-scope app-task-grid" to the parent element for the tasks:

<div class="items">
<div class="style-scope app-task-grid waiting">
<app-task id="task1"></app-task>
</div>
</div>


then if I add a normal css rule like a color its applied in the app-task, but the css variables are not.




UPDATE#2:

As it was mention that this template is working, and I tested it and it is, !But id did not mention that the items are created on the fly and appended to the items. I added almost everything from my code on Plunker: http://plnkr.co/edit/b5XW1w3sEOy4UHc0rdWH?p=preview

Sorry about my mislead, I did not know that the problem source was the dynamic load.

Note: I updated the question with more example.




UPDATE#3:

Thanks to @a1626s and @GünterZöchbauer we found the answer:

My initial code was good and worked from the beginning, I defined the questions badly becasue I did not see what was the problem. So if somebody dynamically load elements inside an element must use Polymer.dom api.

Polymer.dom(this.querySelector('.items')).appendCild('itemElement');

Answer

I don't see any problem in your initial code. I copied your code and pasted it in plunker

<style>
    :host {
        display: block;
    }

    .waiting {
        --task-background-color: #e9d32c;
        --task-border-color: #b0a030;
    }

    .assigned {
        --task-background-color: #1b7eee;
        --task-border-color: #1357a4;
    }

    .started {
        --task-background-color: #EF6207;
        --task-border-color: #c05d1d;
    }

    .working {
        --task-background-color: #e99c2c;
        --task-border-color: #c48222;
    }

    .aborted {
        --task-background-color: #E34126;
        --task-border-color: #b72d15;
    }
    </style>

    <div class="items">
        <app-task id="task1" class="waiting"></app-task>
        <app-task id="task2" class="waiting"></app-task>
        <app-task id="task3" class="working"></app-task>
        <app-task id="task4" class="working"></app-task>
        <app-task id="task5" class="assigned"></app-task>
        <app-task id="task6" class="aborted"></app-task>
    </div>

and it seemed to be working fine for me. Isn't this the expected behavior?

Comments