Hierarchy between CSS styles

4

I am studying some more efficient ways to stylize an application using themes. My idea would be to use something like this:

<div class='tema-1'>
    <button class='btn btn-primary'>botão principal</button>
</div>
.tema-1 .btn-primary {
    background-color: green;
}

The problem arises when I try to use hierarchy between themes:

<div class='tema-2'>
    <button class='btn btn-primary'>botão principal tema 2</button>

    <div class='tema-1'>
        <button class='btn btn-primary'>botão principal tema 1</button>
    </div>
</div>
.tema-1 {
    background-color: green;
}

.tema-2 {
    background-color: red;
}

In the example, the button belonging to tema-1 (which is below tema-2 ) continues to receive styles tema-2 . I understand that tema-2 styles have priority over tema-1 because of the order they are inserted into css, but my question is, is there any way to get to expected behavior using CSS? And using JS?

    
asked by anonymous 29.06.2015 / 22:20

5 answers

1

What you have to set first are defaults.

What will the button default, for example?

Size
Padding
Rounded Edge

What will change the button?

Color
Border Color
Color of the Letter

So,

// Padrão

.btn{
   width: 200px;
   height: 40px;
   border-radius: 5px;
   font-family: "Verdana";
   font-size: 14px;
   padding: 8px;
   box-sizing: border-box;
}

// Mudanças
.btn .red{
   background-color: red;
   color: white;
   border: 1px solid red;
}
    
29.06.2015 / 23:01
1

@Chun is right when he said that his HTML "hierarchy" should not be implemented like this. However solving the "problem", you can include "priorities" in your selectors, for example:

.tema-1 .btn, .tema-2 .tema-1 .btn{
    background-color:#975167;
    border-color:#774137;
}

.tema-2 .btn, .tema-1 .tema-2 .btn{
    background-color:#36c1ab;
    border-color:#26819b;
}

The .tema-2 .tema-1 .btn selector has a predominance over .tema-2 .btn , even though it was before. As well as .tema-1 .tema-2 .btn on .tema-2 .btn . If you have 10 themes you will have to do this for everyone in each rule:

.tema-1  .btn, 
.tema-2  .tema-1 .btn,
.tema-3  .tema-1 .btn,
.tema-4  .tema-1 .btn,
.tema-5  .tema-1 .btn,
.tema-6  .tema-1 .btn,
.tema-7  .tema-1 .btn,
.tema-8  .tema-1 .btn,
.tema-9  .tema-1 .btn,
.tema-10 .tema-1 .btn,{
    background-color:#975167;
    border-color:#774137;
}

.tema-1  .controle, 
.tema-2  .tema-1 .controle,
.tema-3  .tema-1 .controle,
.tema-4  .tema-1 .controle,
.tema-5  .tema-1 .controle,
.tema-6  .tema-1 .controle,
.tema-7  .tema-1 .controle,
.tema-8  .tema-1 .controle,
.tema-9  .tema-1 .controle,
.tema-10 .tema-1 .controle,{
    /* Regras */
}

.tema-1  .alerta, 
.tema-2  .tema-1 .alerta,
.tema-3  .tema-1 .alerta,
.tema-4  .tema-1 .alerta,
.tema-5  .tema-1 .alerta,
.tema-6  .tema-1 .alerta,
.tema-7  .tema-1 .alerta,
.tema-8  .tema-1 .alerta,
.tema-9  .tema-1 .alerta,
.tema-10 .tema-1 .alerta,{
    background-color:#975167;
    border-color:#774137;
}

This would be bad to manage, so you could use a preprocessor such as LESS or SASS . And do something like:

.tema-1, 
.tema-2  .tema-1,
.tema-3  .tema-1,
.tema-4  .tema-1,
.tema-5  .tema-1,
.tema-6  .tema-1,
.tema-7  .tema-1,
.tema-8  .tema-1,
.tema-9  .tema-1,
.tema-10 .tema-1{

    .btn { 
        /* Regras */ 
    }

    .controle { 
        /* Regras */ 
    }

    .alerta { 
        /* Regras */ 
    }
}

