<form id="form">
  
  <div>
    <input type="text" name="_text" required/>
  </div>
  
  <div>
    <label>
      <input type="radio" name="radio1" required/>
      ラジオボタン
    </label>
  </div>
  
  <div>
    <label>
      <input type="checkbox" name="agree" value="1" required/>
      チェックボックス
    </radio>
  </div>
  
  <div>
    <select name="example" required>
      <option></option>
      <option value="選択肢1">選択肢1</option>
      <option value="選択肢2">選択肢2</option>
      <option value="選択肢3">選択肢3</option>
    </select>
  </div>
  
  <div>
    <input type="file" required/>
  </div>
  
  <button type="submit">送信</button>
</form>
input,
select {
  &:valid {
    border: 1px solid green;
  }
  &:invalid {
    border: 1px solid red;
  }
}

// 案件上デフォルトのstyleで使われることがほぼないのでstyleは適当
[type='radio'],
[type='checkbox'] {
  &:valid {
    box-shadow: green 0px 0px 3px 1px;
  }
  &:invalid {
    box-shadow: red 0px 0px 3px 1px;
  }
}
View Compiled
const $form = document.getElementById('form');

// 親要素(form)にイベントをつけると子要素のイベントが拾える
$form.addEventListener('change', (e) => {
  let type = e.target.type;
  console.log('onChange', type);
});

$form.addEventListener('input', (e) => {
  let type = e.target.type;
  console.log('onInput', type);
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.