A guide to filling an irregular shape (such as a star) based on a percentage using CSS in a React project

I am currently working on developing a React component that showcases a rating percentage using a star icon with two different shades.

For example, if the input rating is 79%, I want to display a star with 79% of it in gold color and the remaining 21% in grey.

At this point, I have managed to place two separate stars from the Font Awesome library in the same location (one in gold and one in grey).

You can find my code in this sandbox and below:

import React from 'react';
import { FaStar } from "react-icons/fa";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
    starFill: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 1
    },
    starContainer: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 2
    }
}));

const StarRating = (percentRating) => {

    const classes = useStyles();
    
    console.log(percentRating);

    return (
        <React.Fragment>
            <div className={classes.starFill}>
                <FaStar color='#ffc107' size={200} />
            </div>
            <div className={classes.starContainer}>
                <FaStar color='#e4e5e9' size={200} />
            </div>
        </React.Fragment>
    )
}

export default StarRating;

Answer №1

After some experimentation, I successfully achieved my objective by adjusting the star's zIndexes and modifying its width to a percentage while adding overflow:hidden to the style.

You can view my sandbox here and find the code below:

import React from 'react';
import { FaStar } from "react-icons/fa";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
    starFill: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 2,
    },
    starContainer: {
        cursor: 'pointer',
        transition: 'color 200ms',
        position: 'absolute',
        top: '25%',
        left: '50%',
        transform: 'translate(-50%, -75%)',
        zIndex: 1,
    }
}));

const StarRating = ({ rating = 100, size = 200, ...props }) => {

    const classes = useStyles();

    rating = (rating / 100) * size;

    return (
        <React.Fragment>
            <div className={classes.starFill}>
                <div style={{ width: rating, overflow: 'hidden' }}>
                    <FaStar color='#ffc107' size={size} />
                </div>
                {/* transparent div to reserve the complementary spacing */}
                <div style={{ width: size }}>
                </div>
            </div>
            <div className={classes.starContainer}>
                <FaStar color='#e4e5e9' size={size} />
            </div>
        </React.Fragment>
    )
}

export default StarRating;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Introduction to React with Typescript: Greeting the World

I am attempting to create a Hello World React application with Typescript. Below is the code I have written. Method 1 works without any issues, but method 2 throws an error. Method 1 - TypeScriptComponent.tsx import React from 'react' import Re ...

Troubleshooting Div Element Width in CSS Not Functioning

When working on a form design, I encountered an issue where the text labels were not aligning to the same width. Despite setting the width, it didn't seem to work as expected: .form-label { display:inline; width: 160px; } <div class="form-label ...

CSS/jQuery animation alignment problem

Exploring an animation using CSS transitions and jQuery has been my recent project. The concept involves presenting the user with clickable divs to load a new page. When a div is clicked, it expands to cover the entire screen and transition to the next pag ...

Reset the text input field when the dropdown menu is set to 'no/other'

CURRENT: Choosing from a dropdown menu with options 'Yes' or 'No'. If 'Yes' is chosen: Display additional dropdowns/inputs for entry If 'No' is chosen: Conceal additional dropdowns/inputs WANT: I am looking to imp ...

Every time I try to create a new React app, I consistently run into the same error

I keep encountering this error every time I try to create a React app using create-react-app. ...

What is the best approach for generating individual variables for every row in a React table?

Presently, I am developing a dynamic table using react and the structure is as follows: <TableBody> {finalLoadedTokensData.map((loadedToken, index) => { const isItemSelected = isSelected(loadedToken.contract); const label ...

Encountering an error message stating "The variable 'App' is declared but not used" when running the index.tsx function

This React project is my attempt to learn how to use a modal window. The tutorial I've been following on YouTube uses JavaScript instead of TypeScript for their React project. However, I'm facing some challenges. Could you possibly help me ident ...

Ensure that the nested div maintains its height consistently across all three columns

In my layout, I am trying to achieve uniform height for three columns, each containing the same sections like title and address. Not only do I want the cards to have the same height, but also the nested sections should maintain equal heights. For instance, ...

What is the best way to display an image and text side by side within a single row in react-table?

I am trying to display an image and text side by side within a single column in a React table. I have successfully added two texts together in a single column using the code below: Header: "Name", id: "User", accessor: (d) => ...

The angular view is lacking a CSS class

index.html: <div ng-view="myview.html"></div> myview.html: <table class="table table-striped table-hover"> <tr> <td>Name</td> <td>Product</td> </tr> <tr ng-repeat="deal in deals" class="clickableR ...

What is the best way to superimpose an image onto a canvas?

I am working on a cool project where I have created a canvas that displays matrix binary code raining down. However, I would like to enhance it by adding an image overlay on top of the canvas. Here is my current setup: <div class="rain"> ...

Is there a way to update a todo list on the same input field where I initially added it in a React application?

I am new to using React js and currently working on a project that I found on YouTube. The issue I am facing is related to editing tasks - I would like to be able to edit them within the same input field where I add tasks. Unfortunately, I am not sure how ...

Unraveling the mystery: Retrieving event.target.value in a React component

Having trouble accessing the event.target.value from a React child Component, but not an HTML tag? In this scenario: the Button tag (React Component) cannot access event.target.value, while the button tag (HTML tag) can. import React from "react"; impor ...

Creating engaging animations for variable content in Safari using CSS

This multi-step wizard is designed to smoothly transition between its 3 steps. Upon clicking the "next" button in step 1, the content is pushed down to reveal step 2. Similarly, when advancing from step 2 to step 3, the contents of both previous steps are ...

The React Redux state has been modified, but the changes are not reflecting in the component's UI

const mapStateToProperties = state => { return { items: state.tabItems }; }; class Application extends Component { render() { return ( <div> <Layout> <Route path="/:item" component={ItemsPag ...

Styling Fonts in Safari with CSS

Because FixedSys doesn't appear correctly in Chrome or Safari, I switch it to Lucida Console. While this solution works for Chrome, I encounter a problem with Safari. Unless Lucida Console stands alone, the font will not display as desired. If there a ...

React function causing website to freeze upon dispatch

I created a function in the child component to handle checkbox selection and trigger setDispatch(true). Unfortunately, whenever I check the checkbox, the website freezes and stops responding until I close and reopen it. Here is the function: const [ ...

Tips for correctly cloning a create-react-app repository and compiling it (with existing error) - (Git)

After developing on a different server, I am now looking to move my project to the live server. On the live server, I initiated the create react app using: create-react-app test Then, I navigated into the project and initialized it with git: cd test gi ...

Material Design Angular2 Toolbar

I am currently working on designing a toolbar using Material and Angular2. My main challenge is formatting the toolbar in such a way that the search bar appears centered in white, while the "Create Project" button and other buttons are aligned to the right ...

Troubleshooting issue of incorporating hintText in a TextField within a create-react-app-with-typescript

After recently downloading, installing, and running the create-react-app-with-typescript, I have been exploring different components. My latest experiment involved adding a TextField with hintText using the following code: import TextField from 'mate ...