Overflow visible on text input, is it possible?

28.5k views Asked by At

CSS overflow:visible doesn't seem to get applied to inputs.

See the following JS fiddle: https://jsfiddle.net/b4sr578j/

input {
  border: 1px dashed black;
  overflow: visible;
  height: 28px;
  font-size: 30px;
}
<input type='text' value='gggyyyXXX'/>

Is it possible to make the bottom of the gs and ys visible (without increasing the height of the text input)?

Thanks for any help.

6

There are 6 answers

0
Harry On

Answer to the original question - As indicated already by Sebastian Hens, this is not possible. The reason is because input elements are replaced elements and the overflow property applies only to non-replaced elements.

Quote from MDN about overflow property:

Applies to - non-replaced block-level elements and non-replaced inline-block elements

As already mentioned in comments, the ideal solution would be to make use of contenteditable elements because they do respect the overflow settings.


Here is a workaround solution which uses multiple linear-gradient to generate the dashed border effect. Part of the answer is adopted from Danield's answer (the parts about padding and removal of height). On top of it, I have modified the appearance and added the gradients.

Though we haven't added the height explicitly, the actual height of the area within the border would still be the same as that in your original code. I have added an input box with your original code on the left side for comparison. I don't know if that is acceptable for you. If you mandatorily want the height to be set then this would not work.

input.test {
  appearance: none;
  box-sizing: border-box;
  font-size: 30px;
  padding: 2px 0px 6px;
  border: 0;
  background: linear-gradient(to right, gray 50%, transparent 50%), linear-gradient(to right, gray 50%, transparent 50%), linear-gradient(to bottom, gray 50%, transparent 50%), linear-gradient(to bottom, gray 50%, transparent 50%);
  background-size: 8px 1px, 8px 1px, 1px 8px, 1px 8px;
  background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
  background-position: 0px 0px, 0px 1em, 0px 0px, 100% 0px;
  box-shadow: inset 0px -10px 0px white;
  width: 200px;
}
input.original {
  border: 1px dashed black;
  overflow: visible;
  height: 28px;
  font-size: 30px;
  width: 200px;
}

input{
  vertical-align: top;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<input type='text' value='gggyyyXXX' class='original' />
<input type='text' value='gggyyyXXX' class='test' />

In the above snippet a white box-shadow is used to hide the bottom part of the gradient so that it doesn't overflow (you can see the effect by removing the box-shadow) and because of this it needs a solid color background. On the other hand if the height of your text box is fixed then you could use something like the below snippet to even support non solid backgrounds.

input.original {
  border: 1px dashed black;
  overflow: visible;
  height: 28px;
  font-size: 30px;
  width: 200px;
}
input.test-fixedheight {
  appearance: none;
  box-sizing: border-box;
  font-size: 30px;
  padding: 2px 0px 6px;
  border: 0;
  background: linear-gradient(to right, crimson 50%, transparent 50%), linear-gradient(to right, crimson 50%, transparent 50%), linear-gradient(to bottom, crimson 12.5%, transparent 12.5%, transparent 25%, crimson 25%, crimson 37.5%, transparent 37.5%, transparent 50%, crimson 50%, crimson 62.5%, transparent 62.5%, transparent 75%, crimson 75%, crimson 87.5%, transparent 87.5%), linear-gradient(to bottom, crimson 12.5%, transparent 12.5%, transparent 25%, crimson 25%, crimson 37.5%, transparent 37.5%, transparent 50%, crimson 50%, crimson 62.5%, transparent 62.5%, transparent 75%, crimson 75%, crimson 87.5%, transparent 87.5%),linear-gradient(to bottom, transparent 0%, white 0%);
  background-size: 8px 1px, 8px 1px, 1px 1em, 1px 1em, 100% 1em;
  background-repeat: repeat-x, repeat-x, no-repeat, no-repeat;
  background-position: 0px 0px, 0px 29px, 0px 2px, 100% 2px;
  width: 200px;
}
input.test-fixedheight-transparent {
  appearance: none;
  box-sizing: border-box;
  font-size: 30px;
  padding: 2px 0px 6px;
  border: 0;
  background: linear-gradient(to right, beige 50%, transparent 50%), linear-gradient(to right, beige 50%, transparent 50%), linear-gradient(to bottom, beige 12.5%, transparent 12.5%, transparent 25%, beige 25%, beige 37.5%, transparent 37.5%, transparent 50%, crimson 50%, beige 62.5%, transparent 62.5%, transparent 75%, beige 75%, beige 87.5%, transparent 87.5%), linear-gradient(to bottom, beige 12.5%, transparent 12.5%, transparent 25%, beige 25%, beige 37.5%, transparent 37.5%, transparent 50%, beige 50%, beige 62.5%, transparent 62.5%, transparent 75%, beige 75%, beige 87.5%, transparent 87.5%);
  background-size: 8px 1px, 8px 1px, 1px 1em, 1px 1em;
  background-repeat: repeat-x, repeat-x, no-repeat, no-repeat;
  background-position: 0px 0px, 0px 29px, 0px 2px, 100% 2px;
  width: 200px;
}


/* Just for demo */

body{
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}

input{
  vertical-align: top;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<input type='text' value='gggyyyXXX' class='original' />
<input type='text' value='gggyyyXXX' class='test-fixedheight' />
<input type='text' value='gggyyyXXX' class='test-fixedheight-transparent' />

This approach is tested in Chrome, Firefox, Opera and IE11. Because gradients is supported in IE10, it should work fine there also but would not work with any of the lower versions as they don't support gradients.

0
Sebastian Hens On

To make it short: No this is not possible! The only thing what you could do is to create a javascript/html/css replacement for an input. But this would be an overhead.

To get an idea:

  • set the input to visibility hidden
  • position a DIV with the "input styling" under the input
  • let a javascript check if the user does a keypress while focusing the input an copy the input value to the div
6
csaw On

i doubt it can be done like this. input uses size attribute for this. so manipulate size, using code. for eg. in php;

<input type="text" name="nm" size = "<?php if(strlen($text)<=10)echo 10;
 else echo strlen($text); ?>" >
5
Danield On

Here's a solution for Webkit and Firefox:

(This won't work in IE - because it doesn't support outline-offset)

1) Remove the height

2) Use outline instead of border

3) Add a negative outline-offset

4) Add padding to fine tune the offset

FIDDLE

input {
  overflow: visible;
  font-size: 30px;
  outline: 1px dashed black;
  border: 0;
  outline-offset: -8px;
  padding: 6px 0 2px 8px;
}
<input type='text' value='gggyyyXXX' />

0
Jeremias Nater On

Solution 1

Use Contenteditable

const editorElement = document.getElementById("editor");

editorElement.addEventListener("input", function(event) {
    console.log("value: ", editorElement.innerText );
}, false);
<div contenteditable="true" id="editor">Please type something in here</div>

Solution 2

Use negative Margins on top and Bottom To prevent the text from overflowing the input:

input {
display: block;
 margin-top: -5px;
 margin-bottom: -25px;
 height: 30px;
}
<div>Content before</div>
<input type="text" value="input Value"/><br>
<div>Content after</div>

0
Jamie Barker On

More of a workaround really, but why not absolutely position an input with no border over the top?

body {
  position:relative;
}
input {
  border: 1px dashed black;
  overflow: visible;
  height: 28px;
  font-size: 30px;
}
input.noborder {
  border:1px transparent solid;
  height:34px;
  position:absolute;
  left:0;
  background:transparent;
}
<input type='text' value=''/>
<input class="noborder" type='text' value='gggyyyXXX'/>