Skip to content

Instantly share code, notes, and snippets.

@equinusocio
Last active May 30, 2019 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save equinusocio/980fa5d51c861095e425597ef1550560 to your computer and use it in GitHub Desktop.
Save equinusocio/980fa5d51c861095e425597ef1550560 to your computer and use it in GitHub Desktop.
Pure CSS review indicator (not interactive) based on data attribute and SVG gradient to make the half star.
<svg visually-hidden>
<linearGradient id="half-star" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="50%" stop-color="currentColor" />
<stop offset="50%" stop-color="currentColor" stop-opacity="0.3" />
<stop offset="100%" stop-color="currentColor" stop-opacity="0.3" />
</linearGradient>
</svg>
<div class="ReviewIndicator" data-value="3.5">
<svg width="32" height="32" role="img" viewBox="0 0 24 24">
<path d="M10 0l2.609 6.957H20l-6.087 5.217L16.522 20 10 15.217 3.478 20l2.609-7.826L0 6.957h7.391L10 0z" />
</svg>
<svg width="32" height="32" role="img" viewBox="0 0 24 24">
<path d="M10 0l2.609 6.957H20l-6.087 5.217L16.522 20 10 15.217 3.478 20l2.609-7.826L0 6.957h7.391L10 0z" />
</svg>
<svg width="32" height="32" role="img" viewBox="0 0 24 24">
<path d="M10 0l2.609 6.957H20l-6.087 5.217L16.522 20 10 15.217 3.478 20l2.609-7.826L0 6.957h7.391L10 0z" />
</svg>
<svg width="32" height="32" role="img" viewBox="0 0 24 24">
<path d="M10 0l2.609 6.957H20l-6.087 5.217L16.522 20 10 15.217 3.478 20l2.609-7.826L0 6.957h7.391L10 0z" />
</svg>
<svg width="32" height="32" role="img" viewBox="0 0 24 24">
<path d="M10 0l2.609 6.957H20l-6.087 5.217L16.522 20 10 15.217 3.478 20l2.609-7.826L0 6.957h7.391L10 0z" />
</svg>
</div>
$i: 5;
$halfstar-style: url(#half-star) currentColor;
$dimmed-star-opacity: 0.3;
.ReviewIndicator {
display: inline-flex;
/**
* Set consecutive icons spacing
*/
svg + svg {
margin-left: 10px;
}
/**
* Generate half-star style using a svg gradient
* to fill the full star icon, based on the review value
* defined inside the [data-value] attribute
*/
@while $i >= 0 {
/**
* If he value is less than 1 (0 or 0.5) change the dimmed
* behaviour to force the first icon to be NOT dimmed
*/
@if $i < 1 {
@if $i == 0.5 {
&[data-value='#{$i}'] > svg:nth-child(n + #{floor($i) + 2}) {
opacity: $dimmed-star-opacity;
}
&[data-value='#{$i}'] > svg:nth-child(1) {
fill: $halfstar-style;
}
} @else {
&[data-value='#{$i}'] > svg {
opacity: $dimmed-star-opacity;
}
}
/**
* If the value is 1 or greather, check if the next star should have
* the half-style and dimm the stars starting from $i + 2
* value: 2.5 --> (⭑⭑ = $i = 2) + (⭑-half = $i + 1) + (⭒⭒ = $i + 2∞)
*/
}
@else {
@if not call(get-function("is-integer"), $i) {
&[data-value='#{$i}'] > svg:nth-child(#{floor($i)}) + svg {
fill: $halfstar-style;
}
&[data-value='#{$i}'] > svg:nth-child(n + #{floor($i) + 2}) {
opacity: $dimmed-star-opacity;
}
}
@else {
&[data-value='#{$i}'] > svg:nth-child(n + #{floor($i) + 1}) {
opacity: $dimmed-star-opacity;
}
}
}
$i: $i - 0.5;
}
}
/**
* Check if $value is a number
*/
@function is-number($value) {
@return type-of($value) == 'number';
}
/**
* Check if $value number is an integer or not
*/
@function is-integer($value) {
@return is-number($value) and round($value) == $value;
}
[visually-hidden] {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment