[html] Insert line break inside placeholder attribute of a textarea?

I have tried a few approaches but none worked. Does anyone know a the nifty trick to get around this?

<textarea placeholder='This is a line \n this should be a new line'></textarea>

<textarea placeholder='This is a line     
should this be a new line?'></textarea> <!-- this works in chrome apparently -->

UPDATE: It doesn't work in chrome. It was just the textarea width.

See: http://jsfiddle.net/pdXRx/

This question is related to html

The answer is


You can insert a new line html entity &#10; inside the placeholder attribute:

_x000D_
_x000D_
<textarea name="foo" placeholder="hello you&#10;Second line&#10;Third line"></textarea>
_x000D_
_x000D_
_x000D_

Works on: Chrome 62, IE10, Firefox 60

Doesn't work on: Safari 11

https://jsfiddle.net/lu1s/bxkjLpag/2/


You can't do it with pure HTML, but this jQuery plugin will let you: https://github.com/bradjasper/jQuery-Placeholder-Newlines


Add only &#10 for breaking line, no need to write any CSS or javascript.

_x000D_
_x000D_
textarea{_x000D_
    width:300px;_x000D_
    height:100px;_x000D_
_x000D_
}
_x000D_
<textarea placeholder='This is a line this &#10should be a new line'></textarea>_x000D_
_x000D_
<textarea placeholder=' This is a line _x000D_
_x000D_
should this be a new line?'></textarea>
_x000D_
_x000D_
_x000D_


I liked the work of Jason Gennaro and Denis Golomazov, but I wanted something that would be more globally useful. I have modified the concept so that it can be added to any page without repercussion.

http://jsfiddle.net/pdXRx/297/

<h1>Demo: 5 different textarea placeholder behaviors from a single JS</h1>

<h2>Modified behaviors</h2>

<!-- To get simulated placeholder with New Lines behavior,
     add the placeholdernl attribute -->

<textarea placeholdernl>    (click me to demo)
Johnny S. Fiddle
248 Fake St.
Atlanta, GA 30134</textarea>

<textarea placeholder='Address' placeholdernl>    (click me to demo)
Johnny S. Fiddle
248 Fake St.
Atlanta, GA 30134</textarea>

<h2>Standard behaviors</h2>

<textarea placeholder='Address'>    (delete me to demo)
Johnny S. Fiddle
248 Fake St.
Atlanta, GA 30134</textarea>

<textarea>    (delete me to demo)
Johnny S. Fiddle
248 Fake St.
Atlanta, GA 30134</textarea>

<textarea placeholder='Address'></textarea>

The javascript is very simple

<script>
(function($){
var handleFocus = function(){
    var $this = $(this);
    if($this.val() === $this.attr('placeholdernl')){
        $this.attr('value', '');
        $this.css('color', '');
    }
};

var handleBlur = function(){
    var $this = $(this);
    if($this.val() == ''){
        $this.attr('value', $this.attr('placeholdernl'))
        $this.css('color', 'gray');
    }    
};

$('textarea[placeholdernl]').each(function(){
    var $this = $(this),
        value = $this.attr('value'),
        placeholder = $this.attr('placeholder');
    $this.attr('placeholdernl', value ? value : placeholder);
    $this.attr('value', '');
    $this.focus(handleFocus).blur(handleBlur).trigger('blur');
});
})(jQuery);
</script>

Use &#10; in place of \n this will change the line.


Textarea respects the white-space attribute for the placeholder. https://www.w3schools.com/cssref/pr_text_white-space.asp

Setting it to pre-line solved the problem for me.

_x000D_
_x000D_
textarea {_x000D_
  white-space: pre-line;_x000D_
}
_x000D_
<textarea placeholder='This is a line     _x000D_
should this be a new line'></textarea>
_x000D_
_x000D_
_x000D_


This issue can be tackled by using the placeholder-shown selector and super imposed backgrounds, if your implementation allows:

textarea:not(:placeholder-shown) {
  background: #fff;
}

div {
  top: 0;
  left: 14px;
  color: rgba(0,0,0,0.4);
  z-index: -1;
  position: absolute;
  line-height: 1.2;
  white-space: pre-wrap;
}

https://codepen.io/franciscoaquino/pen/YzyBPYK

Selector support:

https://caniuse.com/#feat=css-placeholder-shown


Based on a combination of three different tricks I saw this seems to work in all browsers I've tested it in.

