Стояла задача добавить стар-рейтинг к форме комментариев для шаблона.
Это должны быть обычные 5 звездочек, при наведении на которые выделяются все звездочки от начала до той, на которую навели и при выборе (клике) такое состояние сохраняется. Также, конечно, нужно обеспечить передачу значения указанного рейтинга при отправке формы.
Решение делал не для конечного проекта, а для шаблона. Поэтому нужно было сделать звездочки максимально гибким для дальнейшей кастомизации. То есть изменения цвета, размера звездочек должно быть максимально легким. Под такую конфигурацию использование спрайта изображений не подходило, поэтому решил использовать шрифтовые иконки. Выбор пал на сервис Font Awesome. Там есть звездочки с названием fa-star-o — звездочка по умолчанию и fa-star — звездочка активная (при наведении и выборе).
Дальше решил подумать, как можно реализовать такую задача минимальными ресурсами, в идеале без использования javascript. В итоге все получилось и, как по мне, такое решение оптимальное для подобной задачи.
Кому лень читать дальше, можете сразу посмотреть результат тут — codepen.
Общая идея состоит в том, что мы выводим рейтинг обычными радиокнопками, что бы сохранить передачу данные через форму. Дальше прячем радиокнопки с помощью CSS, а выделять их будем с помощью клика по соседних лейблах, которые ссылаются на радиокнопку атрибутом for. Сами же лейблы мы выводим в виде иконок с сервиса Font Awesome.
В итоге HTML-разметка следующая:
Конечно, не забываем подключить шрифт Font Awesome в начале.
Очень важно сохранять порядок следования элементов input и label, при чем не помещать никаких вложенных элементов внутрь.Такая зависимость от html-разметки негативная, но это та жертва которую я посчитал уместной.
Также очень важно выводить радиокнопки в обратном порядке от 5 до 1.
Первое, что нужно сделать — это спрятать радиокнопки. В результате у нас остаются только звездочки при нажатия на которые выделяется нужный радиобокс.
Второе — при наведении иконка должна изменятся на активную, при чем измениться должна не только текущая иконка, а и все иконки перед ней!
content: "\f005"; — это код активной иконки стар-рейтинга в шрифте Font Awesome. Иконки в этом шрифте вставляются через псевдоэлемент ::before
Третье — при клике на иконку состояние наведения должно сохраниться, то-есть активными должны быть текущая и соседние звездочки.
Добавляем к этому же правилу еще один селектор:
В результате главные стили, которые делают основную работу следующие:
Дальше нужно перевернуть звездочки в другую сторону, так как сестринский селектор выбирает соседей по направлению текста. По умолчанию слева-направо, а нам нужно наоборот.
Для решения этой задачи есть два способа: изменить направления текста для элемента star-rating указав direction: rtl или сделать элемент плавающим по правой стороне. Мне больше по душе второй вариант. Кроме этого сделав элементы внутри .star-rating плавающими мы уберем отступы между звездочками из-за которых пропадает наведение
В общем, дальше уже все обычно. Еще раз ссылка на результат codepen.
В результате у нас полноценный стар-рейтинг со шрифтовыми иконками, написанный только на HTML+СSS в котором легко изменять размеры и цвет звездочек.
Это должны быть обычные 5 звездочек, при наведении на которые выделяются все звездочки от начала до той, на которую навели и при выборе (клике) такое состояние сохраняется. Также, конечно, нужно обеспечить передачу значения указанного рейтинга при отправке формы.
Решение делал не для конечного проекта, а для шаблона. Поэтому нужно было сделать звездочки максимально гибким для дальнейшей кастомизации. То есть изменения цвета, размера звездочек должно быть максимально легким. Под такую конфигурацию использование спрайта изображений не подходило, поэтому решил использовать шрифтовые иконки. Выбор пал на сервис Font Awesome. Там есть звездочки с названием fa-star-o — звездочка по умолчанию и fa-star — звездочка активная (при наведении и выборе).
Дальше решил подумать, как можно реализовать такую задача минимальными ресурсами, в идеале без использования javascript. В итоге все получилось и, как по мне, такое решение оптимальное для подобной задачи.
Кому лень читать дальше, можете сразу посмотреть результат тут — codepen.
HTML-разметка
Общая идея состоит в том, что мы выводим рейтинг обычными радиокнопками, что бы сохранить передачу данные через форму. Дальше прячем радиокнопки с помощью CSS, а выделять их будем с помощью клика по соседних лейблах, которые ссылаются на радиокнопку атрибутом for. Сами же лейблы мы выводим в виде иконок с сервиса Font Awesome.
В итоге HTML-разметка следующая:
<div class="star-rating">
<div class="star-rating__wrap">
<input class="star-rating__input" id="star-rating-5" type="radio" name="rating" value="5">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-5" title="5 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-4" type="radio" name="rating" value="4">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-4" title="4 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-3" type="radio" name="rating" value="3">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-3" title="3 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-2" type="radio" name="rating" value="2">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-2" title="2 out of 5 stars"></label>
<input class="star-rating__input" id="star-rating-1" type="radio" name="rating" value="1">
<label class="star-rating__ico fa fa-star-o fa-lg" for="star-rating-1" title="1 out of 5 stars"></label>
</div>
</div>
Конечно, не забываем подключить шрифт Font Awesome в начале.
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
Очень важно сохранять порядок следования элементов input и label, при чем не помещать никаких вложенных элементов внутрь.Такая зависимость от html-разметки негативная, но это та жертва которую я посчитал уместной.
Также очень важно выводить радиокнопки в обратном порядке от 5 до 1.
CSS-стили
Первое, что нужно сделать — это спрятать радиокнопки. В результате у нас остаются только звездочки при нажатия на которые выделяется нужный радиобокс.
.star-rating__input{
display: none;
}
Второе — при наведении иконка должна изменятся на активную, при чем измениться должна не только текущая иконка, а и все иконки перед ней!
.star-rating__ico:hover:before,
.star-rating__ico:hover ~ .b-star-rating__ico:before,
{
content: "\f005";
}
content: "\f005"; — это код активной иконки стар-рейтинга в шрифте Font Awesome. Иконки в этом шрифте вставляются через псевдоэлемент ::before
Третье — при клике на иконку состояние наведения должно сохраниться, то-есть активными должны быть текущая и соседние звездочки.
Добавляем к этому же правилу еще один селектор:
.star-rating__input:checked ~ .star-rating__ico:before
В результате главные стили, которые делают основную работу следующие:
.star-rating__input{
display: none;
}
.star-rating__ico:hover:before,
.star-rating__ico:hover ~ .star-rating__ico:before,
.star-rating__input:checked ~ .star-rating__ico:before
{
content: "\f005";
}
Дальше нужно перевернуть звездочки в другую сторону, так как сестринский селектор выбирает соседей по направлению текста. По умолчанию слева-направо, а нам нужно наоборот.
Для решения этой задачи есть два способа: изменить направления текста для элемента star-rating указав direction: rtl или сделать элемент плавающим по правой стороне. Мне больше по душе второй вариант. Кроме этого сделав элементы внутри .star-rating плавающими мы уберем отступы между звездочками из-за которых пропадает наведение
В общем, дальше уже все обычно. Еще раз ссылка на результат codepen.
В результате у нас полноценный стар-рейтинг со шрифтовыми иконками, написанный только на HTML+СSS в котором легко изменять размеры и цвет звездочек.
jemali_m
Неплохо конечно же, но вы просто слегка изменили решение от Криса Койера на который ссылается сам автор Font Awesome на этой странице.
А вот что касается отдельного подключения целой таблицы стилей со шрифтом Font Awesome, то это реально громоздко. можно было просто обойтись одной или двумя иконками звездочек.
Что-то вроде этого:
KaLGaN
Проще использовать свой шрифт, сделанный на сервисах типа fontello.com
А вообще, автор поста не открыл Америки. Решение известное и довольно прикольное.
Kepler-22b Автор
Спасибо за ссылки, решение на Font Awesom не видел. В отрыве от контекста для такой задачи грузить весь Font Awesom, конечно, накладно. Но как я замечаю эта библиотека шрифтов очень часто итак подключена на многих проектах. В Криса Койера не нравиться использование direction rtl, мне кажется с float лучше. Кроме того я максимально изолировал блок рейтинга, что-бы просто скопипастить код и вставить в любое место на сайте.
jemali_m
Вообще, само решение Койера уже давно морально устарело, и реализация через direction rtl является для многих спорным вариантом.
Ohar
Нет никакого «всего Font Awesome».
Вы выбираете из него нужные глифы и скачиваете их. Я обычно ставлю 3–10 глоифов на проект, больше не пригождается.
Aiki
А зачем label-ы? И hover-ы можно обыграть интереснее: codepen.
Serator
Псевдо-элементы на элементах с заменяемым содержимым противоречат спецификации и то, что это поддерживает Webkit / Blink вовсе не означает, что так всегда и будет.
code.google.com/p/chromium/issues/detail?id=480891
bugzilla.mozilla.org/show_bug.cgi?id=1157575
Kepler-22b Автор
Да, согласен. Странно, как такое решение работает. Псевдоэлементы before и after нельзя добавлять к одиночным тегам, так как в них нельзя ничего вложить. Хром как-то осилил, Firefox и IE10 в ауте.
Serator
Если интересно, то вот тест возможности использования псевдо-элементов в различных элементах: red-team-design.com/wp-content/uploads/2012/06/generated-content-on-replaced-elements-test.html.
Kepler-22b Автор
Спасибо! Посмотрел исходник в хроме, офигел. В DOM браузер открыл input, вставил туда псевдоэлемент и закрыл — prntscr.com/7tis4r Это жесть какая-то. Не знаю, что именно меня тревожит, но это уже слишком.
Ohar
Спасибо, очень интересно.
Не знал, что Blink настолько сошёл с ума.
«Где логика? Где разум?» © известный анекдот.
TNK
К одиночным можно, нельзя к заменяемым (replaced). Факт 11 отсюда: www.sitepoint.com/12-little-known-css-facts-the-sequel
Aiki
Видимо создателям спецификации ничего не говорят такие вещи, как AJAX, DHTML, contenteditable в конце концов. В современном вебе у любого элемента может замениться содержимое, у некоторых это происходит чаше, чем у иного input-а. По этой логике следует отказаться от псевдоэлементов вообще.
Kepler-22b Автор
Тут дело даже не в спецификации, а в логике. Суть псевдоэлементов в том, что они добавляют виртуальный элемент первым или последним ребенком. В одиночного элемента нету понятий закрывающий и открывающий тег и контент внутри, как, в принципе, там может оказаться другой элемент?
max_rip
Ну не правильно это как-то считать с конца)
Лучше как положено с 1 до 5 codepen.io/anon/pen/mJjEMj
Конечно звездочки немного прыгают, но это скорее всего из-за самого шрифта. Если их подогнать под целые значения и сделать свой шрифт, то все должно стать супер)
savostin
А зачем FontAwesome, когда есть ? и ??
Ohar
К сожалению, они довольно криво рендерятся разными браузерными движками.
![](https://habrastorage.org/files/ce4/17f/1a1/ce417f1a19d54ff689ccfd0cf13546d9.png)
Ohar
Ну или не подходят по дизайну.
cmdr
Как-то странно, что если одна из звезд чекнута, то ховер срабатывает только на тех, что после нее, а предыдущие как будто дизейблятся. Не думаю, что это ожидаемое поведение.
Kudja
В этом случае иммхо лучше иметь состояния с разными цветами на чекнутый и на ховер