Reputation: 85
I'm trying to make a simple typing test application using HTML, CSS and JS. I want to display some placeholder text in the box the user is typing in so that they know exactly what to type as they are typing it. If they mess up, it will become apparent because the placeholder text and input text wont line up. I've spent more than a few hours trying to figure this out and have come up with two sub-par solutions: HTML:
<div id='test' class="placeholder" data-value="This appears in the box!">
<textarea id="typed" name="typed" cols=50 rows=15></div>
CSS:
.placeholder
{
position: relative;
}
.placeholder::after
{
position: absolute;
left: 2px;
top: 2px;
content: attr(data-value);
pointer-events: none;
opacity: 0.6;
text-align: left;
}
This works fairly well, but unfortunately, any newline characters are completely ignored, displayed as a space, or displayed literally. I've tried \u000A, \x0A, \r\n, just pressing enter, it doesn't work.
Option two is using the placeholder attribute:
<textarea placeholder="line1
line2" id="typed" name="typed" cols=50 rows=15></textarea>
This displays correctly but as soon as you start typing, it disappears.
Does anyone know of a way to make the standard placeholder text stay permanently, or have some other workaround that formats correctly?
Upvotes: 6
Views: 2956
Reputation: 13666
I would stay away from using a data attribute or placeholder text to accomplish this. I think you will find it pretty difficult to include line breaks and cross-browser compatibility if you go that route. What about using 2 absolutely positioned textareas stacked on top of each other? The lower textarea
would contain the text the user needs to type and would be disabled and the top one would have a transparent background so you could see the text below. Here's a quick mockup of how that could look:
textarea {
position: absolute;
font-size: 20px;
}
#type {
color: red;
}
#typed {
background: none;
z-index: 10;
}
<div id='test' class="placeholder">
<textarea id="typed" name="typed" cols=50 rows=15></textarea>
<textarea id="type" name="typed" cols=50 rows=15 disabled>
This is the text you have to type.
You can put as many lines as you want.
</textarea>
</div>
Upvotes: 6
Reputation: 4971
Here is an example.
You were pretty much there, all I've done is wrapped them in a container.
The div and text textarea are both absolutely positioned and share the same font. The placeholder is positioned to take into account the 1px border and the 2px padding on a textarea. These are defaults, if you change them then you'll need to change the placeholder positioning.
.container {
position: relative;
}
textarea
{
position: absolute;
top: 0px;
left: 0px;
}
.placeholder
{
position: absolute;
left: 3px;
top: 3px;
content: attr(data-value);
pointer-events: none;
opacity: 0.6;
text-align: left;
z-index: 1;
}
textarea,
.placeholder {
font-family: arial;
font-size: 16px;
}
You'll notice below that the placeholder div has a <br />
in it for the line break. HTML handles line breaks differently from text so your comparison code will have to take this into account:
<div class='container'>
<div id='test' class="placeholder">This text appears<br /> in the box</div>
<textarea id="typed" name="typed" cols=50 rows=15></textarea>
</div>
Upvotes: 0