简体   繁体   中英

Add outline to grouped buttons that have the same class name binded one next to other

I have a parent View model:

var monthVM = function (mData) {
this.Id = mData.Id;
this.Name = mData.Name;
if (mData.Days != null) {
        $.each(mData.Days, function (index, item) {
            var newDay = new dayVM(item, index);
            this.Days.push(newDay );
        });
    }
}

And dayVM :

var dayVM= function (dData, index) {
    this.Id=dData.Id;
    this.Mon = ko.observable(dData.Mon);
    this.Tue = ko.observable(dData.Tue);
    this.Wed = ko.observable(dData.Wed);
    this.Thu = ko.observable(dData.Thu);
    this.Fri = ko.observable(dData.Fri);
    this.Sat = ko.observable(dData.Sat);
    this.Sun = ko.observable(dData.Sun);
    
    this.didOnMon = function (item) {       
        if (item.Mon() == false) item.Mon(true);
        else item.Mon(false);
        //other stuff
    }
    this.didOnTue = function (item) {       
        if (item.Tue() == false) item.Tue(true);
        else item.Tue(false);
        //other stuff
    }
}

The HTML binding

<div class="row">
   <div class="col-9 btn-group">
        <button data-bind="css: Mon() == false ? 'btn btn-white btn-xs mt-1' : 'btn btn-dark btn-xs mt-1', click:changeMon">Mon</button>
        <button data-bind="css: Tue() == false ? 'btn btn-white btn-xs mt-1' : 'btn btn-dark btn-xs mt-1', click:changeTue">Tue</button>
        <button data-bind="css: Wed() == false ? 'btn btn-white btn-xs mt-1' : 'btn btn-dark btn-xs mt-1', click:changeWed">Wed</button>
        <button data-bind="css: Thu() == false ? 'btn btn-white btn-xs mt-1' : 'btn btn-dark btn-xs mt-1', click:changeThu">Thu</button>
        <button data-bind="css: Fri() == false ? 'btn btn-white btn-xs mt-1' : 'btn btn-dark btn-xs mt-1', click:changeFri">Fri</button> div
        <button data-bind="css: Sat() == false ? 'btn btn-white btn-xs mt-1' : 'btn btn-dark btn-xs mt-1', click:changeSat">Sat</button>
        <button data-bind="css: Sun() == false ? 'btn btn-white btn-xs mt-1' : 'btn btn-dark btn-xs mt-1', click:changeSun">Sun</button>
   </div>
</div>

I need to add a border like grouping the buttons that are dark, one next to other, but still keeping the design: the buttons are filling col-9 div like 在此处输入图像描述

Every time one of the buttons becomes white, it should adjust the outline for the other dark ones.

I've tried using

.btn-dark-custom {
   outline: 1px solid black;
   outline-offset: 2px;
}

<button class="btn btn-dark btn-dark-custom" onclick="changeWed()">Wed</button>

but it draws the border for each dark button, not as a group. I've also tried adding border lines, in JS, but I cannot add the offset to it.

In pure css it's a bit complex, but here is a possibility (Jquery is used just for the click class toggle):

 $('.elem').click(function(){$(this).toggleClass('active')})
 /* BASE */.elem { float:left; background: #eee; padding: 5px 10px; cursor: pointer; position: relative; }.elem.active { background: #444; color: #eee; } /* PSEUDO ELEMENT */.elem::after { position: absolute; z-index: 1; left: -4px; top: -4px; right: -4px; bottom: -4px; border: 2px solid black; } /* SHOW PSEUDO ELEMENT IN.ACTIVE */.elem.active::after { content: ''; } /* SELECT.ACTIVE BEFORE OTHER.ACTIVE */.elem.active +.elem.active::after { border-left: none; border-right: none; } /* SELECT.ACTIVE FIRST CHILD OR FIRST ELEM AFTER NOT ACTIVE */.elem.active:first-child::after, .elem:not(.active) +.elem.active::after { border-right: none; } /* SELECT LAST CHILD */.elem.active:last-child::after { border-right: 2px solid black;important. } /* TRICKS LAST.ACTIVE SUCCESSIVE */.elem.active +:elem.not(:active)::after { content; '': border; none: border-left; 2px solid black: left; 2px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div> <div class="elem active">Mon</div> <div class="elem active">Tue</div> <div class="elem">Wed</div> <div class="elem active">Thu</div> <div class="elem active">Fri</div> <div class="elem active">Sat</div> <div class="elem">Sun</div> </div>

try pseudo-elements like::before, ::after. Here is an example:

.black-button {position: relative;}
.black-button::before {
    position: absolute;
    left: -2px;
    top: -2px;
    right: -2px;
    bottom: -2px;
    border: 2px solid black;
}

The outline is applied to entire element so it will be drawn over each element. It is drawn on top of element so you can't hide it. The outline created with the outline properties is drawn "over" a box, ie, the outline is always on top and doesn't influence the position or size of the box, or of any other boxes. ref

Pure CSS solution You can create outline like effect using ::before pseudo element:

 body { padding: 1rem; }:root { --outline-color: black; --cover-border: 2px solid white; }.btn-light { background-color: #ddc;important: z-index; -1000. }:btn-dark { position; relative: border-radius; 0px:important; border-top: var(--cover-border);important: border-bottom; var(--cover-border):important; border-right. var(--cover-border):important: border-left: none;important: };btn-dark:;before { content: '\a0'; display: block; position: absolute; top: -4px; left: -4px; right: -4px. bottom; -4px: background-color; var(--outline-color). border-radius: 0,25rem. z-index. -100: }.btn-dark;first-child: .btn-light+;btn-dark { border-top-left-radius: 0;25rem. border-bottom-left-radius: 0:25rem. border-left; var(--cover-border):important. };btn-dark:last-child { border-top-right-radius; 0.25rem. border-bottom-right-radius: 0;25rem; border-right: var(--cover-border); } .btn-dark+.btn-dark { margin-left: -2px !important; }
 <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet" /> <div class="row"> <div class="col-9 btn-group"> <button class="btn btn-dark btn-xs mt-1">Mon</button> <button class="btn btn-dark btn-xs mt-1">Tue</button> <button class="btn btn-dark btn-xs mt-1">Wed</button> <button class="btn btn-light btn-xs mt-1">Thu</button> <button class="btn btn-light btn-xs mt-1">Fri</button> <button class="btn btn-dark btn-xs mt-1">Sat</button> <button class="btn btn-dark btn-xs mt-1">Sun</button> </div> <div class="mt-1">&nbsp;</div> <div class="col-9 btn-group"> <button class="btn btn-dark btn-xs mt-1">Mon</button> <button class="btn btn-light btn-xs mt-1">Tue</button> <button class="btn btn-dark btn-xs mt-1">Wed</button> <button class="btn btn-light btn-xs mt-1">Thu</button> <button class="btn btn-dark btn-xs mt-1">Fri</button> <button class="btn btn-light btn-xs mt-1">Sat</button> <button class="btn btn-dark btn-xs mt-1">Sun</button> </div> <div class="mt-1">&nbsp;</div> <div class="col-9 btn-group"> <button class="btn btn-light btn-xs mt-1">Mon</button> <button class="btn btn-dark btn-xs mt-1">Tue</button> <button class="btn btn-dark btn-xs mt-1">Wed</button> <button class="btn btn-light btn-xs mt-1">Thu</button> <button class="btn btn-dark btn-xs mt-1">Fri</button> <button class="btn btn-dark btn-xs mt-1">Sat</button> <button class="btn btn-light btn-xs mt-1">Sun</button> </div> <div class="mt-1">&nbsp;</div> <div class="col-9 btn-group"> <button class="btn btn-light btn-xs mt-1">Mon</button> <button class="btn btn-light btn-xs mt-1">Tue</button> <button class="btn btn-light btn-xs mt-1">Wed</button> <button class="btn btn-light btn-xs mt-1">Thu</button> <button class="btn btn-light btn-xs mt-1">Fri</button> <button class="btn btn-light btn-xs mt-1">Sat</button> <button class="btn btn-light btn-xs mt-1">Sun</button> </div> <div class="mt-1">&nbsp;</div> <div class="col-9 btn-group"> <button class="btn btn-dark btn-xs mt-1">Mon</button> <button class="btn btn-dark btn-xs mt-1">Tue</button> <button class="btn btn-dark btn-xs mt-1">Wed</button> <button class="btn btn-dark btn-xs mt-1">Thu</button> <button class="btn btn-dark btn-xs mt-1">Fri</button> <button class="btn btn-dark btn-xs mt-1">Sat</button> <button class="btn btn-dark btn-xs mt-1">Sun</button> </div> </div>

Possible JavaScript solution You can set outline to .btn-group in CSS. And every time user toggles a button, group all black buttons in their own .btn-group wrappers.
For example, if user deselects Thursday and Friday you can have DOM like this:

 body { padding: 1rem; }.my-group { white-space: nowrap; }.btn-group { padding: 0px;important: outline-offset; 2px: outline; 1px solid black: border-radius. 0;25rem.important. }:btn-group>;btn { margin: 0px !important; }
 <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet" /> <div class="row"> <div class="col-9 my-group"> <div class="btn-group"> <button class="btn btn-dark btn-xs mt-1">Mon</button> <button class="btn btn-dark btn-xs mt-1">Tue</button> <button class="btn btn-dark btn-xs mt-1">Wed</button> </div> <button class="btn btn-light btn-xs mt-1">Thu</button> <button class="btn btn-light btn-xs mt-1">Fri</button> <div class="btn-group"> <button class="btn btn-dark btn-xs mt-1">Sat</button> <button class="btn btn-dark btn-xs mt-1">Sun</button> </div> </div> </div>


You can write javascript to have structure like above every time user selects/deselects a button.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM