JS/HTML/CSS: dividing one CSS class into several classes

Issue

This Content is from Stack Overflow. Question asked by Ben123

I am extending this HTML5 image editor repo (repo: https://github.com/viliusle/miniPaint, live version: https://github.com/viliusle/miniPaint).

I want to separate the tools on the left into different sections with a gap between them (see attached picture circled in red). I want each different set of tools in each section to have unique CSS properties (e.g. when I hover over or click on one of the first three tools, the background color (green in picture), should be different).

Desired effect:

Effect so far:

As you can see I’m quite far away from the desired effect and my solution (as code below shows) is very inelegant/hacky. I can’t seem to get past this.

This is the javascript function which renders the tools (I have labelled what I have done so far with ‘My Extension’):

render_tools() {
        var target_id = "tools_container";
        var _this = this;
        var saved_tool = this.Helper.getCookie('active_tool');
        if(saved_tool == 'media' || saved_tool == 'shape' || saved_tool == 'inpaint' || saved_tool == 'imagine' || saved_tool == 'variation') {
            //bringing this back by default gives bad UX
            saved_tool = null
        }
        if (saved_tool != null) {
            this.active_tool = saved_tool;
        }

        //left menu
        for (var i in config.TOOLS) {
            var item = config.TOOLS[i]; //config.TOOLS is a list of tools defined elsewhere
//My extension starts

            if(i == 3) {
                var emptyDom = document.createElement('span');
                emptyDom.className = 'item empty_box';
                document.getElementById(target_id).appendChild(emptyDom);
            }
//My extension ends

            if(item.title)
                var title = item.title;
            else
                var title = this.Helper.ucfirst(item.name).replace(/_/, ' ');

            var itemDom = document.createElement('span');
            itemDom.id = item.name;
            itemDom.title = title;
            if (item.name == this.active_tool) {
                itemDom.className = 'item trn active ' + item.name;
            }
            else {
                itemDom.className = 'item trn ' + item.name;
            }
            if(item.visible === false){
                itemDom.style.display = 'none';
            }

            //event
            itemDom.addEventListener('click', function (event) {
                _this.activate_tool(this.id);
            });

            //register
            document.getElementById(target_id).appendChild(itemDom);
        }

        this.show_action_attributes();
        new app.Actions.Activate_tool_action(this.active_tool, true).do();
        this.Base_gui.check_canvas_offset();
    }

And the relevant bits of the css file (with my extension labelled):

/* ========== left sidebar ================================================== */

.sidebar_left{
    -ms-grid-row: 2;
    -ms-grid-column: 1;
    grid-area: sidebar_left;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    background-color: var(--section-background-color);
    padding: 0 5px 5px 0;
    margin-right: 5px;
    overflow: hidden;
    align-self: start;
    width: 40px;
    overflow-y: auto;
    max-height: 100%;
}
//My extension

.sidebar_left .empty_box:after{
    position: absolute;
    content: '';
    left:0;
    top:0;
    bottom:0;
    right:0;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: 20px 20px;
    cursor: default
}
//My extension ends

.sidebar_left .item{
    position: relative;
    display:block;
    background-color: var(--area-background-color);
    height: 25px;
    width: 30px;
    margin: 5px 0 0 5px;
    overflow: hidden;
    cursor: pointer;
}
.sidebar_left .item:after{
    position: absolute;
    content: '';
    left:0;
    top:0;
    bottom:0;
    right:0;
    filter: var(--menu-icons-filter);
    background-position: center center;
    background-repeat: no-repeat;
    background-size: 20px 20px;
}
.sidebar_left .item:hover{
    background-color: var(--background-color-hover);
}
.sidebar_left .item.active{
    background-color: var(--background-color-active);
    color: var(--text-color-active);
}
.sidebar_left .item.active:after{
    filter: var(--menu-icons-filter-active);
}


.sidebar_left .select:after{ background-image: url('images/icons/select.svg'); }
.sidebar_left .selection:after{ background-image: url('images/icons/selection.svg'); }
.sidebar_left .brush:after{ background-image: url('images/icons/brush.svg'); }
.sidebar_left .pencil:after{ background-image: url('images/icons/pencil.svg'); }
.sidebar_left .pick_color:after{ background-image: url('images/icons/pick_color.svg'); }
.sidebar_left .erase:after{ background-image: url('images/icons/erase.svg'); }
.sidebar_left .magic_erase:after{ background-image: url('images/icons/magic_erase.svg'); }
.sidebar_left .fill:after{ background-image: url('images/icons/fill.svg'); }
.sidebar_left .media:after{ background-image: url('images/icons/media.svg'); }
.sidebar_left .shape:after{ background-image: url('images/icons/shape.svg'); }
.sidebar_left .variation:after{ background-image: url('images/icons/variation.svg'); }
.sidebar_left .imagine:after{ background-image: url('images/icons/imagine.svg'); }
.sidebar_left .inpaint:after{ background-image: url('images/icons/inpaint.svg'); }
.sidebar_left .text:after{ background-image: url('images/icons/text.svg'); background-size: 16px auto; }
.sidebar_left .gradient:after{ background-image: url('images/icons/gradient.png'); background-size: 18px 12px; filter: none; }
.sidebar_left .clone:after{ background-image: url('images/icons/clone.svg'); }
.sidebar_left .crop:after{ background-image: url('images/icons/crop.svg'); }
.sidebar_left .blur:after{ background-image: url('images/icons/blur.svg'); }
.sidebar_left .sharpen:after{ background-image: url('images/icons/sharpen.svg'); }
.sidebar_left .desaturate:after{ background-image: url('images/icons/desaturate.svg'); }
.sidebar_left .bulge_pinch:after{ background-image: url('images/icons/bulge_pinch.svg'); }
.sidebar_left .animation:after{ background-image: url('images/icons/animation.svg'); }

@media screen and (max-width:550px){
    #sidebar_left{
        left: -110px;
    }
}

I suspect I need to create several CSS classes from the singular class that exists now, but I have no idea how to dd this (rookie!). Any amendments or different approaches would be very welcome.



Solution

Check the Answers

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?