<div class="calc-outer-wrap">
  <div id="form-error" style="display:none;"></div>
  <form class="calc-form" id="calc-form">
    <div class="form-fields">
      <div class="field-outer col-1">
      
        <label for="r-time-m" class="top-label">Race Distance</label>
        <div class="field-items">
          <div class="field field-large">
            <select id="race" name="race">
                            <option value=""> </option>
                            <option value='1m'>1 Mile</option>   
                            <option value='5k'>5 km</option>
                            <option value='5m'>5 Mile</option>
                       <option value='10k'>10 km</option>         
                            <option value='10m'>10 Mile</option>
                            <option value='halfmarathon'>Half Marathon</option>
                            <option value='marathon'>Marathon</option>

                        </select>
          </div>
          <!--  /.field -->
        </div>
        <!--  /.field-items -->
        
        
        
      </div>
      <!--  /.field-outer -->
      
      
      
      <div class="field-outer col-2">
        <label for="r1" class="top-label">Your Time:</label>
        <div class="field-items">

          <div class="field">
            <input type="text" name="finish-time-hr" id="finish_time_hr" inputmode="numeric" pattern="[0-9]*" placeholder="Hour">

          </div>
          <!--  /.field -->
          <div class="field">
            <input type="text" name="finish-time-min" id="finish_time_min" inputmode="numeric" pattern="[0-9]*" placeholder="Min">

          </div>
          <!--  /.field -->
          <div class="field">
            <input type="text" name="finish-time-sec" id="finish_time_sec" inputmode="numeric" pattern="[0-9]*" placeholder="Sec">

          </div>
          <!--  /.field -->

        </div>
        <!--  /.field-items -->
      </div>
      <!--  /.field-outer -->

      

      <div class="btn-wrap field-outer">
        <button class="form-submit">Calculate</button>
      </div>

    </div>
    <!--  /.form fields -->
  </form>
  <div id="results" style="display:none;"></div>
</div>
<!--  /.calc-outer-wrap -->
$border-radius : 0.1875rem;
$primary: #9951FF;
$primary-dark: #803ede;
$secondary: #59e7ed;
$secondary-dark: darken($secondary, 10);

@mixin mobile {
  @media (min-width:22.5rem) {
    @content;
  }
}
@mixin tablet {
  @media (min-width:45rem) {
    @content;
  }
}

* {box-sizing: border-box;}

html, body {
  margin: 0;
  padding: 0;
}
.calc-outer-wrap {
  margin: 0 auto;
  background: #f3f3f3;
  font-size: 1rem;
  line-height: 1.3;
  font-family: Helvetica Neue,Helvetica, Arial, sans-serif;
  padding: 0 0.625rem;
  
  @include mobile {
    padding: 0.625rem;
  }
  @supports (-webkit-overflow-scrolling: touch) {
    padding: 0.625rem;
  }
}

.form-fields {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-end;
}
.field-outer {
  width: 32%;
  flex-basis: calc(100% / 3 - 5px);
  
  @include tablet {
    width: 48%;
    flex-basis: calc(50% - 10px);
    margin-bottom: 5px;
  }
}
label,
input,
select {
  font-size: 1em;
  line-height: 1.3;
  display: block;
}
input,
select {
  height: 1.75rem;
  border: 1px solid #bbb;
  width: 100%;
  background: #fff;
  padding: 0 0.325rem;
  border-radius : $border-radius;
  transition: box-shadow 200ms ease-in-out;
  box-shadow: inset 0 0 0 0 $secondary;
  -webkit-appearance: none;
   -moz-appearance: none;
        appearance: none;

  &:focus {
    outline: 0;
    box-shadow: inset 0 -3px 0 -1px $secondary;
    border-radius: $border-radius $border-radius 1px 1px;
  }
}
select {
  font-size: 0.875rem;
  background: #fff url("data:image/svg+xml;charset=UTF-8,%3csvg width='16px' height='14px' viewBox='0 0 8 17' xmlns='http://www.w3.org/2000/svg' fill='%238A8A8A'%3e%3cpolygon fill='%238A8A8A' points='4 17 0 10 8 10'%3e%3c/polygon%3e%3cpolygon fill='%238A8A8A' points='4 0 0 7 8 7'%3e%3c/polygon%3e%3c/svg%3e") right center no-repeat;
  &:-moz-focusring {
    color: transparent;
    text-shadow: 0 0 0 #000;
  }
  &::-ms-expand {
    display: none;
  }
}
.field-items {
  display: flex;
  justify-content: space-between;

  label,
  small{
    font-size: 0.75rem;
    color: #999;
  }
}
.field {
  display: inline-block;
  width: 32%;
  flex-grow: 1;

  + .field {
    margin-left: 3px;
  }

}
.m-hide {
  display: none;
  @include tablet {
    display: inline;
  }
}
.field-large {
  flex: 1;
  width: 67%;
}
.field-small {
  width: 4em;
  flex-grow: 0
}
.top-label {
  font-weight: bold;
  font-size: 0.875rem;
  line-height: 1.4;
  display: block;
  .small {
    color: #999;
    font-weight: normal;
    font-size: 0.75rem;
  }
}
.btn-wrap {
  align-self: flex-end;
  margin: 5px 0 0 auto;
  margin-left: auto;
  flex-basis: 12rem;
}
.form-submit {
  background: $secondary;
  display: block;
  border: 0;
  width: 100%;
  font-size: 1rem;
  border-radius: $border-radius;
  height: 1.5rem;
  color:#fff;
  box-shadow: 1px 1px 1px 0 rgba(0,0,0,0.15);
  cursor: pointer;
  text-transform: uppercase;
  
  @include mobile {
    height: 2rem;
  }

  &:hover,
  &:focus {
    background: $secondary-dark;
    box-shadow: 2px 2px 3px 0 rgba(0,0,0,0.3);
    outline: 0;
  }

  &:active {
    box-shadow: none;
  }
}

