Visual limited for textarea

by Denis Minov

HTML

<div class="add-text">
  <textarea id="for_limiter" spellcheck="false" maxlength="40" placeholder="Введите текст"></textarea>
  <div id="in_limiter" class="limiter">
    <div class="limiter--progress">
      <div class="limiter--progress-bg"></div>
    </div>
    <div class="limiter--counter"></div>
  </div>
</div>

CSS

@import url('https://fonts.googleapis.com/css?family=Roboto');
body {background: transparent; font-family: 'Roboto', sans-serif; font-size: 13px; font-weight: 400; color: #333;}

.add-text {display: block; width: 100%; max-width: 350px; background: #fff; border-radius: 10px; padding: 10px; box-sizing: border-box;}
.add-text textarea {display: block; width: 100%; max-width: 100%; min-height: 100px; border: 1px solid #aaa; border-radius: 5px; background: #eee; padding: 10px; box-sizing: border-box; resize: vertical; font: inherit;}
.add-text textarea:focus {border-color: #ccc; background: #fff;}

.limiter {display: block; width: 100%;}
.limiter .limiter--progress {display: block; width: 100%; height: 5px; background: #d7dfe3; border-radius: 2px; position: relative; overflow: hidden; margin: 5px 0 2px;}
.limiter .limiter--progress-bg {display: block; width: 0; background: #95a5a6; max-width: 100%; height: inherit; position: absolute; left: 0; transition: background-color .2s linear;}
.limiter.--warning .limiter--progress-bg {background: #e67e22;}
.limiter.--warning .limiter--counter {color: #e67e22;}
.limiter.--limited .limiter--progress-bg {background: #e74c3c;}
.limiter.--limited .limiter--counter {color: #e74c3c;}

JavaScript

let limiter = $('#in_limiter'), // textarea
		vallimit = $('#for_limiter').attr('maxlength') || 5000, // ограничение, изначально берётся от атрибута maxlength, если его нет то 5000 символов
    limitWarn = vallimit-30; // момент, на котором выдаст предупреждение, что скоро лимит кончиться.
    
$('#in_limiter .limiter--counter').text(0+' / '+vallimit);
$('#for_limiter').on('input propertychange', function(){
	let vallen = $(this).val().length,
  		classes = vallen == vallimit ? ' --limited' : vallen >= limitWarn ? ' --warning' : '';
  limiter.attr('class', 'limiter'+classes);
  limiter.find('.limiter--progress-bg').css('width', (100 / (vallimit / vallen)).toFixed(2)+'%');
  limiter.find('.limiter--counter').text(vallen+' / '+vallimit);
});