为具有相同 class 名称并排绑定的分组按钮添加轮廓

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

我有一个父视图模型:

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

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

HTML绑定

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

我需要添加一个边框,比如将深色按钮分组,一个挨着另一个,但仍保持设计:按钮正在填充 col-9 div 就像

每次其中一个按钮变白时,它应该调整其他深色按钮的轮廓。

我试过使用

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

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

但它为每个深色按钮绘制边框,而不是作为一个组。 我也试过在 JS 中添加 border 行,但我无法为其添加偏移量。

尝试像 ::before、::after 这样的伪元素。这是一个例子:

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

在纯 css 中有点复杂,但这是一种可能性(Jquery 仅用于单击 class 切换):

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

outline 应用于整个元素,因此它将绘制在每个元素上。它绘制在元素之上,因此您无法隐藏它。使用 outline 属性创建的轮廓绘制在框的“上方”,即轮廓始终在顶部并且不影响框或任何其他框的位置或大小。ref

纯CSS解决方案您可以使用::before伪元素创建类似轮廓的效果:

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>

可能的JavaScript解决方案可以在CSS中将大纲设置为.btn-group。每次用户切换按钮时,将所有黑色按钮分组到它们自己的 .btn-group 包装器中。
例如,如果用户取消选择星期四和星期五,您可以 DOM 像这样:

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>


每次用户 selects/deselects 一个按钮时,您可以编写 javascript 以具有上述结构。