Usually we see input fields with fixed width, but sometimes we see adaptive content width, like this

So far I know there are two ways, I believe it is not difficult to find

  1. Set the normal div tag to contenteditable=”true” and set inline-block to allow you to adjust the content width
  2. Synchronize the input to a transparent div, with the parent width following the width of the div, and then set the input to absolutely positioned and overlaid, with a width of 100%

These are all good ideas. This time bring a new pure CSS implementation scheme, I believe can bring a different feeling

Substitutable elements

First, the input is a replaceable element, unlike a normal DIV element

In CSS, the presentation of replacement elements is not controlled by CSS. These elements are external objects, and the rendering of their appearance is CSS independent.

Normally, you can set the width of an element if you want it to be internally determined

div{
  display: inline-block;
}
Copy the code

In CSS3, you can do this in another way

div{
  width: fit-content;
}
Copy the code

CSS3 Max /min-content; fit-Content; CSS3 Max /min-content;

However, in input, none of this works, and as you can see from the developer tools, input also has a layer of shadow-root

Also, the browser does not expose the relevant selectors for developers to use, so it is not possible to adapt the content width simply by conventional means

Underline style

What do you think of when you look at the input box in the renderings? That’s right, underline. Underline is a type of text decoration that follows the text, so remove the border around the input and underline it

input{
  border: 0;
  outline: 0;
  text-decoration: 4px solid underline;
}
Copy the code

Results the following

The underline does appear and follows the input, but it’s a little too tight

Underscore offset

To solve this problem, you need to use a new CSS property, text-underline-offset, which represents the offset position of the underline. At present, compatibility is good, except IE, mainstream browsers are supported

Now, offset the underline a little bit

input{
  / * * /
  text-underline-offset: 10px;
}
Copy the code

The underline was missing! Change from 0px to 10px as follows: text-underline-offset

This is due to internal size issues. The underline has been offset out of the container. Try adding height to the input, for example

input{
  / * * /
  height: 60px;
  text-underline-offset: 10px;
}
Copy the code

But nothing

As you can see from the developer tools, the height set on the outside does not affect the size of the inside, so the inside remains the default height

So, what else can you do to change the height?

The answer is line-height!

input{
  / * * /
  line-height: 2;
  text-underline-offset: 10px;
}
Copy the code

The line height is a text property that can be inherited internally so that the internal dimensions are directly stretched out and the underline is visible

4. Default minimum width

And because I’m using underscores, when the input box is just placeholder with no content, the underscores are not there, for example

<input placeholder="Please enter...">
Copy the code

Results the following

You might think it’s a little bit ugly and want to add a minimum width underline (of course it depends on the design)

In this case, you can use a linear gradient underline

input{
  background: linear-gradient(currentColor,currentColor) center bottom 6px no-repeat;
  background-size: 10rem 4px;
}
Copy the code

This has an effect similar to the minimum width

Note that the position of the underline and the linear gradient should be the same

Fifth, focusing style

Now with a little bit of focus, it looks more like an input border, the underline needs to change color, and then the linear gradient needs to change color as well

input:focus{
  text-decoration-color: dodgerblue;
  background-image: linear-gradient(dodgerblue,dodgerblue)
}
Copy the code

This has achieved the effect of the beginning of the article

The full code can be accessed: Auto Input (codepen.io)

Summary and explanation

The above introduces a new kind of self-adaptive content width of pure CSS solution, using the usually not very impressive underline style, if your project is not compatible with IE, also happens to have this aspect of the need, you can rest assured to use, but even if not, you can also learn the idea. To summarize the main points:

  1. Input is a replaceable element
  2. The underline follows the text, not the container
  3. Now there’s a brand new onetext-underline-offsetCan be used to control the offset of the underline
  4. If the input is blank, the underscore will not exist
  5. Use CSS gradient to draw an underscore
  6. Underline colors can be modified by texttext-decoration-colorModify the

There is also a small detail, the input is set to be 100% width, that is, the entire line can be entered, but visually it looks like the underline part is the input field, which is a small distraction. If you think it’s good and helpful, please like, bookmark and retweet ❤❤❤