Friday, February 6, 2026
HomeLanguagesHow to create a translucent text input in ReactJS ?

How to create a translucent text input in ReactJS ?

In this article, we are going to learn how to create a translucent text input in ReactJS.

Prerequisites:

  1. Knowledge of JavaScript (ES6)
  2. Knowledge of HTML/CSS.
  3. Basic knowledge of ReactJS.

React hooks used in building this application are:

JavaScript modules:

Creating React Application and Installing Modules:

Step 1: Now, you will start a new project using create-react-app so open your terminal and type:

npx create-react-app translucent-input-box

Step 2: After creating your project folder i.e. translucent-input-box , move to it using the following command.

cd translucent-input-box

Step 3: Add the npm packages you will need during the project:

npm install framer-motion styled-components

Step 5: Now open your newly created project and open the src folder and delete the following files (Optional):Ā 

  • logo.svg
  • serviceWorker.js
  • setupTests.js
  • index.css
  • App.test.js (if any)

Create a folder named Input and create the following files:

  • Component.jsx
  • Component.motion.js
  • Component.styles.js

Project structure: It will look like this.

Project structure

Approach:Ā 

  • We are going to create a translucent animated text input using framer-motion and styled components.
  • Wrapper, Input, Label, Underline are the styled components used to make the text input box collectively in Component.jsx file.
  • In Component.jsx file, we use framer-motion with custom animation variants from the Component.motion.js file to animate the text input box.
  • React useState hook is used to manage the state of value that is used as a placeholder attribute & also to set it as a label when active.
  • Framer-motion useCycle hook is similar to react useState hook. It cycles through a series of visual properties used for animation. It is used to toggle between or cycle through animation variants.

Implementation:

Filename: App.js

javascript




import React, { useState } from "react";
import "./App.css";
Ā Ā 
import Input from "./Input";
Ā Ā 
const App = () => {
Ā Ā // The useState hook is used to manage the state ofĀ 
Ā Ā // "value" that is used as placeholder attribute
Ā Ā // and also to set it as a label when clicked
Ā Ā const [value, setValue] = useState("");
Ā Ā Ā Ā 
Ā Ā return (
Ā Ā Ā Ā <div className="App">
Ā Ā Ā Ā Ā Ā <div className="container">
Ā Ā Ā Ā Ā Ā Ā {/* "Input" component created using styled-components
Ā Ā Ā Ā Ā Ā Ā and animated using framer-motion
Ā Ā Ā Ā Ā Ā Ā */}
Ā Ā Ā Ā Ā Ā Ā Ā <Input
Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā value={value}
Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā onChange={(id, value) => setValue(value)}
Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā label={"First name"}
Ā Ā Ā Ā Ā Ā Ā Ā />
Ā Ā Ā Ā Ā Ā </div>
Ā Ā Ā Ā </div>
Ā Ā );
};
Ā Ā 
export default App;


Filename: index.js

javascript




import React from "react";
import ReactDOM from "react-dom";
Ā Ā 
import App from "./App";
Ā Ā 
const rootElement = document.getElementById("root");
ReactDOM.render(
Ā Ā <React.StrictMode>
Ā Ā Ā Ā <App />
Ā Ā </React.StrictMode>,
Ā Ā rootElement
);


Filename: App.css

css




.App {
Ā Ā font-family: "Times New Roman", Times, serif;
Ā Ā text-align: center;
Ā Ā 
Ā Ā width: auto;
Ā Ā height: 98vh;
Ā Ā 
Ā Ā display: flex;
Ā Ā justify-content: center;
Ā Ā align-items: center;
Ā Ā 
Ā Ā overflow: hidden;
Ā Ā background: #1e9600; /* fallback for old browsers */
Ā Ā background: -webkit-linear-gradient(
Ā Ā Ā Ā to right,
Ā Ā Ā Ā #ff0000,
Ā Ā Ā Ā #fff200,
Ā Ā Ā Ā #1e9600
Ā Ā ); /* Chrome 10-25, Safari 5.1-6 */
Ā Ā background: linear-gradient(
Ā Ā Ā Ā to right,
Ā Ā Ā Ā #ff0000,
Ā Ā Ā Ā #fff200,
Ā Ā Ā Ā #1e9600
Ā Ā );
}
Ā Ā 
.container {
Ā Ā border-radius: 25px;
Ā Ā 
Ā Ā width: 50vw;
Ā Ā height: 20vh;
Ā Ā 
Ā Ā display: flex;
Ā Ā justify-content: center;
Ā Ā align-items: center;
Ā Ā 
Ā Ā opacity: 0.5;
Ā Ā background-color: #f1f1f1;
}
Ā Ā 
Input {
Ā Ā text-decoration: none;
Ā Ā background-color: #f1f1f1;
Ā Ā width: 40%;
}


Filename: Component.jsx

javascript




