1

I am trying to create a design from a graphic artists and i have successfully created the button that acts like a checkbox, however i cant seem to figure out the CSS to mimic the design. Its grey but on hover/click(checked) it changes color. I'm using bootstrap and fontawesome to try and achieve this.

IMG of functionality im trying to replicate: enter image description here

https://jsfiddle.net/nojil/Lskdcu6r/31/

#canvasBranch-ck-button {
  margin: 4px;
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #D0D0D0;
  overflow: auto;
  float: left;
  width: 150px;
}

#canvasBranch-ck-button:hover {
  background: #fff;
  color: #ff4c00;
  border-color: #ff4c00;
  cursor: pointer;
}

#canvasBranch-ck-button label {
  float: left;
  width: 100%;
}

#canvasBranch-ck-button label span {
  text-align: center;
  padding: 3px 0px;
  display: block;
}

#canvasBranch-ck-button label span.iconSpan {
  background-color: #D0D0D0;
  color: #fff;
}

#canvasBranch-ck-button label input {
  position: absolute;
  top: -20px;
}

#canvasBranch-ck-button input:checked+span.textSpan {
  color: #ff4c00 !important;
}

#canvasBranch-ck-button input:checked+span.iconSpan {
  background-color: #ff4c00;
}
<div id="canvasBranch-ck-button">
  <label class="d-flex mb-0">
        <input type="checkbox" value="canvasBranch">
        <span class="flex-fill align-items-center iconSpan"><i class="fas fa-angle-left"></i></span>
        <span class="align-items-center flex-fill textSpan">Canvas Branch</span>
      </label>
</div>

7
  • Are you using anything like Bootstrap for styling or are you creating this on your own? Commented Jan 22, 2019 at 19:07
  • @bspeagle using bootstrap, i updated the jsfiddle Commented Jan 22, 2019 at 19:07
  • In CSS, + is the "adjacent sibling combinator", meaning it only applies if the given items are directly beside eachother. Your checkbox and textSpan are not adjacent siblings, therefore this will not work: input:checked + span.textSpan. You'll want to use the regular sibling combinator instead: input:checked ~ span.textSpan Commented Jan 22, 2019 at 19:10
  • @TylerRoper im getting close but check out the latest jsfiddle. I cant seem to get the iconspan to turn oj on hover and then the border color to turn oj on checked jsfiddle.net/nojil/Lskdcu6r/36 Commented Jan 22, 2019 at 19:15
  • @Charles Given the structure of your HTML, this is not possible without JavaScript. You cannot style a parent based on a child, therefore you won't be able to format the <div> based on the checkbox. They would have to be siblings instead. You may have to re-think your HTML. Commented Jan 22, 2019 at 19:17

3 Answers 3

2

Given that you've shown an attempt, I figured I could throw you a bone here and give you a bit of an idea of how this might be implemented.

The issue you've run into, that I've explained in my comments, is that you're trying to style a parent (the <div>) based on the status (checked/unchecked) of a child, which cannot be done in CSS.

Given the use of ::before, you could also implement icon-specific styling. You'll notice how I implemented them using the .money and .question class, and the only declaration necessary would be content: 'x'. You can do this with Font-Awesome too.

Consider something like this instead. Of course, you'll need to update the fonts and whatnot.

body {
  font-family: arial;
  background-color: #f6f6f6;
}

.hidden {
  display: none;
}

label {
  display: block;
  border: 1px solid transparent;
  display: flex;
  max-width: 170px;
  border-radius: 6px;
  overflow: hidden;
  background-color: #eee;
  align-items: center;
  cursor: pointer;
  margin: 5px;
}

label::before {
  width: 35px;
  padding: 10px 0;
  display: block;
  background-color: #ccc;
  color: white;
  font-size: 18px;
  content: '!';
  text-align: center;
}

label.money::before {
  content: '$';
}

label.question::before {
  content: '?';
}

label>.text {
  display: block;
  flex-grow: 1;
  text-align: center;
  height: 100%;
  padding-top: 2px;
  font-size: 13px;
  color: #333;
}

label:hover,
input:checked+label {
  border: 1px solid #ff4c00;
}

label:hover>.text,
input:checked+label>.text {
  color: #ff4c00;
}

input:checked+label {
  background-color: white;
}