Functional example:

.box{
    background-color:rgba(0,0,0,0.08);
    padding:5px;
}
.box .box{margin: 10px 0 0 10px;}
.btn{
    border: 1px solid #CF8A5B;
    border-radius:2px;
    background-color: #DFAA5B;
    color:#333;
    padding:3px;
    margin:5px 0;
    cursor:pointer;
}

.tema-1 .btn, .tema-2 .tema-1 .btn{
    background-color:#975167;
    border-color:#774137;
}

.tema-2 .btn, .tema-1 .tema-2 .btn{
    background-color:#36c1ab;
    border-color:#26819b;
}
<div class="box">
    Padrão: <button class="btn">Botão</button>
    <div class="box tema-2">
        Tema 2:
        <button class="btn">Botão</button>
        <div class="box tema-1">
            Tema 1:
            <button class="btn">Botão</button>
            <div class="box tema-2">
                Tema 2:
                <button class="btn">Botão</button>
            </div>
        </div>
    </div>
</div>
    
02.07.2015 / 21:30
0

So that your configuration is not overwritten, put !important

.tema-1 {
    background-color: green !important;
}

.tema-2 {
    background-color: red;
}
    
29.06.2015 / 22:28
0

As I mentioned in my comment above in your question, I do not think the hierarchy of your HTML should be implemented in this way. For what I realized, what you are trying to do here, is to create is a code that changes the color of background , that is that changes the color of the theme as an option is selected by the user , for example:

<!-- Se a opção 2 estiver selecionada - Corre este código -->
<div class='tema-2'>
    <button class='btn btn-primary'>botão principal tema 2</button>
</div>

<!-- Mas se a opção 1 estiver selecionada - Então corre este código -->
<div class='tema-1'>
    <button class='btn btn-primary'>botão principal tema 1</button>
</div>

That's why I said in the above comment that your hierarchy should be this way and not 1 within the other.

If you are looking to create a theme change option depending on the theme the user chooses, you can do this as in the example below:

You also have an example online of how it will work on a real site: link

$('select[id$=-status][id^=id_item-]').change(function (){
    var color = $(this).find('option:selected').val();
    
    $(".tema").removeClass('t1 t2 t3').addClass('t' + $(this).find('option:selected').val());
}).change();
.tema    { background-color:white; }
.tema.t1 { background-color:green; }
.tema.t2 { background-color:cornflowerblue; }
.tema.t3 { background-color:orange; }

.tema {
    height: 100px;
    border: 1px solid #C2C2C2;
    margin-top: 15px;
    padding: 10px;
}

.tema .container { 
    background-color: #fff;
    text-align: center;
    height: 70%;
    margin: 10px auto;
 }
.t1 .container { background-color: #B6DC33; width:50%; height: 20%;}
.t2 .container { background-color:cornflowerblue; }
.t3 .container { background-color: #D23131; color: #fff; width:30%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script><selectname="item-0-status" id="id_item-0-status">
<option value="">-- Escolher tema --</option>
<option value="1">Tema 1 - Verde</option>
<option value="2">Tema 2 - Azul</option>
<option value="3">Tema 3 - Laranja</option>
</select>

<div class="tema">
    <button class='btn btn-primary'>botão principal</button>
    <div class="container">Texto Aleatório</div>
</div>
    
29.06.2015 / 23:40
0

I was studying the jquery mobile code to see how the themes were processed.

What happens with jquery mobile is that the theme is set via a data-theme attribute and at application startup all html is modified to use classes.

For example:

<div data-theme="b">
    <button></button>
</div>

will be:

<div data-theme="b">
    <button class="ui-btn-b">
</div>

As the script that directs the class to search for the closest theme (something like .closest('[data-theme]').data('theme') ), the hierarchy of themes in the html is maintained.

It is not yet the solution I was looking for (which may not even exist) because it still requires each element to have a theme-specific class, but it is the closest to what you want.

    
02.07.2015 / 22:56