Search code examples
jquerycsscalc

jQuery CSS width calculation using calc


After pulling my hair out trying to make a jQuery/CSS-calc scenario get the width of a element to equal a specific numerical value (32px) multiplied by the value of an input[type="number"] field, I eventually gave up. I kept running into trouble storing the element's width in a variable & using the correct syntax inside the calc declaration.

I eventually accomplished what I set out to do by hard-coding the CSS width values in conditional statements corresponding to each value from 1-4. Though I got it to work, it is definitely inefficient & dirty. I am hoping someone can show me some more efficient alternatives that accomplish the same result using calc or something else requiring much less code.

So to sum up - when the quantity is 1, the width of the target element span#dogFace is 32px. When the quantity is 2, the width of the target element is 64px, and so on. If you try to increase it to 5, a text warning appears.

Here is the example I posted

Any advice appreciated!

Bonus Points: I initially tried to find a CSS-only solution, which I think still must be possible, but I couldn't make it work. If anyone knows how to accomplish this with some fancy CSS, I'd love to learn how that'd work as well.

$('#input_5_78').on('change', function() {
    if (this.value >= 5) {
      $('#dogFace').hide();
      $('#xtraDog').show();
    } else {
      $('#dogFace').show();
      $('#xtraDog').show();
    }

    if (this.value == 0) {
      $('#dogFace').width('0');
      $('#xtraDog').hide();
    } else if (this.value == 1) {
      $('#xtraDog').hide();
      $('#dogFace').width('32px');
    } else if (this.value == 2) {
      $('#dogFace').width('64px');
      $('#xtraDog').hide();
    } else if (this.value == 3) {
      $('#dogFace').width('96px');
      $('#xtraDog').hide();
    } else if (this.value == 4) {
      $('#dogFace').width('128px');
      $('#xtraDog').hide();
    }
})
.emoji {
  height: 32px;
  background-position: left top;
  background-repeat: repeat-x;
  background-size: contain;
  display: inline-block;
  vertical-align: top;
}

.emoji.dog {
  background-image: url('https://afeld.github.io/emoji-css/emoji/dog.png');
}

#dogFace {
  float: left;
}

#xtraDog {
  display: none;
}

ul li.qtyField {
  list-style-type: none;
}

.qtyField label {
  float: left;
}

.qtyField input[type="number"] {
  float: left;
  font-weight: bold;
  font-size: 1.15em;
  margin: 0 0 0 15px;
  width: 45px!important;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <ul>
    <li class="qtyField">
      <label class="gfield_label" for="input_5_78">How many dogs need training?</label>
      <div class="ginput_container ginput_container_number">
        <input name="input_78" id="input_5_78" step="any" min="0" max="5" value="0" type="number">
      </div>
      <div class="gfield_description">
        <span id="dogFace" class="emoji dog"></span>
        <span id="xtraDog"><br><br>Woah, that's a lot of dogs!<br />Please call (480) 555-1234 to discuss your training needs.</span>
      </div>
    </li>
  </ul>
</form>


Solution

  • Probably not possible using only CSS, but that would be awesome. Here's a variation of your attempt that DRYs up the code a bit and makes it easier to understand.

    $('#input_5_78').on('change', function() {
      if (this.value < 5) {
        $('#xtraDog').hide();
        $('#dogFace').width(this.value * 32 + 'px');
      } else {
        $('#dogFace').width('0');
        $('#xtraDog').show();
      }
    })
    .emoji {
      height: 32px;
      background-position: left top;
      background-repeat: repeat-x;
      background-size: contain;
      display: inline-block;
      vertical-align: top;
    }
    
    .emoji.dog {
      background-image: url('https://afeld.github.io/emoji-css/emoji/dog.png');
    }
    
    #dogFace {
      float: left;
    }
    
    #xtraDog {
      display: none;
    }
    
    ul li.qtyField {
      list-style-type: none;
    }
    
    .qtyField label {
      float: left;
    }
    
    .qtyField input[type="number"] {
      float: left;
      font-weight: bold;
      font-size: 1.15em;
      margin: 0 0 0 15px;
      width: 45px!important;
      text-align: center;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <form>
      <ul>
        <li class="qtyField">
          <label class="gfield_label" for="input_5_78">How many dogs need training?</label>
          <div class="ginput_container ginput_container_number">
            <input name="input_78" id="input_5_78" step="any" min="0" max="5" value="0" type="number">
          </div>
          <div class="gfield_description">
            <span id="dogFace" class="emoji dog"></span>
            <span id="xtraDog"><br><br>Woah, that's a lot of dogs!<br />Please call (480) 555-1234 to discuss your training needs.</span>
          </div>
        </li>
      </ul>
    </form>