HTML:

<textarea placeholder="Line One&#10;Line Two&#10;&#10;Line Four"></textarea>

JS At bottom of HTML file:

<script>
    
    var textAreas = document.getElementsByTagName('textarea');

    Array.prototype.forEach.call(textAreas, function(elem) {
        elem.placeholder = elem.placeholder.replace(/\u000A/g, 
        '                                                     \
                                                              \
                                                              \
        \n\u2063');
    });

</script>

Note, the extra spaces will cause a clean wrap around but there has to be enough spaces that it will fill the width of the textarea, I placed enough that it's sufficient for my projects but you could be robust and generate them by observing the textarea.width and calculating the proper cardinality.


Old answer:

Nope, you can't do that in the placeholder attribute. You can't even html encode newlines like &#13;&#10; in a placeholder.

New answer:

Modern browsers give you several ways to do this. See this JSFiddle:

http://jsfiddle.net/pdXRx/5/


I don't like hiding the placeholder when you focus the textarea. So I made a constructor function Placeholder that looks exactly like the built-in placeholder and works also in other browsers than Google Chrome. It's very convenient because you can use the Placeholder function as often as you want and it doesn't even need jQuery.

EDIT:

It now also handles special cases, like inserting the placeholder, correctly.

_x000D_
_x000D_
var textarea = document.getElementById("textarea");_x000D_
new Placeholder(textarea, "Line 1\nLine 2\nLine 3");_x000D_
_x000D_
function Placeholder(el, placeholder) {_x000D_
    if (el.value == "" || el.value == placeholder) {_x000D_
        el.style.color = "gray";_x000D_
        el.value = placeholder;_x000D_
        el._plc = true;_x000D_
        el.className += " unselectable";_x000D_
    }_x000D_
    function keyPress(e) {_x000D_
        window.setTimeout(function() {_x000D_
            var replaced = reverseStr(el.value).replace(reverseStr(placeholder), "");_x000D_
            _x000D_
            if (el.value == "") {_x000D_
                el.value = placeholder;_x000D_
                el.style.color = "gray";_x000D_
                cursorToStart(el);_x000D_
                el._plc = true;_x000D_
                el.className += " unselectable";_x000D_
            } else if (el._plc && el.value.endsWith(placeholder) && replaced !== "") {_x000D_
                el.value = reverseStr(replaced);_x000D_
                el.style.color = "black";_x000D_
                el._plc = false;_x000D_
                el.readOnly = false;_x000D_
                el.className = el.className.replace("unselectable", "");_x000D_
            } else if (el._plc && el.readOnly) {_x000D_
                var ch = String.fromCharCode(e.charCode);_x000D_
                if (e.keyCode == 13) ch = "\n";     // ENTER_x000D_
                else if (e.charCode == 0) return;   // non-character keys_x000D_
                _x000D_
                el.value = ch;_x000D_
                el.style.color = "black";_x000D_
                el._plc = false;_x000D_
                el.readOnly = false;_x000D_
                el.className = el.className.replace("unselectable", "");_x000D_
            }_x000D_
        }, 10);_x000D_
    }_x000D_
    el.addEventListener("keypress", keyPress, false);_x000D_
    el.addEventListener("paste", keyPress, false);_x000D_
    el.addEventListener("cut", keyPress, false);_x000D_
    el.addEventListener("mousedown", function() {_x000D_
        if (el._plc) el.readOnly = true;_x000D_
    }, false);_x000D_
    el.addEventListener("mouseup", function() {_x000D_
        el.readOnly = false;_x000D_
        if (el._plc) cursorToStart(el);_x000D_
    }, false);_x000D_
  _x000D_
    function cursorToStart(input) {_x000D_
        if (input.createTextRange) {_x000D_
            var part = input.createTextRange();_x000D_
            part.move("character", 0);_x000D_
            part.select();_x000D_
        } else if (input.setSelectionRange){_x000D_
            input.setSelectionRange(0, 0);_x000D_
        } input.focus();_x000D_
    }_x000D_
    function reverseStr(str) {_x000D_
        if (!str) return "";_x000D_
        return str.split("").reverse().join("");_x000D_
    }_x000D_
}
_x000D_
textarea {_x000D_
    border: 1px solid gray;_x000D_
    padding: 3px 6px;_x000D_
    font-family: Arial;_x000D_
    font-size: 13px;_x000D_
    transition: .2s;_x000D_
}_x000D_
textarea:hover, textarea:focus {_x000D_
    border-color: #2277cc;_x000D_
}_x000D_
textarea:focus {_x000D_
    box-shadow: inset 0 0 5px #85B7E9;_x000D_
}_x000D_
*.unselectable {_x000D_
    -webkit-user-select: none;_x000D_
    -webkit-touch-callout: none;_x000D_
    -khtml-user-select: none;_x000D_
    -moz-user-select: none;_x000D_
    -ms-user-select: none;_x000D_
    -o-user-select: none;_x000D_
}
_x000D_
<textarea id="textarea"></textarea>
_x000D_
_x000D_
_x000D_


