Home > Mobile >  Is it possible to replicate behaviour of "flex-end" in :before & :after pseudo-elements
Is it possible to replicate behaviour of "flex-end" in :before & :after pseudo-elements

Time:11-20

I have the following code below which creates a checkbox using :before & :after and then utilises a hidden input to handle the logic of selecting an item. It all works as expected and I'm happy with the behaviour however I'm wondering is it possible to make the checkbox (created in the :before & :after) to sit at the very right hand side of the wrapper like so:

enter image description here

I would usually use flex-end but that of course then moves the entire label (with the checkbox) to the end of the wrapper.

.wrapper {
  position: relative;
  display: inline-flex;
  min-height: 1.5rem;
  border: 1px solid black;
  margin-right: 1rem;
  padding: 0.5rem;
  width: 200px;
}

.input {
  position: absolute;
  z-index: -1;
  visibility: hidden;
}

.label-wrapper {
  margin-left: 24px;
  margin-right: 0;
}

.label.reverse > .label-wrapper {
  margin-left: 0;
  margin-right: 24px;
}

.label {
  position: relative;
  margin-bottom: 0;
  display:flex;
  flex-direction: row;
}

.label.reverse{
  flex-direction: row-reverse;
}

 .label:before {
    position:absolute;
    display: block;
    width: 20px;
    height: 20px;
    content: "";
    background-color: #fff;
    border: 1px solid black;
    border-radius:4px;
  }

.label:after {
   position: absolute;
   display: block;
   height: 20px;
   content: "";
   background-repeat: no-repeat;
   background-position: center center;
   background-size: 80%;
}

input[type="checkbox"]:checked ~ .label::after {
    background-image: url("https://cdn-icons-png.flaticon.com/512/447/447147.png");
    width: 20px;
    height: 20px;
  }
<div class="wrapper">
  <input class="input" name="checkbox2" id="checkbox2" type="checkbox">
  <label class="label reverse" for="checkbox2">
    <div class="label-wrapper">
      Option 1
    </div>  
  </label>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

When a flex item is absolutely positioned it is removed from the flex formatting context. In other words, most flex properties won't work anymore. (See flexbox spec: §4.1. Absolutely-Positioned Flex Children)

Try removing position: absolute from the checkbox.

Make three simple adjustments to your CSS code:

.label.reverse {
  flex-direction: row-reverse;
  justify-content: space-between; /* new; pin items to opposite ends */
  flex: 1; /* new; give container full width of parent */
}

.label:before {
  /* position: absolute; */ /* keep item in flex formatting context */
  display: block;
  width: 20px;
  height: 20px;
  content: "";
  background-color: #fff;
  border: 1px solid black;
  border-radius: 4px;
}

Show code snippet

.wrapper {
  position: relative;
  display: inline-flex;
  min-height: 1.5rem;
  border: 1px solid black;
  margin-right: 1rem;
  padding: 0.5rem;
  width: 200px;
}

.input {
  position: absolute;
  z-index: -1;
  visibility: hidden;
}

.label-wrapper {
  margin-left: 24px;
  margin-right: 0;
}

.label.reverse>.label-wrapper {
  margin-left: 0;
  margin-right: 24px;
}

.label {
  position: relative;
  margin-bottom: 0;
  display: flex;
  flex-direction: row;
}

.label.reverse {
  flex-direction: row-reverse;
  justify-content: space-between; /* new; pin items to opposite ends */
  flex: 1; /* new; give containe full width of parent */
}

.label:before {
  /* position: absolute; */
  display: block;
  width: 20px;
  height: 20px;
  content: "";
  background-color: #fff;
  border: 1px solid black;
  border-radius: 4px;
}

.label:after {
  position: absolute;
  display: block;
  height: 20px;
  content: "";
  background-repeat: no-repeat;
  background-position: center center;
  background-size: 80%;
}

input[type="checkbox"]:checked~.label::after {
  background-image: url("https://cdn-icons-png.flaticon.com/512/447/447147.png");
  width: 20px;
  height: 20px;
}
<div class="wrapper">
  <input class="input" name="checkbox2" id="checkbox2" type="checkbox">
  <label class="label reverse" for="checkbox2">
    <div class="label-wrapper">
      Option 1
    </div>  
  </label>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Css:-

label {
    float: left;
    margin: 5px 0px;
}

input {
    float: right;
    margin: 5px 0px;
    width: 200px;
}

.clear {
    clear: both;
}

html

<label for="autologin">Option 1</label>
<input type="checkbox" class="checkbox" id="autologin" name="autologin" value="1">
<div class="clear"></div>

CodePudding user response:

.wrapper {
    position: relative;
    display: inline-flex;
    min-height: 1.5rem;
    border: 1px solid black;
    margin-right: 1rem;
    padding: 0.5rem;
    width: 200px;
  }
  
  .input {
    position: absolute;
    z-index: -1;
    visibility: hidden;
    
  }
  
  .label-wrapper {
    margin-left: 24px;
    margin-right: 0;
  }
  
  .label.reverse > .label-wrapper {
    margin-left: 0px;
    margin-right: 24px;
  }
  
  .label {
    position: relative;
    margin-bottom: 0;
    display:flex;
    flex-direction: row;
  }
  
  .label.reverse{
    flex-direction: row-reverse;
    
  }
  
   .label:before {
      display: block;
      width: 20px;
      height: 20px;
      content: "";
      background-color: #fff;
      border: 1px solid black;
      border-radius:4px;
      margin-left:90px
    }
  
  .label:after {
     position: absolute;
     display: block;
     height: 20px;
     content: "";
     background-repeat: no-repeat;
     background-position: center center;
     background-size: 80%;
  }
  
  input[type="checkbox"]:checked ~ .label::after {
      background-image: url("https://cdn-icons-png.flaticon.com/512/447/447147.png");
      width: 20px;
      height: 20px;
    }
<div class="wrapper">
        <input class="input" name="checkbox2" id="checkbox2" type="checkbox">
        <label class="label reverse" for="checkbox2">
          <div class="label-wrapper">
            Option 1
          </div>  
        </label>
      </div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related