Создание фиксированного 5-ти кругового рейтинга с использованием CSS/HTML
Я пытаюсь создать 5-балльную рейтинговую систему, используя только CSS и HTML (см. Изображение ниже, чтобы увидеть, как я хотел бы выглядеть), но я не уверен, как этого добиться.
Моя первоначальная идея состояла в том, чтобы сделать 5 кругов и затем каким-то образом использовать их в качестве маски для цвета фона, который является полной шириной всех 5 кругов. Таким образом, первое изображение имеет ширину 90% с цветом фона #4a494a
в то время как второе изображение имеет ширину 60% и снова, цвет фона #4a494a
,
Эти круги зафиксированы, поэтому не нужно никакого взаимодействия, чтобы их закрасить.
У кого-нибудь есть идеи, как мне это сделать?
5 ответов
Вы можете сделать это с помощью псевдоэлемента (.rating:after
), который расположен на вершине div.rating
, .rating
имеет linear-gradient
чья background-size
определяет, сколько круга заполнено и в .rating:after
E сть radial-gradient
который производит пять кругов, которые действуют как маски).
Я использовал анимацию, чтобы показать, как круг заполняется как background-size
увеличивается. Вы можете установить необходимые background-size
используя JS (или любой внутренний код, который генерирует элемент рейтинга), а затем добавьте его с помощью встроенных стилей в div.rating
,
Используя этот подход, даже между рейтингами (или рейтингами любого значения, такими как 3,65, 2,25, 1,85 и т. Д.) Можно легко справиться, просто рассчитав требуемый background-size
, Я добавил несколько образцов в демо.
.rating {
position: relative;
height: 50px;
width: 250px;
background: linear-gradient(to right, black, black);
background-repeat: no-repeat;
background-position: 0px 0px;
background-size: 0px 100%;
}
.rating.auto-anim {
animation: fill-circle 5s ease infinite;
}
.rating:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
background: radial-gradient(20px at center, transparent 7.5px, beige 9px);
background-position: 0px 0px;
background-size: 50px 100%;
border: 1px solid;
}
@keyframes fill-circle {
to {
background-size: 100% 100%;
}
}
<div class='rating auto-anim'></div>
<div class='rating' style="background-size: 50px 100%;"></div> <!-- rating of 1 -->
<div class='rating' style="background-size: 75px 100%;"></div> <!-- rating of 1.5 -->
<div class='rating' style="background-size: 121.25px 100%;"></div> <!-- rating of 2.25 -->
<div class='rating' style="background-size: 228.75px 100%;"></div> <!-- rating of 4.75 -->
<div class='rating' style="background-size: 177.25px 100%;"></div> <!-- rating of 3.65 -->
<div class='rating' style="background-size: 80.25px 100%;"></div> <!-- rating of 1.85 -->
<!--
Background Size Calculation Logic: Each circle is only 15px wide with 17.5px gap on either side
1 rating = 50px (for 1 circle)
1.5 rating = 50px (for 1 circle) + 17.5px (gap before 2nd circle on left) + 7.5px (.5 of 15px circle)
2.25 rating = 100px (for 2 circles) + 17.5px (gap before 3rd circle on left) + 3.75px (.25 of 15px circle)
4.75 rating = 200px (for 4 circles) + 17.5px (gap before 5th circle on left) + 11.25px (.75 of 20px circle)
3.65 rating = 150px (for 3 circles) + 17.5px (gap before 4th circle on left) + 9.75px (.65 of 20px circle)
1.85 rating = 50px (for 1 circle) + 17.5px (gap before 2nd circle on left) + 12.75px (.85 of 20px circle)
-->
Это можно выполнить с помощью небольшого и простого количества CSS, чтобы создать необходимый эффект.
.rating {
direction: rtl;
text-align: center;
}
.rating > span {
display: inline-block;
position: relative;
box-sizing: border-box;
width: 20px;
height: 20px;
border: 1px solid black;
border-radius: 10px;
}
.rating > span:hover,
.rating > span:hover ~ span {
background: transparent;
}
.rating > span:hover:before,
.rating > span:hover ~ span:before {
content: "";
position: absolute;
left: -2px;
top: -2px;
background: gold;
width: 20px;
height: 20px;
border: 1px solid gold;
border-radius: 20px;
}
<div class="rating">
<span></span><span></span><span></span><span></span><span></span>
</div>
Это вариант Star Ratings
разработанный css-tricks.com. Нажми сюда, чтобы прочитать больше!
Если вы используете некоторые умные CSS вместе с некоторыми radio
входы вы можете достичь этого с чистым CSS и HTML, даже сохраняя его интерактивным. Посмотрите на скрипку, которую я настроил: https://jsfiddle.net/2rs79wsh/
#ratings {
font-size: 0;
}
#ratings * {
float: right;
}
#ratings input {
display: none;
}
#ratings label {
width: 20px;
height: 40px;
background-color: #ccc;
display: inline-block;
}
#ratings label:nth-of-type(even) {
border-top-left-radius: 20px;
border-bottom-left-radius: 20px;
margin-left: 10px;
}
#ratings label:nth-of-type(odd) {
border-top-right-radius: 20px;
border-bottom-right-radius: 20px;
margin-right: 10px;
}
#ratings input:checked ~ label {
background-color: red;
}
<div id="ratings">
<input type="radio" id="rating-10" name="rating" value="10">
<label for="rating-10"></label>
...
<input type="radio" id="rating-1" name="rating" value="1" checked=checked>
<label for="rating-1"></label>
</div>
Круги, которые вы видите, являются метками для входных данных. Порядок обратный (с помощью float right), так что вы можете использовать ~
селектор, чтобы показать состояние всех братьев и сестер, следующих за проверенным. Радиоприемники предназначены для хранения состояния и даже должны позволять вам отправлять любые изменения обратно, отправляя их в форму. Каждый круг состоит из двух меток, поэтому в зависимости от того, на какую половину круга вы щелкнете, вы получите различную оценку. odd
/ even
селекторы сдвигают две половинки вместе на две, чтобы они выглядели как один круг.
Не стесняйтесь спрашивать, если что-то неясно!
Вы можете сделать это довольно легко с помощью элементов psuedo:HTML
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li class="half"></li>
</ul>
CSS
ul {
display:block;
}
li {
display:inline-block;
list-style: none;
width:20px;
height:20px;
border-radius:50%;
background-color:orange;
overflow:hidden;
position:relative;
}
li::after {
position:absolute;
content: '';
background-color:rgba(0,0,0,.5);
display:block;
width:20px;
height:20px;
top:0;
left:0;
}
li.half::after {
left:-10px;
}
Скрипка https://jsfiddle.net/fz2qo82m/
Вы просто измените класс на последнем круге (или на последней паре, вы можете добавить none
класс если рейтинг ниже 4 кружков)