import React from "react";
import { Wrapper, Input, Label, Underline } from "./Component.styles";
import { motionLabel, motionUnderline } from "./Component.motion";
import { useCycle } from "framer-motion";
Ā Ā 
export default ({ label, value, onChange, id, errors }) => {
Ā Ā const onTapStart = (event, info) => {
Ā Ā Ā Ā focus === "inactive" && cycleFocus();
Ā Ā Ā Ā return blur === "inactive" && cycleBlur();
Ā Ā };
Ā Ā const onBlur = event => {
Ā Ā Ā Ā value === "" && cycleFocus();
Ā Ā Ā Ā cycleBlur();
Ā Ā };
Ā Ā const [focus, cycleFocus] = useCycle("inactive", "active");
Ā Ā const [blur, cycleBlur] = useCycle("inactive", "active");
Ā Ā return (
Ā Ā Ā {/* Wrapper,Label,Underline - custom styled-components withĀ 
Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā some of its attributes
Ā Ā Ā */}
Ā Ā Ā {/* These all collectively make the animated input box whichĀ 
Ā Ā Ā then given transluscent background using CSS
Ā Ā Ā */}Ā 
Ā Ā Ā Ā <Wrapper>
Ā Ā Ā Ā Ā Ā <Input
Ā Ā Ā Ā Ā Ā Ā Ā onTap={onTapStart}
Ā Ā Ā Ā Ā Ā Ā Ā placeholder={label}
Ā Ā Ā Ā Ā Ā Ā Ā onBlur={e => onBlur(id)}
Ā Ā Ā Ā Ā Ā Ā Ā onChange={e => onChange(id, e.target.value)}
Ā Ā Ā Ā Ā Ā Ā Ā type={"text"}
Ā Ā Ā Ā Ā Ā Ā Ā required
Ā Ā Ā Ā Ā Ā Ā Ā value={value}
Ā Ā Ā Ā Ā Ā />
Ā Ā Ā Ā Ā Ā <Label {...motionLabel(focus)}>{label}</Label>
Ā Ā Ā Ā Ā Ā <Underline {...motionUnderline(blur)} />
Ā Ā Ā Ā </Wrapper>
Ā Ā );


Filename: Component.motion.js

javascript




const variantsWrapper = {
Ā Ā initial: {},
Ā Ā in: {},
Ā Ā out: {},
Ā Ā hover: {},
Ā Ā tap: {}
};
Ā Ā 
const variantsLabel = {
Ā Ā active: {
Ā Ā Ā Ā x: -15,
Ā Ā Ā Ā y: -20,
Ā Ā Ā Ā scale: 0.7
Ā Ā },
Ā Ā inactive: { x: 0, y: 0, scale: 1 }
};
const variantsUnderline = {
Ā Ā active: {
Ā Ā Ā Ā width: "100%",
Ā Ā Ā Ā transition: {
Ā Ā Ā Ā Ā Ā ease: "easeIn",
Ā Ā Ā Ā Ā Ā duration: 0.2
Ā Ā Ā Ā }
Ā Ā },
Ā Ā inactive: {
Ā Ā Ā Ā width: "0",
Ā Ā Ā Ā transition: {
Ā Ā Ā Ā Ā Ā ease: "easeIn",
Ā Ā Ā Ā Ā Ā duration: 0.1
Ā Ā Ā Ā }
Ā Ā }
};
Ā Ā 
export const motionLabel = state => {
Ā Ā return {
Ā Ā Ā Ā animate: state,
Ā Ā Ā Ā variants: variantsLabel
Ā Ā };
};
Ā Ā 
export const motionUnderline = state => {
Ā Ā return {
Ā Ā Ā Ā animate: state,
Ā Ā Ā Ā variants: variantsUnderline
Ā Ā };
};
Ā Ā 
export const animationWrapper = {
Ā Ā initial: "initial",
Ā Ā animate: "in",
Ā Ā exit: "out",
Ā Ā whileHover: "hover",
Ā Ā whileTap: "tap",
Ā Ā variants: variantsWrapper
};


Filename: Component.styles.js

javascript




import styled from "styled-components";
import { motion } from "framer-motion";
Ā Ā 
// Below are the styled-components used toĀ 
// make the animated text input box
Ā Ā 
export const Wrapper = styled(motion.div)`
Ā Ā position: relative;
Ā Ā width: 80%;
Ā Ā padding: 18px;
Ā Ā padding-bottom: 30px;
Ā Ā border-bottom: 1px solid #2f528f;
`;
Ā Ā 
export const Label = styled(motion.span)`
Ā Ā align-self: center;
Ā Ā position: absolute;
Ā Ā left: 0;
Ā Ā top: 50%;
Ā Ā grid-area: input;
Ā Ā font-family: Montserrat;
Ā Ā font-size: 18px;
Ā Ā line-height: 18px;
Ā Ā text-align: left;
Ā Ā pointer-events: none;
Ā Ā font-weight: normal;
Ā Ā /* background: green; */
`;
Ā Ā 
export const Input = styled(motion.input)`
Ā Ā height: 18px;
Ā Ā font-size: 18px;
Ā Ā -webkit-appearance: none;
Ā Ā background: transparent !important;
Ā Ā position: absolute;
Ā Ā left: 0;
Ā Ā top: 50%;
Ā Ā padding: 0;
Ā Ā padding-bottom: 5px;
Ā Ā margin: 0;
Ā Ā color: black;
Ā Ā border: none;
Ā Ā box-shadow: none !important;
Ā Ā font-weight: normal;
Ā Ā &:focus {
Ā Ā Ā Ā outline: none;
Ā Ā }
Ā Ā &::placeholder {
Ā Ā Ā Ā color: #f1f1f1;
Ā Ā }
`;
Ā Ā 
export const Underline = styled(motion.div)`
Ā Ā position: absolute;
Ā Ā background-color: #2f528f;
Ā Ā bottom: 0;
Ā Ā left: 0;
Ā Ā width: 100%;
Ā Ā height: 3px;
`;


Step to Run Application: Run the application using the following command from the root directory of the project :

npm start

Output: Now open your browser and go to http://localhost:3000/, you will see the following output:

Whether you’re preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, neveropen Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we’ve already empowered, and we’re here to do the same for you. Don’t miss out – check it out now!
RELATED ARTICLES

Most Popular

Dominic
32490 POSTS0 COMMENTS
Milvus
126 POSTS0 COMMENTS
Nango Kala
6862 POSTS0 COMMENTS
Nicole Veronica
11985 POSTS0 COMMENTS
Nokonwaba Nkukhwana
12073 POSTS0 COMMENTS
Shaida Kate Naidoo
6995 POSTS0 COMMENTS
Ted Musemwa
7236 POSTS0 COMMENTS
Thapelo Manthata
6946 POSTS0 COMMENTS
Umr Jansen
6931 POSTS0 COMMENTS