Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 enter image description here

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.

like image 936
Dana Avatar asked Oct 14 '25 07:10

Dana


2 Answers

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>
like image 182
Liberateur Avatar answered Oct 19 '25 18:10

Liberateur


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, i.e., 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.

like image 25
the Hutt Avatar answered Oct 19 '25 19:10

the Hutt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!