Half font awesome heart rating css - html

I'm generating a rating system using font-awesome fa-heart class. It is working fine by colouring the full heart, but I'm in trouble when trying to fill it in red only the first half of the heart.
I have been searching but always are stars and not a half-heart, always full heart and not from font-awesome.
Font awesome version used 4.0.3 and cannot be changed...
Any trick to do that?
.full {
color:red;
}
.half {
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.min.css">
<div class="rating-love ">
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart half"></span>
<span>23 Review(s)</span>
</div>

Here is another idea where you can easily have any kind of rating by simply adjusting a CSS variable:
.rating-love {
display: inline-grid!important;
}
.rating-love:before,
.rating-love:after {
content: "\f004 \f004 \f004 \f004 \f004";
grid-area: 1/1;
}
.rating-love:after {
white-space: nowrap;
overflow: hidden;
width: var(--w);
color: red;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.min.css">
<div class="rating-love fa" style="--w: 50%;"></div>
<br>
<div class="rating-love fa" style="--w: 30%;"></div>
<br>
<div class="rating-love fa" style="--w: 80%;"></div>

This can be done using text Clip & Background Gradient, I hope this trick will work for you too.
I just made a gradient with 2 colors and divided them with clip its looking fine. You can make half of the heart white if you want just by changing the hexcode in css.
.fa-heart.half:before {
background: -webkit-linear-gradient(180deg,#000 0%, #000 50%,#FF0000 50%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.full {
color:red;
}
.half {
}
.fa-heart.half:before {
background: -webkit-linear-gradient(180deg,#000 0%, #000 50%,#FF0000 50%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.min.css">
<div class="rating-love ">
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart half"></span>
<span>23 Review(s)</span>
</div>

Without using JavaScript you'd cut the width of the span to half, hiding the overflow.
.full {
color: red;
vertical-align:text-bottom;
}
.half {
color: red;
width: 8px;
overflow: hidden;
vertical-align:text-bottom;
margin-right: 8px;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.min.css">
<div class="rating-love ">
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart full"></span>
<span class="fa fa-heart half"></span>
<span>23 Review(s)</span>
</div>

Related

How to crop an element and keep the size adjusted

I have an element which I would like to crop x% of it from the right, and so the width will automatically decrease by half to fit the new content.
Currently I'm using this:
div{
display:flex;
justify-content: space-evenly;
width:180px;
}
i{
color: yellow;
}
span i{
position:relative;
left: 50%;
}
span{
overflow: hidden;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<span>
<i class="fas fa-2x fa-star"></i>
</span>
</div>
But as you can see when using it the span keeps it's original width and doesn't crop
Or using clip-path
so it creates an extra gap between the half star and the solid star before/after it.
I have tried using transform: translateX(-x%); on the container but it sabotages the entire layout and every element positioned after it gets a x% offset.
Is there a way to crop the element and so it's size?
NOTE: the real element size is dynamic. I prefer a pure css solution that doesn't evolve using constants /JS
Thanks
edit, after understanding the question, you may use width + overflow
If it is dynamic and can show up many times, you may use var() to update the value on the fly
examples
Why do i use em for sizing ? - because its size is about its own font-size : here : fa-2x in your question , which em will match even if the class turns to be fa-4x .
div{
display:flex;
justify-content: space-evenly;
width:180px;
margin:1em;
filter:drop-shadow(0 0 3px)
}
i{
color: yellow;
}
div i:last-of-type{
width: var(--size);
overflow:hidden;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div style="--size: calc(1em * 0.3)">
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>30%
</div>
<div style="--size: calc(1em * 0.6)">
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>60%
</div>
<div style="--size: calc(1em * 0.7)">
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>70%
</div>
You may use clip-path, it will allow you to cut off a portion of the element . % can be used .
It also can allow you to cut it off with different shapes .
This will help you create your first clip-path https://bennettfeely.com/clippy/
specification https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path
examples
div{
display:flex;
justify-content: space-evenly;
width:180px;
margin:1em;
filter:drop-shadow(0 0 3px)
}
i{
color: yellow;
}
div i:last-of-type{
clip-path: polygon(0 0, 60% 0, 60% 100%, 0% 100%);
}
/*cut half of its surface , but differently*/
[title] i:last-of-type{
clip-path: polygon(0 40%, 100% 40%, 100% 100%, 0% 100%);
}
[class] i:last-of-type{
clip-path: polygon(0 0, 100% 0, 0 100%, 0% 100%);
}
[id] i:last-of-type{
clip-path: polygon(0 0, 100% 0, 0 100%, 100% 100%);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>60%
</div>
<div title="2.6">
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>60%
</div>
<div class>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>50%
</div>
<div id >
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>50%
</div>
You should specify the width of each star, which is 36px in this case. Then you can just set the width to 16px for the last star and add overflow hidden.
div{
display:flex;
justify-content: space-evenly;
width:180px;
}
i{
color: yellow;
width: 36px;
}
.half-star {
overflow: hidden;
width: 16px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star half-star"></i>
</div>
You can use the clip property and just for example do that
clip: rect(0px,60px,200px,0px); it should split it in half
Use fa-star-half as an alternative to custom styles. This will ensure dynamicity.
div {
display: flex;
justify-content: space-evenly;
width: 180px;
}
i {
color: yellow;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star-half"></i>
</div>
Solution w/o fa-star-half.
I called your custom span with the customs styles .custom. This solution requires removing justify-content: space-evenly and uses a calculated width on your span's that are not custom.
However, you still want the .custom span to be factored into this width. So you can set something like span:not(.custom) { width: calc(100% / 3); } Then, you will want to set text-align: center; to the non custom spans's also.
div {
display: flex;
width: 180px;
}
i {
color: yellow;
}
span.custom i {
position: relative;
left: 50%;
}
span.custom {
overflow: hidden;
}
span:not(.custom) {
width: calc(100% / 3);
text-align: center;
}
span {
outline: black 1px dotted;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<span>
<i class="fas fa-2x fa-star"></i>
</span>
<span>
<i class="fas fa-2x fa-star"></i>
</span>
<span class="custom">
<i class="fas fa-2x fa-star"></i>
</span>
</div>
If you're looking to make the star half, you could use <i class="fa fa-star-half-o" aria-hidden="true"></i> instead of trying to crop it in half and then fit to the content.
Please let me know if I have misunderstood your question.
EDIT:
I would make a parent container for each star that is responsible for the width and height, and let the child base its width on the preferred percentage.
.star-row {
display: flex;
gap: 5px;
}
i {
color: yellow;
overflow: hidden;
}
.last-star {
width: 50%;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div class="star-row">
<div class="star-container">
<i class="fas fa-2x fa-star"></i>
</div>
<div class="star-container">
<i class="fas fa-2x fa-star last-star"></i>
</div>
</div>
I cropped the stars using a span outside (and I replaced the div with span).
span{
display:flex;
justify-content: space-evenly;
overflow: hidden;
width: 95px;
}
i{
color: gold;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<span>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star" style="width:calc(36px / 2);"></i>
</span>
it's simple you just need to use negative for margin element.
margin-right:-18px;
div{
display:flex;
justify-content: space-evenly;
width:180px;
}
i{
color: yellow;
}
span i{
margin-right:-18px;
}
span{
background:red;
overflow: hidden;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<span>
<i class="fas fa-2x fa-star"></i>
</span>
</div>
Using clip-path can be a practical solution for this case.
It's not size dependent, and you can use any value between 0-100% for the --percentage variable.
div{
display:flex;
justify-content: space-evenly;
width:180px;
}
i{
color: yellow;
}
i:last-child{
--percentage: 50%;
clip-path: polygon(0 0, var(--percentage) 0, var(--percentage) 100%, 0 100%);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
</span>
</div>
If the last star bounding box is a concern, you should be able to achieve that by providing a width like this.
div{
display:flex;
justify-content: space-evenly;
width: 180px;
--star-count: 5;
--star-width: calc(100% / var(--star-count));
--last-star-crop: 1/2;
}
i{
width: var(--star-width);
color: yellow;
}
i:last-child{
width: calc(var(--star-width) * var(--last-star-crop));
overflow: hidden;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.1/css/all.min.css">
<div>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
<i class="fas fa-2x fa-star"></i>
</span>
</div>
Note: FontAwesome uses font-size to dictate icon sizing, due to that smaller container widths can cause distortion.

How to get text displayed below font awesome icon?

I have this html below where I am using font awesome icons. What I would like is the for text for each icon (in the example below joinery and plumbing to appear below it's relevant font awesome icon). At the moment the text is display to the right of the icon half way up.
<div class="icons">
<span class="fa-stack fa-4x">
<i class="far fa-circle fa-stack-2x icon-background"></i>
<i class="fa fa-hammer fa-stack-1x"></i>
</span>
<span class="icons-text">Joinery</span>
<span class="fa-stack fa-4x">
<i class="far fa-circle fa-stack-2x icon-background"></i>
<i class="fa fa-wrench fa-stack-1x"></i>
</span>
<span class="icons-text">Plumbing</span>
</div>
.icon-background {
color: #000000;
}
.icons{
text-align:center;
}
.icons-text{
color:#000000;
font-size:10px;
padding:5px 0 10px 0;
text-transform:uppercase;
letter-spacing:1px;
}
I tried including display:block within icon.text and this does add the text below the icon, but what is also does it stack the icons vertically and not keeping them next to each other horizontally.
There are several ways of doing this, depending on exactly what is required. One is to make the spans into divs, then the browser automatically stacks the text below the icon, but to make this icon/text stay on the same line as the next one, wrap each set in a div - I've given it the class 'trade' - and float that.
.icon-background {
color: #000000;
}
.icons{
text-align:center;
}
.icons-text{
color:#000000;
font-size:10px;
padding:5px 0 10px 0;
text-transform:uppercase;
letter-spacing:1px;
}
div.trade {
float:left;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css" crossorigin="anonymous" />
<div class="icons">
<div class="trade">
<div class="fa-stack fa-4x">
<i class="far fa-circle fa-stack-2x icon-background"></i>
<i class="fa fa-hammer fa-stack-1x"></i>
</div>
<div class="icons-text">Joinery</div>
</div>
<div class="trade">
<div class="fa-stack fa-4x">
<i class="far fa-circle fa-stack-2x icon-background"></i>
<i class="fa fa-wrench fa-stack-1x"></i>
</div>
<div class="icons-text">Plumbing</div>
<div>
</div>
There is a cleaner way to do it, if you'd like:
.icons .fa {
display: inline-block;
padding: 0 0 10px;
color: #000;
font-size: 10px;
text-align: center;
text-transform: uppercase;
letter-spacing: 1px;
}
.icons .fa:before {
display: block;
width: 1.5em; height: 1.5em;
margin: 0 auto 5px;
border: solid .2em; border-radius: 55%;
font-size: 6.4em;
line-height: 1.5em;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css" rel="stylesheet" />
<div class="icons">
<span class="fa fa-hammer">Joinery</span>
<span class="fa fa-wrench">Plumbing</span>
</div>

How to change the inner white color of Font Awesome's exclamation triangle icon?

How to change the inner (white) color of the icon
<i class="fa fa-exclamation-triangle"></i>?
P.S. Applying <i class="fa fa-exclamation-triangle" style="color:red"></i> is not an answer, as the red color applies to the outer color, not to the inner exclamation white sign itself.
The Font Awesome version is: 4.7.0.
The exclamation mark of this icon is a transparent part, so a trick is to add a background behind it to have the needed coloration. Of couse, the background shouldn't cover the whole area so we need to use a gradient to cover only a part of it.
.fa-exclamation-triangle {
background:linear-gradient(red,red) center bottom/20% 84% no-repeat;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css">
<i class="fas fa-exclamation-triangle fa-7x"></i>
<i class="fas fa-exclamation-triangle fa-4x"></i>
<i class="fas fa-exclamation-triangle fa-2x"></i>
The same thing with the V4:
.fa-exclamation-triangle {
background:linear-gradient(red,red) center /20% 70% no-repeat;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<i class="fa fa-exclamation-triangle fa-5x"></i>
<i class="fa fa-exclamation-triangle fa-4x"></i>
<i class="fa fa-exclamation-triangle fa-2x"></i>
Also the SVG version:
.fa-exclamation-triangle {
background:linear-gradient(red,red) center bottom/20% 84% no-repeat;
}
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js" ></script>
<i class="fas fa-exclamation-triangle fa-7x"></i>
<i class="fas fa-exclamation-triangle fa-4x"></i>
<i class="fas fa-exclamation-triangle fa-2x"></i>
UPDATE
To make the answer more generic we can also consider multiple background and radial-gradient in order to color any kind of shape. The trick is to cover with the background the transparent part without overflowing.
Here is some example of icons:
.fa-exclamation-triangle {
background:linear-gradient(red,red) center bottom/20% 84% no-repeat;
}
.fa-ambulance {
background:
linear-gradient(blue,blue) 25% 30%/32% 45% no-repeat,
radial-gradient(green 60%,transparent 60%) 15% 100%/30% 30% no-repeat,
radial-gradient(green 60%,transparent 60%) 85% 100%/30% 30% no-repeat;
}
.fa-check-circle {
background:radial-gradient(yellow 60%,transparent 60%);
}
.fa-angry {
background:
radial-gradient(red 60%,transparent 60%) 25% 40%/30% 30% no-repeat,
radial-gradient(red 60%,transparent 60%) 75% 40%/30% 30% no-repeat;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css">
<i class="fas fa-exclamation-triangle fa-7x"></i>
<i class="fas fa-ambulance fa-7x"></i>
<i class="fas fa-check-circle fa-7x"></i>
<i class="fas fa-angry fa-7x"></i>
The answer of Temani Afif is a good one! Here's another approach;
.fa-exclamation-triangle{
position: relative;
z-index:0;
}
.fa-exclamation-triangle:after{
content: ' ';
width: 20%;
height: 70%;
position: absolute;
top: 15%;
left: 40%;
background: red;
z-index: -1;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<i class="fa fa-exclamation-triangle fa-5x"></i>
<i class="fa fa-exclamation-triangle fa-4x"></i>
<i class="fa fa-exclamation-triangle fa-2x"></i>

Div background color

I'm having a hell of a time trying to get a background color to show on a div. I have tried specifying width, height, overflow, etc. with no luck. The code is below. I can get inner div background to change, but not the containing div.
The div in question is header-top-container. Any help is greatly appreciated.
.header-top-container {
background: #F0F0F0;
overflow: hidden;
}
.header-top-container>.main-container {
padding-top: 0;
padding-bottom: 0;
display: flex;
}
.main-container {
position: relative;
max-width: 1260px;
margin: 0 auto;
padding: 15px;
}
body .header-top-container .external-store-tab {
width: 360px;
}
body .header-top-container .external-store-tab,
body .header-top-container .account-cart-wrapper {
position: relative;
width: 70%;
}
<div class="header-top-container">
<div class="main-container header-main-container">
<div class="external-store-tab">
<div class="tab-item">
<a href="https://www.example.org">
<img src="https://www.example.org/logo-foundation.png" class="tab-logo">
</a>
</div>
<div class="tab-item active">
<a href="http://store.example.org/">
<img src="https://www.example.org/logo-store.png" class="tab-logo">
</a>
</div>
</div>
<div class="account-cart-wrapper">
<a href="http://www.example.org/contact/" class="account-link hide-mb">
<span class="label" style="color:#008CA8;">
<i class="fa fa-envelope" aria-hidden="true"></i>
<span class="bar-text" tyle="font-family: 'Open Sans',sans-serif;">Contact</span>
</span>
</a>
<a href="tel:800.222.5870" class="account-link">
<span class="label" style="color:#008CA8;">
<i class="fa fa-phone fa-lg" aria-hidden="true"></i>
<span class="bar-text" style="font-family: 'Open Sans',sans-serif;">800.222.5870</span>
</span>
</a>
<a href="https://store.example.org/customer/account/login/" class="skip-link skip-account account-link sign-in-bar">
<span class="label">
<i class="fa fa-user fa-lg" aria-hidden="true"></i>
<span class="bar-text" style="font-family: 'Open Sans',sans-serif;">Sign in</span>
</span>
</a>
<a href="https://store.example.org/checkout/cart/" class="skip-link skip-account account-link">
<span class="label">
<i class="fa fa-shopping-cart fa-lg" aria-hidden="true"></i>
</span>
</a>
</div>
</div>
</div>
Add to class "header-top-container", property "position:inherit" class, like following:
.header-top-container {
background: #F0F0F0;
overflow:hidden;
position: inherit;
}
Your #custom-layer1 has a background that matches the page. Your header-container-top is changing color, but is being 'painted' over so to speak by the background of #custom-layer1.

Vertical Align Text After Font Icon

<div class="col-md-4">
<span class="fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x blue"></i>
<i class="fa fa-wifi fa-stack-1x white"></i>
</span>
<h4 class="blue">Free wifi</h4>
</div>
How can I display h4 element on the right of the icon and vertically aligned? Should I float left the span?
One of the ways would be to use inline-block display and middle align it - see demo below:
.wrapper > * {
display: inline-block;
vertical-align: middle;
}
.blue {
color: blue;
}
.white {
color: white;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<div class="col-md-4 wrapper">
<span class="fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x blue"></i>
<i class="fa fa-wifi fa-stack-1x white"></i>
</span>
<h4 class="blue">Free wifi</h4>
</div>
Use CSS Flexbox. Make a parent <div> that wraps icon and text into it (in my case its icon-holder) and make it a flexbox container using display: flex.
Have a look at the snippet below:
.icon-holder {
display: flex; /* Flex Container */
align-items: center; /* Vertically Align Content */
}
.blue {
color: #33b5e5;
}
span {
color: #fff;
}
h4 {
padding-left: 5px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="col-md-4">
<div class="icon-holder">
<span class="fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x blue"></i>
<i class="fa fa-wifi fa-stack-1x white"></i>
</span>
<h4 class="blue">Free wifi</h4>
</div>
</div>
Hope this helps!
You can use display: flex and can do something like below :
.col-md-4 {
display: flex;
align-items: center;
}
.blue {
color: blue
}
.white {
color: white;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<div class="col-md-4 wrapper">
<span class="fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x blue"></i>
<i class="fa fa-wifi fa-stack-1x white"></i>
</span>
<h4 class="blue">Free wifi</h4>
</div>