skip to Main Content

See below basic component (and fiddle here: https://jsfiddle.net/j4oxths6/14/)

I’m using Handlebars and vanilla HTML, CSS & Javascript.

As part of my JSON object, a property that exists is "theme" which could be multiple options (always defined by JSON and not user driven).

How can I update the below code to handle various theme options? For example when the theme is "default" the main-nav should be lightpink but when "dark" it will be black?

Is there a clean and easy way to update CSS classes to based on I assume a variable?

const template = Handlebars.compile(document.getElementById('Template').innerHTML);

const data = {
  "direction": "ltr",
  "theme": "default",
  "skinnyBannerItems": [
    {
      "label": "Option 1",
      "url": ""
    },
    {
      "label": "Option 2",
      "url": ""
    },
    {
      "label": "Option 3",
      "url": ""
    },
    {
      "label": "Option 4",
      "url": ""
    }
  ],
  "navigationItems": [
    {
      "label": "Option 5",
      "url": ""
    },
    {
      "label": "Option 6",
      "url": ""
    },
    {
      "label": "Option 7",
      "url": ""
    },
    {
      "label": "Option 8",
      "url": ""
    },
    {
      "label": "Option 9",
      "url": ""
    }
  ]

};

const output = template(data);

console.log(output);
document.body.innerHTML = output;
body {
  margin: 0;
}

.skinny-banner {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  
  height: 40px;
  padding-right: 40px;
  background-color: green;
}

.skinny-nav-menu{
  display: flex;
  list-style: none;
  gap: 20px;
}

.skinny-nav-menu li a {
  color: white;
  text-decoration: none;
}

.main-nav {
  display: flex;
  align-items: center;
  
  min-height: 115px;
  background-color: lightpink;
}

.nav-menu{
  display: flex;
  list-style: none;
  gap: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js" type="text/javascript"></script>

<script id="Template" type="text/template">
<div class="nav-container">
    <div class="skinny-banner">
    <ul class="skinny-nav-menu">
      {{#each this.skinnyBannerItems}}
      <li><a href="{{url}}">{{label}}</a></li>
      {{/each}}
    </ul>
  </div>
  <div class="main-nav">
    <ul
        class="nav-menu"
     >
        {{#each this.navigationItems}}
        <li><a href="{{url}}">{{label}}</a></li>
        {{/each}}
      </ul>
  </div>
</div>
 
</script>

2

Answers


  1. On the parent add a variable something like theme-{{theme}}. That will dynamically add new classes like theme-dark, theme-default etc..

    <div class="nav-container theme-{{theme}}">
    

    Then in your CSS, you can reference those classes and the main-nav child.

    .theme-default .main-nav{
        background-color: lightpink;
    }
    
    .theme-dark .main-nav{
        background-color: black;
    }
    

    You can easily expand this as needed plus by attaching the theme to the parent, you can always change the children as needed not just the main-nav.

    Login or Signup to reply.
  2. You can use css variables for this. Add css variables in :root like

    :root {
      --bg: black;
    }
    
    ...
    
    .main-nav {
      display: flex;
      align-items: center;
      
      min-height: 115px;
      background-color: var(--bg);
    }
    ...
    

    check theme in data and update css variable, something like this

    if(data.theme == "default") {
    document.documentElement.style.setProperty('--bg', 'lightpink');
    } else {
    document.documentElement.style.setProperty('--bg', 'black');
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search