Хороший вопрос. Не уверен, что есть хороший ответ, кроме изменения схемы для использования символов Unicode вместо байтов. Например, в SQL Server с NVARCHAR или MySQL с UTF-8 столбцы параметров сортировки ограничены длиной символа. Это немного подталкивает к тому, что «длины столбцов не могут изменяться», конечно, даже если они технически имеют одинаковую «длину».
Что бы это ни стоило, восточноазиатские пользователи привыкнут к мысли, что символ не является байтом, поскольку существует давняя традиция латинских символов «полуширины», занимающих вдвое меньше памяти и места на экране как китайские идеографы.
Вы, в общем-то, не можете ожидать, что кто-нибудь получит номера байтов UTF-8. Возможно, на стороне клиента вы могли бы сделать это чисто визуально, используя строку «использованное количество» вместо количества байтов:
<style type="text/css">
.field { width: 12em; }
.field input { width: 100%; }
.field input { box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; -webkit-box-sizing: border-box; -khtml-box-sizing: border-box; }
.indicator { background: blue; height: 5px; }
.indicator-over { background: red; height: 5px; }
</style>
<div class="field">
<input type="text" name="pwd" class="limited-12">
</div>
<script type="text/javascript">
function limitInput(element, limit) {
var indicator= document.createElement('div');
element.parentNode.insertBefore(indicator, element.nextSibling);
element.onchange=element.onkeyup= function() {
var utf8= unescape(encodeURIComponent(element.value));
indicator.className= utf8.length>limit? 'indicator-over' : 'indicator';
var used= Math.min(utf8.length/limit, 1);
indicator.style.width= Math.floor(used*100)+'%';
}
element.onchange();
}
var inputs= document.getElementsByTagName('input');
for (var i= inputs.length; i-->0;)
if (inputs[i].className.substring(0, 8)=='limited-')
limitInput(inputs[i], parseInt(inputs[i].className.substring(8)));
</script>