How to create an input with an inner label in ReactJs and Styled-Components

Nadine Thery
urbanData Analytics
4 min readJul 5, 2021

--

Input HTML tags can be customized to the infinite. However, they do not admit other tags inside in order to nest other elements within. Let’s take a look at one way to achieve this through css trompe l’oil…

An artsy intro

Have you ever heard about the trompe l’oeil painting technique?

John Pugh, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons

Trompe l’oeil: a painting that is cleverly designed to trick people into thinking that the objects represented in it are really there. (according to the Cambridge dictionary).

At frontend development, we face design challenges that requires us to make this trompe l’oeils with the HTMLs elements we already have on a daily basis. HTML tags are limited but highly customized elements. And design ideas and UX needs are just endless.

All this intro to tell you that in order to achieve our goal we are going to trick the eye and recreate an input field with HTML elements and CSS but not only using an input tag.

For this article, I will be using React Js and styled-components library which will allow me to use CSS-in-JS syntax and a very flexible way to write atomic components.

Long story-short

  1. We create a group with all the elements we want to be within the input.
  2. Remove default styles and style all the group like an input.

Create a group with all the elements we want

This is the easy one.

Remove default styles and style all group like an input

Tadah! an input with prefix and suffix

Below you will find the full code and the breakdown of it to understand what’s going on in the formatting here.

Can’t I just copy and paste it? Yeah, sure, but chances are you are going to need to adapt this, so… you’d better understand what’s going on down here.
  1. Let’s create styled-components for all the elements. The div , the input and the p tags. This will allow us to apply the CSS directly. At this point, you can actually do this with a plain old CSS style sheet if you wish.
  2. We make the container relative in order to be able to position our tags absolute but only in relation to the container. Otherwise, it would be positioned in relation to the document.
  3. We remove all the default styles of the input, by putting it transparent and removing the border. Some adjustments in the line height to make it a bit taller.
  4. I apply two different class names to our p . Some characteristics are common such as the top position. Then I apply different side positions (left or right value 0) depending on the orientation of the label. Just position them where you want them to be.
  5. Now that the tags are where they are supposed to, we need to apply style to the input: 100% width in order to fit the container. But also enough padding to prevent the input text to override the prefix and the suffix.

And that’s it when it comes to just formatting our trompe l’oeil.

Let’s talk about limitations

  1. You need to limit the characters of the input to avoid overflow.
  2. This works just fine as long as the prefix or the suffix is not dynamic (and has different widths).

What if I want to make a reactive label?

A very cool use case of a prefix label is to have a reactive label that shows some results depending on the value in the input.

The suffix is usually used for units or more immutable text.

What does that imply in our component?

  • We need to prepare our prefix to handle overflow
  • We need to make the input’s padding reactive to the size of the label
  • Maybe the alignment of the input should be different depending on the prefix use or not.
  • And of course, we need to make it reactive to the content.

Worry not, we will tackle into all this in the next article about How to make a reactive text inside and input with ReactJs.

Peace and code

Nadine

--

--

Nadine Thery
urbanData Analytics

Frontend Developer 👩🏻‍💻, videogamer 🎮, boardgamer 🎲, plant-lady 🌿, mother-of-cat-and-dogs 🐱🐶🐶, environment-concerned🌎, youtuber, ocassional podcaster