Hierarchy between CSS styles

Asked

Viewed 364 times

4

I’m studying some more efficient ways to style an app 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 the 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 the tema-1 (that is below the tema-2) continues to receive the styles of tema-2. I understand the styles of tema-2 have priority over those of the tema-1 due to the order they are inserted into css, but my question is, is there any way to get to the expected behavior using CSS? And using JS?

  • The tema-1 is supposed to be inside thetema-2 in HTML? It doesn’t seem right by its hierarchy...

  • This shouldn’t be within a function if/else in PHP or Javascript? Because from what I understand what you want to do here is: whether the option of tema-1 is selected - run HTML code <div class='tema-1'></div> or if the option tema-2 is selected - <div class='tema-2'></div>

  • The intention is that each theme overwrites the previous one respecting the order in html. Numbered names are just examples.

  • Take a look at in my reply @Oeslei . If she helped you solve your problem, please consider marking it as correct. =)

  • @Chun I asked the question just a simple example. The change is not just for the background. I would like to be able to apply the styles to the elements according to the nearest theme defined. Take as an example the RelativeLayout and the LinearLayout android with a structure of type LinearLayout > RelativeLayout > LinearLayout.

  • This example I posted in the answer is just for you to get a sense of how to apply the styles later in your CSS. Did you also check my jsFiddle example? There’s also an example in jsFiddle with more styles as an example of how this would work on a real website.

Show 1 more comment

5 answers

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, 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 selector .tema-2 .tema-1 .btn has predominance over the .tema-2 .btn, even being before. As well as the .tema-1 .tema-2 .btn about the .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 look bad to manage, so you could use a Pre-processor, like 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>

1

What you have to set first are patterns.

What will be the default button, for example ?

Size
Padding
Rounded Edge

What will change in the button ?

Coloured
Border Color
Letter Color

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;
}

0

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

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

For example:

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

will stay:

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

Like the script that arrow the class searches for the nearest theme (something like .closest('[data-theme]').data('theme')), the hierarchy of themes in html is maintained.

It is not yet the solution I was looking for (which may not even exist) as it still requires each element to have a specific class per theme, but it is the closest to the desired.

0

So that your configuration is not overwritten, put !important

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

.tema-2 {
    background-color: red;
}
  • The problems generated by !important are the ones I want to avoid most, and if I wanted the theme-1 to have priority it was enough to state it last in the CSS.

0

As I mentioned in my above-mentioned comment in your question, I don’t think your HTML hierarchy should be implemented in that way. Because from what I understand, what you’re trying to do here is create a code that changes the color of background, that is to say change 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 is why I said in the comment above that your hierarchy should be this way and not 1 within the other.

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

Here’s also an online example of how it will work on a real site: http://jsfiddle.net/6jm3t2au/

$('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>

<select name="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>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.