Aligning the stars with CSS

One of the components I have deals with a star rating system, and I thought it would be cool to use Font Awesome icons for half stars. Everything is working well except for the CSS styling aspect. While I managed to position some of the stars correctly by flipping them (Font Awesome icons can only span in one direction), they are not touching as desired. Any suggestions on the most straightforward way to address this issue?

Rater.js

import React, { useState } from 'react'
import {FaStarHalf} from "react-icons/all";
import './Rater.css'


const Rater = () => {
    const [rating, setRating] = useState(null);
    const [hover, setHover] = useState(null);
    const [value] = useState(100);
    const [iconValue, setIconValue] = useState(5);

    return (
        <div>
            <select
                onChange={e => {
                    setIconValue(Number(e.target.value));
                }}
            >
                {Array.from(new Array(value), (value, index) => index + 1).map(
                    value => (
                        <option key={value} value={value}>
                            {value}
                        </option>
                    )
                )}
            </select>
            <h1> Select Amount of Icons </h1>

            {[...Array(iconValue), ...Array(iconValue)].map((icon, i) => {
                const value = i + 1;

                return (
                    <label>
                        <input
                            type="radio"
                            name="rating"
                            value={value}
                            onClick={() => setRating(value)}
                        />
                        <FaStarHalf
                            className={i % 2 ? "star-left" : "star"}
                            color={value <= (hover || rating) ? "#ffc107" : "#e4e5e9"}
                            size={100}
                            onMouseEnter={() => setHover(value)}
                            onMouseLeave={() => setHover(null)}
                        />
                    </label>

                );
            })}
        </div>
    );
};

export default Rater

Rater.css

input[type='radio'] {
    display: none;
}

.star {
    cursor: pointer;
    transition: color 200ms;
    /*transform: rotate(180deg);*/
}
.star-left {
    cursor: pointer;
    transition: color 200ms;
    transform: scaleX(-1);
}

Answer №1

If you're looking to neatly align elements, consider using flexbox.

All you need to do is enclose your stars within a container:

<div class="container">
  <div class="star"></div>
  <div class="star"></div>
  <div class="star"></div>
  <div class="star"></div>
  <div class="star"></div>
</div>

Next, apply some flexbox styling to bring it all together:

.container {
  display: flex;
  justify-content: space-between;
  align-items: center;

You have the flexibility to adjust the margin and padding of the stars, along with experimenting with justify-content.

Answer №2

Design a container that is positioned at half the width of the star icon and conceals any overflow. Then, shift the left (technically right) half of the star by half of its width along the x-axis.

The CSS Code

input[type='radio'] {
  display: none;
}

.star-container {
  cursor: pointer;
  display: inline-block;
  height: 2rem;
  width: 1rem;
  overflow: hidden;
}

.star {
  transition: color 200ms;
  height: 2rem;
  width: 2rem;
}

.star-left {
  transform: scaleX(-1) translateX(50%);
}

Star Container Code Snippet

<div className="star-container">
  <FaStarHalf
    className={i % 2 ? "star star-left" : "star"}
    color={value <= (hover || rating) ? "#ffc107" : "#e4e5e9"}
    onMouseEnter={() => setHover(value)}
    onMouseLeave={() => setHover(null)}
  />
</div>

https://i.stack.imgur.com/8vSTJ.png

https://codesandbox.io/s/half-star-rater-styled-63vso?fontsize=14&hidenavigation=1&module=%2Fsrc%2FApp.js&theme=dark

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

Achieving a horizontal alignment of these four div elements containing images

I need some assistance with aligning the divs using the .acontainer class. It was working perfectly before adding the images, but now it's all messed up. I've tried various adjustments and searches online, but I'm still stuck. Thank you for ...

Ways to disable the caching feature in Google Chrome

When I am working on CSS and JS around a page, I need to disable the cache mechanism in Google Chrome browser. A trick is to open Chrome DevTools, which automatically disables the cache mechanism (you can configure this in the settings section). Are ther ...

Decipher encoded parameters utilizing the JavaScript encodeURIComponent method

I'm dealing with an issue in my application where text entered by a user is sent to the server as part of a URL to render an image. The text is encoded using the encodeURIComponent function, but I'm running into problems with certain characters l ...

Is there a way to display a specific dropdown menu depending on the checkbox that is selected?

I have a bunch of checkbox items, including one labeled nocalls, as well as a couple of dropdownlist boxes. Here are the dropdown boxes: <tr> <td align="right"><FONT class="Arial10"><B>Profile<font color="#ff0000">*</ ...

What are the steps to resolve issues with my dropdown menu in IE9?

I have a cool CSS built hover-over drop-down menu that I want to add to my website. It works perfectly on all browsers except for IE9. Here is the code and stylesheet I am using: Check out the code and sheet here If anyone has any insights on what might ...

Encountering Uncaught Promise Rejection Warning in Node.js

I can't figure out why I am receiving this error or warning when my code appears to be correct. Below is a snippet of the UserModel that I have been working on: const fs = require('fs'); class UserModel { constructor(filename) { ...

CSS magic: Text animation letter by letter

I have a <div> with text. <div> to be revealed on the page one character at a time:</p> <div>, the animation should stop and display the full text instantly.</p> In summary, I aim to replicate an effect commonly seen in Jap ...

We are hosting an event focused on DOM text selection outside of Input or TextArea elements

I need help finding a Javascript event that triggers when a user highlights paragraph text with their mouse on a web page. Once the text is highlighted, I want to access it using window.getSelection(). Just to clarify, I am not looking for ways to capture ...

Using AJAX to dynamically edit and update PHP data

The information displayed on my index.php page is fetched from a database using the mysqli_fetch_array function. The data is presented in a table format with fields like Name, Age, Email, and Update. An edit button allows users to modify the data. Here is ...

Stop MatDialog instance from destroying

In my application, I have a button that triggers the opening of a component in MatDialog. This component makes API calls and is destroyed when the MatDialog is closed. However, each time I open the MatDialog for the second time by clicking the button agai ...

Ensuring that a group of items adhere to a specific guideline using JavaScript promises

I need to search through a series of titles that follow the format: <div class='items'> * Some | Text * </div> or <div class='items'> * Some more | Text * </div> There are multiple blocks on the page wit ...

What are the steps to fetch data from Firebase v9 and showcase it on the frontend?

Hello, I have successfully connected a contact form to Firebase and now I need help displaying the data in the browser. Despite trying multiple approaches, I have been unsuccessful so far. The collection for the data is named messages. Below is the code ...

Retrieve a specific column value upon button click in HTML and JavaScript

I am faced with a table containing multiple columns, each row equipped with an edit button. Upon clicking the edit button, a modal view pops up where users can input values that are then sent via AJAX to my controller. The challenge I'm encountering ...

How can you display a personalized modal or error message using React context while incorporating dynamic content?

Can you please help me figure out how to display a custom modal or error message using react context with dynamic content? I attempted it like this: https://codesandbox.io/s/sleepy-wozniak-3be3j import React, { useState } from "react"; import ErrorConte ...

What is the best way to repurpose the vuex module for multiple components?

Currently, I am tackling the pagination aspect of a project that involves handling a large amount of data. My initial instinct was to store this data within Vuex. However, I ended up implementing all the logic in the Vuex store module. Now, my goal is to f ...

Restricting the frequency at which a specific key value is allowed to appear in JSON documents

Within my JSON file, there is an array structured like this: { "commands": [ { "user": "Rusty", "user_id": "83738373", "command_name": "TestCommand", "command_reply": "TestReply" } ] } I have a requirement to restrict the num ...

Is the use of Youtube API with an unaffiliated laborer

What an unusual situation! I've implemented the YouTube JavaScript API to display a playlist on my website, but upon checking how things were operating in my workers, it appears that the API is directing its messages to an unexpected location. The da ...

How can we reduce the use of !important in SCSS when working with React and Material UI?

In my current project, I am developing a Select component in React with Material UI. The CSS styling for the component is managed through an external SCSS sheet imported into the script file. While working on restyling the component, I found it challengin ...

Reply to changes in the window size *prior to* adjusting the layout

Take a look at the "pixel pipeline" concept illustrated with a vibrant diagram on this page. I am currently working on resizing an element (let's say, a span) dynamically when the browser window is resized. I have implemented this using window.onresi ...

Tips on successfully transferring row data that has been clicked or selected from one adjacent table to another table

Currently, I am facing a challenge with two tables that are positioned next to each other. My goal is to append a selected row from the first table to the second table. After successfully extracting data from the selected row and converting it into an arr ...