Производственная пьеса в N+1 частях. Часть первая: Звёздочки
![](https://img.golos.io/proxy/https://i.imgur.com/wimK38T.jpg)
В жизни каждого разработчика наступает момент, когда к нему приходит заказчик и просит «запилить рейтинги».
«Нынче пользователь совсем отупел, поэтому численный рейтинг выглядит непонятно. Нам нужны звёзды! Да что я вам рассказываю, вы и сами всё знаете — вы же профессионал», — уверенно проговорил заказчик.
Так, говорят все клиенты, которым лень описывать задачу. Иногда они сами не знают, что хотят, зачем хотят, но чем-то задним чуют, что без этого им жизнь больше не мила.
«Что может быть проще, чем сделать звёзды?» — с этой мыслью я отправился в отдел разработки и передал задание самому неопытному джуниору. Ведь зачем отвлекать умудренных бородатых дядек такой простой задачей — заказчику просто нужны звёзды.
Во вторник, на следующей планерке, самый молодой джуниор представил своё детище:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<h1>Шеф попросил рейтинг со звёздами</h1>
<h2>Две звезды</h2>
<div class="rating-stars">
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
</div>
<h2>Три звезды</h2>
<div class="rating-stars">
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
</div>
<style>
.rating-stars > span {
color: orange;
}
</style>
https://jsfiddle.net/vryp2t77/
Пам-пам! Вы хотели звёзды — вот вам звёзды: две — генерал-лейтенант, три — генерал-полковник. Молодой отчитался, и с гордым видом белоголового орлана, оттого, что успел сделать всё в поставленный срок, а остальные нет, решил подождать обратную связь от аудитории. Зря. Программисты народ завистливый и чужих успехов не терпят.
«А вот скажи мне, молодой, пять звёзд — это хорошо или плохо?» — каверзно задал вопрос слегка обросший щетиной мидл-разработчик.
«Хорошо», — немного испугано ответил джуниор. Гордости в гримасе заметно поубавилось.
«Это по коньяку понятно, что хорошо. А пять звёзд на кинопоиске — тоже хорошо?» — с интонацией КГБ-шника на допросе продолжил мидл. Джуниор ничего не ответил, лишь про себя подумав, что у его любимого аниме рейтинг 9 звёзд, значит 5 — это как-то так себе. После планёрки он быстро пошёл доделывать вчерашнюю задачу со звёздами. Она всё еще выглядела тривиальной, но было немного стыдно, что до относительности рейтинга своей головой он не додумался.
Среда. Джуниор снова гордо презентует своё детище:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<h1>Относительный рейтинг со звёздами</h1>
<h2>Две звезды</h2>
<div class="rating-stars">
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
</div>
<h2>Три звезды</h2>
<div class="rating-stars">
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star"></span>
<span class="fa fa-star"></span>
</div>
<style>
.rating-stars > span.checked {
color: orange;
}
</style>
https://jsfiddle.net/2ksbcupg/
В офис завезли новый кофе, поэтому настроение было приподнятое и желания снова приструнить новичка не возникло. Решили передать заказчику.
Заказчик рад, льём на продакшен и готовимся открывать шампанское в пятницу — всё же праздник, не каждый день заказчик остаётся доволен.
Да что там день, не каждый месяц!
На следующее утро перед планеркой раздался звонок. «Здравствуйте, мы на счёт ваших звёздочек!» — весело прозвучал голос из трубки. «Благодарности сейчас молодому будут выражать», — подумал аккаунт-менеджер и включил на громкую связь. «Мы тут начали с девочками звёздочки ваши к товарам добавлять, и хотели узнать, а как поставить 3.7 звёздочки?» — продолжил весёлый женский голос из трубки. В помещении воцарило суровое мужское молчание. Джуниор попытался крикнуть «никак», но вовремя был обезврежен, оценившим ситуацию аккаунт-менеджером. Нельзя говорить клиенту «никак», если вот-вот клиент собирался подписать акты выполненных работа.
«Мы вам перезвоним, у нас планёрка» — отточеной фразой закончил разговор аккаунт менеджер, чтобы выиграть немного времени на оценку обстановки.
Полдня джуниор изучал псевдоэлементы :before и :after в CSS, чтобы вечером показать разработку уже нового для себя уровня. «Делать звёзд можно сколько хочешь», — горделиво пояснил молодой.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<h1>Относительный рейтинг со дробными звёздами</h1>
<h2>Две звезды</h2>
<div class="rating-box">
<div class="rating-stars" style="width:40%">
</div>
</div>
<h2>Три и семь звезды</h2>
<div class="rating-box">
<div class="rating-stars" style="width:74%">
</div>
</div>
<style>
.rating-box {
position: relative;
vertical-align: middle;
font-family: FontAwesome;;
display: inline-block;
color: #dadada;
}
.rating-box:before{
content: "\f005 \f005 \f005 \f005 \f005";
}
.rating-box .rating-stars {
position: absolute;
left: 0;
top: 0;
white-space: nowrap;
overflow: hidden;
color: orange;
}
.rating-box .rating-stars:before {
content: "\f005 \f005 \f005 \f005 \f005";
font-weight: 900;
}
</style>
https://jsfiddle.net/30g7m67g/
Накатанная схема: деплой на продакшн, звонок заказчику. «Здрасьте, не могли перезвонить раньше в виду серьезной загруженности. Я уточнил у специалиста, можете ставить ваши звёзды как хотите: хоть 0.5, хоть 3.1416», — уверенно произнёс аккаунт-менеджер. Радость и ликование на той стороне провода, а затем короткие гудки — ушли заполнять.
Пятница. Бухгалтер ждёт подписанные акты выполненных работ, а молодой под видом выполнения задач быстро пролистает новости на Хабре по тегу «криптовалюта», мидл и сеньёр, жестикулируя, обсуждают паттерны проектирования рядом с кофемашиной — всё спокойно. Звонок.
«Здравствуйте, я маркетолог заказчика. Мы начали выставлять звёздочки всем отделом и поняли, что номенклатуру в over 9000 позиций мы будем обрабатывать до утра понедельника, а нам это надо было еще в прошлый вторник. Переделайте чуть-чуть, чтобы пользователи сами могли голосовать. А ещё, мы посмотрели метрику и оказалось, что у 99% наших пользователей AdBlock и вообще отключен JavaScript. Так что давайте там вот без этой вашей Джавы.
С директором согласовали. Ждём через час.»
Джуниор побледнел и молча осунулся на стуле. В голове пробежала мысль распечатать заявление на увольнение, которое он недавно видел в корпоративном файлообменнике.
«Не переживай, молодой, всё уже придумали до нас», — по-отечески похлопав по плечу, проговорил внезапно появившийся сеньор-разработчик. «Надо лишь правильно спросить на правильном языке».
Умудренный опытом программист начал бордо пролистывать выдачу Google на фразу «half star rating radio buttons». О чудо!
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<h1>Рейтинг из radio-кнопок</h1>
<fieldset class="rate">
<input type="radio" id="rating10" name="rating" value="10" /><label for="rating10" title="5 звёзд"></label>
<input type="radio" id="rating9" name="rating" value="9" /><label class="half" for="rating9" title="4 1/2 звезды"></label>
<input type="radio" id="rating8" name="rating" value="8" /><label for="rating8" title="4 звезды"></label>
<input type="radio" id="rating7" name="rating" value="7" /><label class="half" for="rating7" title="3 1/2 звезды"></label>
<input type="radio" id="rating6" name="rating" value="6" /><label for="rating6" title="3 звезды"></label>
<input type="radio" id="rating5" name="rating" value="5" /><label class="half" for="rating5" title="2 1/2 звезды"></label>
<input type="radio" id="rating4" name="rating" value="4" /><label for="rating4" title="2 звезды"></label>
<input type="radio" id="rating3" name="rating" value="3" /><label class="half" for="rating3" title="1 1/2 звезды"></label>
<input type="radio" id="rating2" name="rating" value="2" /><label for="rating2" title="1 звезда"></label>
<input type="radio" id="rating1" name="rating" value="1" /><label class="half" for="rating1" title="1/2 звезды"></label>
</fieldset>
<style>
/* Контейнер для звёзд */
.rate {
display: inline-block;
border: 0;
color: #dadada;
}
/* Прячем стандартные radio-кнопки */
.rate > input {
display: none;
}
/* Звёзды обязательно должны обтекать элементы справа, иначе магии c половинками не получится. Точнее получится, но справа налево. */
.rate > label {
float: right;
}
/* Отображаем звёзды в label-элементах. По клику на них свойство checked выставляется нужной radio-кнопке автоматически */
.rate > label:before {
display: inline-block;
font-size: 2rem;
padding: .3rem .2rem;
margin: 0;
cursor: pointer;
font-family: FontAwesome;
content: "\f005 "; /* Это уже знакомя звезда в Font Awesome */
}
/* Добавляем половинки. Никто не будет оценивать с точностью до второго знака после запятой, а вот половинки не помешают */
.rate .half:before {
content: "\f089 "; /* А это половинка звезды в Font Awesome */
position: absolute;
padding-right: 0;
}
/* Красим звёзды по клику и наведению */
input:checked ~ label, /* красим выделенную звезду и все предыдущие */
label:hover,
label:hover ~ label { color: orange; } /* красим предыдущие звёзды по наведению */
/* Красим звёзды в красный, если уже есть выбранная, но мы хотим переголосовать */
input:checked + label:hover,
input:checked ~ label:hover,
input:checked ~ label:hover ~ label,
label:hover ~ input:checked ~ label { color: red; }
</style>
https://jsfiddle.net/cyps0nq3/7/
Новая версия звёздочек была сдана вовремя, акты оплачены, а заказчик доволен. После этого тривиальные задачи больше не казались молодому такими тривиальными. Работа была выполнена, но справочник по CSS-селекторам он всё-таки добавил в свой список для чтения в iBooks.
Материал подготовлен автором @ambersport
Последний код по ссылке https://jsfiddle.net/cyps0nq3/7/
Примечание редактора если вы не совсем понимаете чем отличаются джуниор, сеньёр и мидл - @hypedemetry недавно рассказывал об этом https://golos.io/vox-populi/@vp-webdev/ne-vse-programmisty-odinakovo-polezny-ili-chem-razlichayutsya-tyzhprogrammisty