Можете ли вы иметь многострочный текст в формате HTML5 в <textarea>?

У меня есть текст-призрак в текстовых полях, которые исчезают, когда вы фокусируетесь на них с помощью атрибута placeholder HTML5:

<input type="text" name="email" placeholder="Enter email"/>

Я хочу использовать тот же механизм, чтобы иметь многострочный текст-заполнитель в текстовом поле, возможно, что-то вроде этого:

<textarea name="story" placeholder="Enter story\n next line\n more"></textarea>

Но те \n отображаются в тексте и не вызывают новые строки... Есть ли способ иметь многострочный placeholder?

ОБНОВЛЕНИЕ. Единственный способ, которым я получил это, - использовать плагин jQuery Watermark, который принимает HTML в тексте заполнителя:

$('.textarea_class').watermark('Enter story<br/> * newline', {fallback: false});

Ответ 1

Для <textarea>спецификация специально описывает, что возврат каретки + разрывы строк в атрибуте-заполнителе ДОЛЖНЫ отображаться браузером как разрывы строк.

Пользовательские агенты должны представить эту подсказку пользователю, когда значением элемента является пустая строка, а элемент управления не сфокусирован (например, путем отображения его внутри пустого несфокусированного элемента управления). Должны быть обработаны все пары символов U + 000D ВОЗВРАТ УСТРОЙСТВА U + 000A LINE FEED (CRLF) в подсказке, а также все другие символы возврата U + 000D CARRIAGE (CR) и U + 000A LINE FEED (LF) в подсказке. как разрывы строк при отображении подсказки.

Также отражено в MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attr-placeholder

FWIW, когда я пробую Chrome 63.0.3239.132, он действительно работает так, как он говорит.

Ответ 2

В большинстве браузеров (см. Подробности ниже) редактирование заполнителя в javascript позволяет использовать многострочный заполнитель. Как уже было сказано, он не соответствует спецификации, и вы не должны ожидать, что он будет работать в будущем (правка: он работает).

Этот пример заменяет весь многострочный текстовый заполнитель.

var textAreas = document.getElementsByTagName('textarea');

Array.prototype.forEach.call(textAreas, function(elem) {
    elem.placeholder = elem.placeholder.replace(/\\n/g, '\n');
});
<textarea class="textAreaMultiline" 
          placeholder="Hello, \nThis is multiline example \n\nHave Fun"
          rows="5" cols="35"></textarea>

Ответ 3

Я нахожу, что если вы используете много пробелов, браузер будет обертывать его правильно. Не беспокойтесь об использовании точного количества пробелов, просто бросьте туда много, и браузер должен должным образом обернуть первый символ пробела на следующей строке.

<textarea name="address" placeholder="1313 Mockingbird Ln         Saginaw, MI 45100"></textarea>

Ответ 4

Существует фактический взлом, который позволяет добавлять многострочные заполнители в браузерах Webkit, Chrome работал, но в последних версиях они удалили его:


Сначала добавьте первую строку вашего заполнителя в html5, как обычно.

<textarea id="text1" placeholder="Line 1" rows="10"></textarea>

затем добавьте остальную часть строки в css:

#text1::-webkit-input-placeholder::after {
    display:block;
    content:"Line 2\A Line 3";
}

Если вы хотите сохранить свои строки в одном месте, вы можете попробовать следующее. Недостатком этого является то, что другие браузеры, чем хром, сафари, webkit и т.д. даже не показывать первую строку:

<textarea id="text2" placeholder="." rows="10"></textarea>​

затем добавьте остальную часть строки в css:

#text2::-webkit-input-placeholder{
    color:transparent;
}

#text2::-webkit-input-placeholder::before {
    color:#666;
    content:"Line 1\A Line 2\A Line 3\A";
}

Демо-скрипт

Было бы здорово, если бы s.o. может получить аналогичную демоверсию, работающую в Firefox.

Ответ 5

Если вы используете AngularJS, вы можете просто использовать фигурные скобки, чтобы поместить в нее все, что вы хотите: Вот скрипка.

<textarea rows="6" cols="45" placeholder="{{'Address Line1\nAddress Line2\nCity State, Zip\nCountry'}}"></textarea>

Ответ 6

html5 spec явно отклоняет новые строки в поле владельца места. Версии Webkit/будут/вставлять новые строки при представлении строк в заполнителе, однако это неправильное поведение и на него нельзя положиться.

Я думаю, что абзацы недостаточно кратки для w3;)

Ответ 7

Если ваш textarea имеет статическую ширину, вы можете использовать комбинацию неразрывного пространства и автоматическую упаковку textarea. Просто замените пробелы на nbsp для каждой строки и убедитесь, что две соседние строки не могут вписаться в одну строку. На практике line length > cols/2.

Это не лучший способ, но может быть единственным кросс-браузерным решением.

<textarea class="textAreaMultiligne" 
          placeholder="Hello,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This&nbsp;is&nbsp;multiligne&nbsp;example Have&nbsp;Fun&nbsp;&nbsp;&nbsp;&nbsp;"
          rows="5" cols="35"></textarea>

Ответ 8

Вы можете попробовать использовать CSS, он работает для меня. Здесь требуется атрибут placeholder=" ".

<textarea id="myID" placeholder=" "></textarea>
<style>
#myID::-webkit-input-placeholder::before {
    content: "1st line...\A2nd line...\A3rd line...";
}
</style>

Ответ 9

React:

Если вы используете React, вы можете сделать это следующим образом:

placeholder={'Address Line1\nAddress Line2\nCity State, Zip\nCountry'}

Ответ 10

Согласно MDN,

Возврат каретки или перевод строки в тексте-заполнителе должны рассматриваться как разрывы строк при отображении подсказки.

Это означает, что если вы просто перейдете на новую строку, она должна отображаться правильно. Т.е.

<textarea placeholder="The car horn plays La Cucaracha.
You can choose your own color as long as it black.
The GPS has the voice of Darth Vader.
"></textarea> 

должен сделать так:

enter image description here

Ответ 11

Я не думаю, что это возможно только с html/css. Возможно, с помощью JavaScript или какого-либо другого взлома - дополнительные пробелы, чтобы переместить текст в следующую строку и т.д.

Ответ 12

Bootstrap + contenteditable + multiline placeholder

Демо: https://jsfiddle.net/39mptojs/4/

на основе ответов @cyrbil и @daniel

Использование Bootstrap, jQuery и https://github.com/gr2m/bootstrap-expandable-input, чтобы включить placeholder в contenteditable.

С помощью "замещающего замещающего" javascript и добавления "white-space: pre" в css отображается многострочный placeholder.

Html:

<div class="form-group">
    <label for="exampleContenteditable">Example contenteditable</label>
    <div id="exampleContenteditable" contenteditable="true" placeholder="test\nmultiple line\nhere\n\nTested on Windows in Chrome 41, Firefox 36, IE 11, Safari 5.1.7 ...\nCredits StackOveflow: .placeholder.replace() trick, white-space:pre" class="form-control">
    </div>
</div>

JavaScript:

$(document).ready(function() {
    $('div[contenteditable="true"]').each(function() {
        var s=$(this).attr('placeholder');
        if (s) {
            var s1=s.replace(/\\n/g, String.fromCharCode(10));
            $(this).attr('placeholder',s1);
        }
    });
});

Css:

.form-control[contenteditable="true"] {
    border:1px solid rgb(238, 238, 238);
    padding:3px 3px 3px 3px;
    white-space: pre !important;
    height:auto !important;
    min-height:38px;
}
.form-control[contenteditable="true"]:focus {
    border-color:#66afe9;
}

Ответ 13

в php с функцией chr (13):

echo '<textarea class="form-control" rows="5" style="width:100%;" name="responsable" placeholder="NOM prénom du responsable légal'.chr(13).'Adresse'.chr(13).'CP VILLE'.chr(13).'Téléphone'.chr(13).'Adresse de messagerie" id="responsable"></textarea>';

Ответ 14

Решение Watermark в оригинальном посте отлично работает. Спасибо за это. В случае, если это кому-то понадобится, для этого существует директива angular.

(function () {
  'use strict';

  angular.module('app')
    .directive('placeholder', function () {
      return {
        restrict: 'A',
        link:     function (scope, element, attributes) {
          if (element.prop('nodeName') === 'TEXTAREA') {
            var placeholderText = attributes.placeholder.trim();

            if (placeholderText.length) {
              // support for both '\n' symbol and an actual newline in the placeholder element
              var placeholderLines = Array.prototype.concat
                .apply([], placeholderText.split('\n').map(line => line.split('\\n')))
                .map(line => line.trim());

              if (placeholderLines.length > 1) {
                element.watermark(placeholderLines.join('<br>\n'));
              }
            }
          }
        }
      };
    });
}());