input:checked+label::before {
  background-color: #ff4c00;
}
<input class="hidden" id="chk1" type="checkbox">
<label class="" for="chk1">
  <span class="text">GENERIC</span>
</label>

<input class="hidden" id="chk2" type="checkbox">
<label class="money" for="chk2">
  <span class="text">MONEY</span>
</label>

<input class="hidden" id="chk3" type="checkbox">
<label class="question" for="chk3">
  <span class="text">QUESTION</span>
</label>

Sign up to request clarification or add additional context in comments.

4 Comments

Why not use ::before instead of two additional span elements?
Because then re-using this button style would require a bunch of specific classes for content. I suppose if the $ portion was going to be re-used, that could be a pseudo.
Which you would do with a simple CSS class on the checkbox. Or the label. Or a parent wrapper, if you want that.
I understand the reason for the $ element, but you suggested "instead of two additional span elements". Using a pseudo for the second span (the text), would require you to have to create a unique class for every single button to declare a new content: 'Button Text', which seems silly and counter-intuitive. You'd end up with a style-sheet full of single-use-case button classes. I'll update the first to be a pseudo though.
1

As @TylerRopper mention on the comment You cannot style a parent based on a child but you can always fake it, here it is:

<div id="canvasBranch-ck-button">
      <label class="d-flex mb-0">

        <input type="checkbox" value="canvasBranch">
        <span class="flex-fill align-items-center iconSpan"><i class="fas fa-angle-left"></i></span>
        <span class="align-items-center flex-fill textSpan">Canvas Branch</span>
         <div class="fakeborder">
         </div>
      </label>

Css

#canvasBranch-ck-button {
    margin: 4px;
    background-color: #fff;
    border-radius: 4px;
    border: 1px solid #D0D0D0;
    overflow: auto;
    float: left;
    width: 150px;
}

#fakeborder{
  width:150px;
}

#canvasBranch-ck-button:hover {
    background: #fff;
    color: #ff4c00;
    border-color: #ff4c00;
    cursor: pointer;
}

#canvasBranch-ck-button label {
    float: left;
    width: 100%;
}

#canvasBranch-ck-button label span {
    text-align: center;
    padding: 3px 0px;
    display: block;
}

#canvasBranch-ck-button label span.iconSpan {
    background-color: #D0D0D0;
    color: #fff;
}

#canvasBranch-ck-button label input {
    position: absolute;
    top: -20px;
}

#canvasBranch-ck-button input:checked ~ span.textSpan {
    color: #ff4c00 !important;
}

#canvasBranch-ck-button input:checked ~ span.iconSpan {
    background-color: #ff4c00;
}

#canvasBranch-ck-button input:checked ~ .fakeborder {
    border: 2px solid #ff4c00;
    width:151px;
    height: 32px;
    margin:-1px;
    border-radius: 4px;
    position:absolute;
}

And here is the fiddle

Comments

0

You can use this as a starting point and customize to your likings.

cb1.addEventListener('click', function() {
  console.log(cb1.checked)
})
.cb-btn {
  display: none;
}

.cb-btn + label {
  border: 1px solid #999;
  border-radius: 5px;
  cursor: pointer;
  padding: 5px 0.5em 5px 2.5em;
  position: relative;
}

.cb-btn:not(:checked + label):hover {
  border-color: #a00;
  color: #a00;
  transition: all .2s ease-in-out;
}

.cb-btn + label::before {
  background-color: #999;
  border-radius: 5px 0 0 5px;
  bottom: 0;
  content: "$ ";
  display: block;
  left: 0;
  line-height: 1.9em;
  position: absolute;
  text-align: center;
  top: 0;
  transition: all .2s ease-in-out;
  width: 2em;
}

.cb-btn:not(:checked) + label:hover::before {
  background-color: #a00;
  color: #fff;
}

.cb-btn:checked + label {
  border: 1px solid green;
  border-radius: 5px;
  color: green;
  cursor: pointer;
  padding: 5px 0.5em 5px 2.5em;
  position: relative;
}

.cb-btn:checked + label::before {
  background-color: green;
  color: #fff;
}
<input type="checkbox" value="canvasBranch" id="cb1" class="cb-btn">
<label class="d-flex mb-0" for="cb1">Label Text</label>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.