2

I've made a fancy checkbox, which uses pseudo-elements to look nice, but unfortunately the overflow: hidden doesn't work well in its case. I don't know why.

Here's my code:

.wrapper {
  background: black;
}

.priority {
    display: none;

}
.priority, .priority:after, .priority:before, .priority *, .priority *:after, .priority *:before, .priority + .priority-btn {
    box-sizing: border-box;
}

.priority + .priority-btn {
    overflow: hidden;
    backface-visibility: hidden;
    transition: all 0.2s ease;
    background: #666;
    width: 100%;
    border-radius: 0.25rem;
    padding: .375rem .75rem;
    height: 2.375em;
}

.priority + .priority-btn::after, .priority + .priority-btn::before {
    display: inline-block;
    transition: all 0.2s ease;
    width: 100%;
    text-align: center;
    position: absolute;
    font-weight: bold;
    color: #fff;
}

.priority + .priority-btn::after {
    left: 100%;
    content: 'IMPORTANT';
}

.priority + .priority-btn::before {
    left: 0;
    content: 'UNIMPORTANT';
}

.priority + .priority-btn:active {
    background: #888;
}

.priority + .priority-btn:active::before {
    left: -10%;
}

.priority:checked + .priority-btn {
    background: #86d993;
}
.priority:checked + .priority-btn:before {
    left: -100%;
}
.priority:checked + .priority-btn:after {
    left: 0;
}
.priority:checked + .priority-btn:active:after {
    left: 10%;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="wrapper">
  <div class="container">
    <div class="row">
      <div class="col">
        <input type="checkbox" ngModel name="priority" id="priority" class="priority">
        <label class="priority-btn" for="priority"></label>
      </div>
    </div>
  </div>
</div>

As you can see the text comes out from the container label.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Drobesz
  • 384
  • 1
  • 7
  • 17
  • 1
    Not sure but would it be enough to add .col { overflow: hidden;} ? Is the problem with specific browser? – Esko Jun 04 '18 at 13:01
  • @Esko it can be enough because col has `position:relative` which make the pseudo element at least be relatively potionned to col ... all depend on the reference of the postion (relatively to what ?) – Temani Afif Jun 04 '18 at 13:15

2 Answers2

3

Give position: relative to the .priority-btn since its pseudo-elements have position: absolute:

.wrapper {
  background: black;
}

.priority {
    display: none;

}
.priority, .priority:after, .priority:before, .priority *, .priority *:after, .priority *:before, .priority + .priority-btn {
    box-sizing: border-box;
}

.priority + .priority-btn {
    overflow: hidden;
    backface-visibility: hidden;
    transition: all 0.2s ease;
    background: #666;
    width: 100%;
    border-radius: 0.25rem;
    padding: .375rem .75rem;
    height: 2.375em;
    position: relative;
}

.priority + .priority-btn::after, .priority + .priority-btn::before {
    display: inline-block;
    transition: all 0.2s ease;
    width: 100%;
    text-align: center;
    position: absolute;
    font-weight: bold;
    color: #fff;
    z-index: 11;
}

.priority + .priority-btn::after {
    left: 100%;
    content: 'IMPORTANT';
}

.priority + .priority-btn::before {
    left: 0;
    content: 'UNIMPORTANT';
}

.priority + .priority-btn:active {
    background: #888;
}

.priority + .priority-btn:active::before {
    left: -10%;
}

.priority:checked + .priority-btn {
    background: #86d993;
}
.priority:checked + .priority-btn:before {
    left: -100%;
}
.priority:checked + .priority-btn:after {
    left: 0;
}
.priority:checked + .priority-btn:active:after {
    left: 10%;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="wrapper">
  <div class="container">
    <div class="row">
      <div class="col">
        <input type="checkbox" ngModel name="priority" id="priority" class="priority">
        <label class="priority-btn" for="priority"></label>
      </div>
    </div>
  </div>
</div>
VXp
  • 11,598
  • 6
  • 31
  • 46
  • 1
    I deleted my answer, this is the real solution. If you give the parent element `overflow: hidden;', the pseudo-elements are still outside of the screen. Hiding the scrollbar doesn't fix it, it just "hides" it, which is not a clean fix. VXp's answer is :) – Jos van Weesel Jun 04 '18 at 13:16
  • 1
    Thanks a lot! That works the same way as I've imagined... :) – Drobesz Jun 04 '18 at 13:17
  • I would probably add explanation to say that overflow:hidden doesn't consider Dom structure but also the position and the reference .. because adding the overflow to col wokrs also for the same reason – Temani Afif Jun 04 '18 at 13:17
  • `It affects the clipping of all of the element's content except any descendant elements (and their respective content and descendants) whose containing block is the viewport or an ancestor of the element.` --> https://www.w3.org/TR/CSS2/visufx.html#overflow. The *except* part is what needed here ;) – Temani Afif Jun 04 '18 at 13:19
  • 1
    [**Here**](https://imgur.com/gallery/j6aSADM) is a visualization of the differences between VXp's clean fix and the fix with `{overflow: hidden;}`. – Jos van Weesel Jun 04 '18 at 13:31
1

Add overflow:hidden to your .col class

.col{
      overflow: hidden;

}
Jins Peter
  • 2,368
  • 1
  • 18
  • 37