Salaamun Alekum

&#10;

Works For Google Chrome

enter image description here

<textarea placeholder="Enter Choice#1 &#10;Enter Choice#2 &#10;Enter Choice#3"></textarea>

I Tested This On Windows 10.0 (Build 10240) And Google Chrome Version 47.0.2526.80 m

08:43:08 AST 6 Rabi Al-Awwal, 1437 Thursday, 17 December 2015

Thank You


Try this:

<textarea
placeholder="Line1&#x0a;&#x09;&#x09;&#x09;Line2"
cols="10"
rows="5"
style="resize:none">
</textarea>

http://jsfiddle.net/vr79B/


Check out this solution with custom placeholder.

  • You get multiline placeholder that works in all browsers (including Firefox)
  • It is posible to customise placeholder as you want

Demo on fiddle.

_x000D_
_x000D_
$(document).on('input', '#textArea', function () {_x000D_
 _x000D_
        if ($('#textArea').val()) {_x000D_
            $('#placeholderDiv').hide();_x000D_
        } else {_x000D_
            $('#placeholderDiv').show();_x000D_
        }   _x000D_
});
_x000D_
#textAreaWrap {_x000D_
    position: relative;_x000D_
    background-color: white;_x000D_
}_x000D_
_x000D_
#textArea {_x000D_
    position: relative;_x000D_
    z-index: 1;_x000D_
    width: 350px;_x000D_
    height: 100px;_x000D_
    min-height: 100px;_x000D_
    padding: 6px 12px;_x000D_
    resize: vertical;_x000D_
    background-color: transparent;_x000D_
    /* When set background-color: transparent - Firefox  displays_x000D_
    unpleasant textarea border. Set border style to fix it.*/_x000D_
    border: 1px solid #a5a5a5;_x000D_
}_x000D_
_x000D_
#placeholderDiv {_x000D_
    position: absolute;_x000D_
    top: 0;_x000D_
    padding: 6px 13px;_x000D_
    color: #a5a5a5;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
_x000D_
<div id="textAreaWrap">_x000D_
    _x000D_
<textarea id="textArea"></textarea>_x000D_
_x000D_
<!-- Check here. If textarea has content -_x000D_
     set for this div attribute style="display: none;" -->_x000D_
<div id="placeholderDiv">Multiline textarea<br>_x000D_
                         placeholder<br>_x000D_
                         <br>_x000D_
                         that works in Firefox</div>_x000D_
    _x000D_
</div>
_x000D_
_x000D_
_x000D_


How about a CSS solution: http://cssdeck.com/labs/07fwgrso

::-webkit-input-placeholder::before {
  content: "FIRST\000ASECOND\000ATHIRD";
}

::-moz-placeholder::before {
  content: "FIRST\000ASECOND\000ATHIRD";
}

:-ms-input-placeholder::before {
  content: "FIRST\000ASECOND\000ATHIRD";
}

very simple

  var position = your break position;
    var breakLine = "&#13;&#10;";//in html 
    var output = [value.slice(0, position), breakLine, value.slice(position)].join('');
    return output;

value represent the original string


HTML

<textarea data-placeholder="1111\n2222"></textarea>

JS

$('textarea[data-placeholder]').each(function(){
    var $this = $(this),
        placeholder = $this.data('placeholder'),
        placeholderSplit = placeholder.split('\\n');
    placeholder = placeholderSplit.join('\n');
    $this.focus(function(){
        var $this = $(this);
        if($this.val() === placeholder){
            $this.val('');
            // $this.removeClass('placeholder');
        }
    }).blur(function(){
        var $this = $(this);
        if($this.val() == '') {
            $this.val(placeholder);
            // $this.addClass('placeholder');
        }
    }).trigger('blur');
});

Don't think you're allowed to do that: http://www.w3.org/TR/html5/forms.html#the-placeholder-attribute

The relevant content (emphasis mine):

The placeholder attribute represents a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value. A hint could be a sample value or a brief description of the expected format. The attribute, if specified, must have a value that contains no U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR) characters.


A slightly improved version of the Jason Gennaro's answer (see code comments):

var placeholder = 'This is a line \nthis should be a new line';
$('textarea').attr('value', placeholder);
$('textarea').focus(function(){
    if($(this).val() == placeholder){
        // reset the value only if it equals the initial one    
        $(this).attr('value', '');
    }
});
$('textarea').blur(function(){
    if($(this).val() == ''){
        $(this).attr('value', placeholder);
    }    
});
// remove the focus, if it is on by default
$('textarea').blur();

I modified @Richard Bronosky's fiddle like this.

It's better approach to use data-* attribute rather than a custom attribute. I replaced <textarea placeholdernl> to <textarea data-placeholder> and some other styles as well.

edited
Here is the Richard's original answer which contains full code snippet.


UPDATE (Jan 2016): The nice little hack might not work on all browsers anymore so I have a new solution with a tiny bit of javascript below.


A Nice Little Hack

It doesn't feel nice, but you can just put the new lines in the html. Like this:

_x000D_
_x000D_
<textarea rows="6" id="myAddress" type="text" placeholder="My Awesome House,
1 Long St
London
Postcode
UK"></textarea>
_x000D_
_x000D_
_x000D_

Notice each line is on a new line (not being wrapped) and each 'tab' indent is 4 spaces. Granted it is not a very nice method, but it seems to work:

http://jsfiddle.net/01taylop/HDfju/

  • It is likely that the indent level of each line will vary depending on the width of your text area.
  • It is important to have resize: none; in the css so that the size of the textarea is fixed (See jsfiddle).

Alternatively When you want a new line, hit return twice (So there is a empty line between your 'new lines'. This 'empty line' created needs to have enough tabs/spaces that would equate to the width of your textarea. It doesn't seem to matter if you have far too many, you just need enough. This is so dirty though and probably not browser compliant. I wish there was an easier way!


A Better Solution

Check out the JSFiddle.

  • This solution positions a div behind the textarea.
  • Some javascript is used to change the background colour of the textarea, hiding or revealing the placeholder appropriately.
  • The inputs and placeholders must have the same font sizes, hence the two mixins.
  • The box-sizing and display: block properties on the textarea are important or the div behind it will not be the same size.
  • Setting resize: vertical and a min-height on the textarea are also important - notice how the placeholder text will wrap and expanding the textarea will keep the white background. However, commenting out the resize property will cause issues when expanding the textarea horizontally.
  • Just make sure the min-height on the textarea is enough to cover your entire placeholder at its smallest width.**

JSFiddle Screenshot

HTML:

<form>
  <input type='text' placeholder='First Name' />
  <input type='text' placeholder='Last Name' />
  <div class='textarea-placeholder'>
    <textarea></textarea>
    <div>
      First Line
      <br /> Second Line
      <br /> Third Line
    </div>
  </div>
</form>

SCSS:

$input-padding: 4px;

@mixin input-font() {
  font-family: 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
  font-size: 12px;
  font-weight: 300;
  line-height: 16px;
}

@mixin placeholder-style() {
  color: #999;
  @include input-font();
}

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

form {
  width: 250px;
}

input,textarea {
  display: block;
  width: 100%;
  padding: $input-padding;
  border: 1px solid #ccc;
}

input {
  margin-bottom: 10px;
  background-color: #fff;

  @include input-font();
}

textarea {
  min-height: 80px;
  resize: vertical;
  background-color: transparent;
  &.data-edits {
    background-color: #fff;
  }
}

.textarea-placeholder {
  position: relative;
  > div {
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding: $input-padding;
    background-color: #fff;
    @include placeholder-style();
  }
}

::-webkit-input-placeholder {
  @include placeholder-style();
}
:-moz-placeholder {
  @include placeholder-style();
}
::-moz-placeholder {
  @include placeholder-style();
}
:-ms-input-placeholder {
  @include placeholder-style();
}

Javascript:

$("textarea").on('change keyup paste', function() {
  var length = $(this).val().length;
  if (length > 0) {
    $(this).addClass('data-edits');
  } else {
    $(this).removeClass('data-edits');
  }
});