#form-error {
  color: #fff;
  margin-bottom: 0.5rem;
  text-align:center;
  color: #c1000b;
  background-color: #ffd5d5;
  padding: 3px;
  font-size: 0.875rem;
}

#results {
  position: relative;
  width: 100%;
  justify-content: center;
  align-items: center;
  font-size: 0.875rem;

  @include mobile {
    font-size: 1rem;
  }

  p {
    margin: 0;

    @include tablet {
      text-align: center;
    }
  }
  dl {
    width: 22em;
    margin: 1em auto 0;
    column-count: 2;

    dt,dd {
      display: inline-block;
      margin: 0;
    }
    dt {
      width: 6em;
      font-weight: bold;
    }
    dt,dd {
      margin: 0;
    }
    dd {
      width: 4em;
      text-align: right;
    }
  }

  #rs {
    position: absolute;
    bottom: 0;
    right: 0;
    font-size: 0.875rem;
    color: #aaa;
    &:hover {
      color: $primary;
    }
  }
}
View Compiled
(function() {
  const form    = document.getElementById('calc-form');
  const results = document.getElementById('results');
  const errors  = document.getElementById('form-error');
  
  /**
   * Display a form validation error
   *
   * @param   {String}  msg  The validation message
   * @return  {Boolen}       Returns false
   */
  function errorMessage(msg) {
    errors.innerHTML = msg;
    errors.style.display = '';
    return false;
  }
  
  // Takes a VO2 measurement and converts it to a velocity. 
function  VO2ToVel (VO2) {
	return (29.54 + 5.000663 * VO2 - 0.007546 * VO2 * VO2);
}
  
// Takes a time in minutes and uses EQ 2 to convert it to a percent of VO2 maximum. 	
function timeToPercentVO2Max (mins) {
	return (.8 + 0.1894393 * Math.exp(-.012778 * mins) + 0.2989558 * Math.exp(-.1932695 * mins)); 
}
  
// Takes a velocity and converts it to a VO2 level. 	
function velToVO2 (vel) {
	return (-4.60 + 0.182258 * vel + 0.000104 * vel * vel);
}  
// Convert speed to display 	  
function timeConvert(speed,checkYasso=false) {
	var resultKm;
  var resultMile;
  
	resultKm = (1 / speed) * 1000;
	resultMile = (1 / speed) * 1609;

	minsKm = Math.floor(resultKm);
	secsKm = Math.floor((resultKm - minsKm) * 60);
	minsMile = Math.floor(resultMile);
	secsMile = Math.floor((resultMile - minsMile) * 60);
 
  if(secsKm > 9){
    sKmSep = ':';
	} else {
    sKmSep = ':0';
	}
  if(secsMile > 9){
    sMSep = ':';
	} else {
    sMSep = ':0';
	}
  if (checkYasso==true) {
  return '' + minsMile + sMSep + secsMile + ' per 800.';
  } else {
  return '' + minsKm + sKmSep + secsKm + ' per Km and ' + minsMile + sMSep + secsMile + ' per Mile.';    
  }  
}
  
// Convert dropdown of race distance to km  
function raceToMiles(raceDist) {
    var miles
    switch (raceDist) {
    case 'marathon':
        miles=26.21875;
        break;
    case 'halfmarathon':
        miles=13.109375;
        break;
    case '10m':
        miles=10;
        break;
    case '10k':
        miles=6.21371192;
        break;
    case '5m':
        miles=5;
        break;
    case '5k':
        miles=3.10685596;
        break;
    case '3k':
        miles=1.864113576;
        break;
    case '1m':
        miles=1;
        break;
    case '1500':
        miles=0.932056788;
        break;
            }
    
    return (miles*1609)
  }  
    
  /**
   * Hide the results and reset the form
   */
  function resetForm(e) {
    if(e.target.id = 'rs') {
      e.preventDefault();
      results.style.display = 'none';
      form.style.display = '';
      //form.reset()
    }
  }
  /**
   * Convert time to seconds
   *
   * @param   {Int}  m  Minutes
   * @param   {Int}  s  Seconds
   * @return  {Int}     The time in seconds
   */
  function toMinutes(h, m, s) {
    h = parseInt(h) || 0;
    m = parseInt(m) || 0;
    s = parseInt(s) || 0;
    return h * 60 + m + s / 60;
  }
  
  /**
   * Display the results on the page
   *
   */
  function displayResults({velEasyDisplay,velMaxDisplay,velTempoDisplay,velSpeedDisplay,velLongDisplay,velYassoDisplay}) {
    results.innerHTML = `<p><b>${(velEasyDisplay)}</b><br> 
<p><b>${(velMaxDisplay)}</b><br>
<p><b>${(velTempoDisplay)}</b><br>
<p><b>${(velSpeedDisplay)}</b><br>
<p><b>${(velLongDisplay)}</b><br>
<p><b>${(velYassoDisplay)}</b><br>

<a href="#" id="rs">Revise</a>


`;    
    
    
    
    results.style.display = '';
    form.style.display = 'none';
    errors.style.display = 'none'; 
  }

  /**
   * Handle form submit
   * Gather/calculate data from form input and display results
   */
  function handleSubmit(e) {
      e.preventDefault();
      let data = {
      race : form.race.value,              
      finishTime : toMinutes(form.finish_time_hr.value, form.finish_time_min.value, form.finish_time_sec.value)
      }
    
      if(!data.race) {
        return errorMessage('You must select a race distance.');
      }
      if (!data.finishTime) {
        return errorMessage('You must enter a finish time.');
      }    
   
     
     data.distance = raceToMiles(data.race);
     data.speed = (data.distance/data.finishTime);
     data.v02Max = velToVO2(data.speed) / timeToPercentVO2Max(data.finishTime);
     data.velEasy		 = VO2ToVel(data.v02Max * .7); 
	   data.velTempo	 = VO2ToVel(data.v02Max * .88);
	   data.velMaximum = VO2ToVel(data.v02Max);
	   data.velSpeed	 = VO2ToVel(data.v02Max * 1.1);
	   data.velxlong	= VO2ToVel(data.v02Max * .6);
     data.velYasso = data.velMaximum * 1.95; 

     data.velEasyDisplay = 'Easy run training pace: ' + timeConvert(data.velEasy);
     data.velTempoDisplay = 'Tempo run training pace: ' + timeConvert(data.velTempo);
     data.velMaxDisplay = 'VO2-max training pace: ' + timeConvert(data.velMaximum);
     data.velSpeedDisplay = 'Speed form training pace: ' + timeConvert(data.velSpeed);
     data.velLongDisplay = 'Long run training pace: ' + timeConvert(data.velxlong);
     data.velYassoDisplay = 'Yasso 800s training pace: ' + timeConvert(data.velYasso,true);

    //console.log(data);
    
    displayResults(data);   
  }

  /**
   * Keep unit select fields in sync
   * Changing one changes both
   */
  function handleChange(e) {
    let sel = 'select.unit';
    if(e.target.matches(sel)) {
      let val = e.target.value;
      document.querySelectorAll(sel).forEach(s => s.value = val);
    }
    // Hide errors
    errors.style.display = 'none';
  }

  // Add Event Listeners
  form.addEventListener('submit', handleSubmit);
  form.addEventListener('change', handleChange);
  results.addEventListener('click', resetForm, true);
 
  
  
}
)();




View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js