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

153

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

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

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

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

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

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

$('.textarea_class').watermark('Enter story<br/> * newline', {fallback: false});
в.
источник
Кажется, IE справляется с этим правильно. Firefox OTOH просто игнорирует переводы строк
ekkis
1
stackoverflow.com/questions/7312623/… очень похожий вопрос с хорошими ответами тоже.
Ллойд Дьюольф
если вы сталкиваетесь с этим и используете js, чтобы установить значение, проверьте css, white-spaceчтобы убедиться, что оно установлено правильно, например, предварительная упаковка
Кори Моухортер
Из этого другого вопроса: &#10;работает везде, кроме Safari.
Sphinxxx

Ответы:

82

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

Пользовательские агенты должны представить эту подсказку пользователю, когда значением элемента является пустая строка и элемент управления не сфокусирован (например, отображая его внутри пустого несфокусированного элемента управления). Должны быть обработаны все пары символов 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, он действительно работает так, как он говорит.

Ionuț G. Stan
источник
37
за исключением того, что атрибут title ведет себя не так, то есть он не показывает содержимое-призрак. фактически для заполнителей было бы совершенно уместно поддерживать несколько строк для текстовых областей, поскольку текстовые области являются многострочными существами. Жаль, что спецификация не позволяет этого. Я думаю, что взломать придется сделать. вздох
ekkis
71

В большинстве браузеров (см. Подробности ниже) редактирование заполнителя в 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>

Фрагмент JsFiddle .

Ожидаемый результат

Ожидаемый результат


Судя по комментариям, некоторые браузеры принимают этот взлом, а другие нет.
Это результаты тестов, которые я провел (с browsertshots и browserserck )

  • Хром:> = 35.0.1916.69
  • Firefox:> = 35.0 (результаты зависят от платформы)
  • IE:> = 10
  • Браузеры на основе KHTML: 4,8
  • Safari: нет (проверено = Safari 8.0.6 Mac OS X 10.8)
  • Опера: нет (проверено <= 15.0.1147.72)

С учетом этой статистики это означает, что она работает на 88,7% используемых в настоящее время (октябрь 2015 г.) браузеров.

Обновление : сегодня он работает не менее чем на 94,4% используемых в настоящее время (июль 2018 г.) браузеров.

Cyrbil
источник
1
Этот пример jsfiddle не работает вообще ... Он только многопоточный, потому что размер текстовой области.
себукем
2
Есть опечатка, но я не могу редактировать, потому что StackOverflow выдает мне эту ошибку «Изменения должны быть не менее 6 символов». Ваш класс должен быть multilineнеmultiligne
Даниэль Кико
@sebnukem: работает в большинстве браузеров, которые я тестировал. И это не вопрос размера текстовой области. Можете ли вы предоставить больше информации по вашей проблеме?
Cyrbil
Кажется, не работает на сафари ... - \ n исчезает, но все в одной строке
Хакерон
1
@Jroonk: я могу это подтвердить. Это связано не с Chrome, а с тем, что Apple заставляет любой браузер использовать свои IOS WKWebView. Впоследствии, любой браузер на IOS не будет правильно обрабатывать этот хак, пока WKWebViewне сделает.
Cyrbil
59

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

<textarea name="address" placeholder="1313 Mockingbird Ln         Saginaw, MI 45100"></textarea>
Томас Хантер II
источник
2
Да, многострочные заполнители не поддерживаются кроссбраузером, они обнаружили, что последнее сафари поддерживает, но определенно не поддерживается на IOS5
Том
7
это не работает для меня ни в IE, ни в Firefox Windows. он просто вставляет пробелы, к которым я его просил
ekkis
Chrome 37 отображает текст-заполнитель в текстовой области без зачеркивания. Кто-нибудь знает, как называется «функция», так что я могу а) найти ее и б) проверить ее?
Бен
23

Существует настоящий хак, который позволяет добавлять многострочные заполнители в браузеры 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";
}

Если вы хотите сохранить свои строки в одном месте, вы можете попробовать следующее. Недостатком этого является то, что другие браузеры, кроме Chrome, Safari, 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";
}

Демо Фиддл

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

Gottox
источник
спасибо за предоставление скриптовой ссылки. это позволяет легко проверить поведение в различных браузерах. в IE 10 обе версии терпят неудачу, а также в FF 12 (Windows). Жаль, что. Safari 6.1 работает :(
ekkis
Больше не работает в Chrome - давно, я бы предположил.
Майк Рокетт
6

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

<textarea rows="6" cols="45" placeholder="{{'Address Line1\nAddress Line2\nCity State, Zip\nCountry'}}"></textarea>
ross_troha
источник
1
Я использую подобный подход , но он не работает в Safari и Firefox
Стан
6

Согласно MDN ,

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

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

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

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

введите описание изображения здесь

прачечная-автомат
источник
3

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

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

Тихий пингвин
источник
1
Поведение Webkit не является неправильным, поскольку в спецификации не сказано, что должно произойти, если CR / LF существует.
Кристиан,
1
@Christian Теперь он говорит: «Пользовательские агенты должны представить эту подсказку пользователю, после того, как она убрала из нее разрывы строк ...». Это говорит об удалении разрывов строк: «Когда пользовательский агент должен вырезать разрывы строк из строки, пользовательский агент должен удалить любые символы« LF »(U + 000A) и« CR »(U + 000D) из этой строки. ».
Ричард Тернер,
Этот ответ больше не соответствует действительности. Спецификации в настоящее время явно требует , чтобы разрывы строк в заполнителе быть вынесены как переносы.
Clonkex
3

React:

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

placeholder={'Address Line1\nAddress Line2\nCity State, Zip\nCountry'}
firetiger77
источник
2

Если у вас 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>

Krzysiek
источник
1

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

<textarea id="myID" placeholder=" "></textarea>
<style>
#myID::-webkit-input-placeholder::before {
    content: "1st line...\A2nd line...\A3rd line...";
}
</style>
Джеффри Нео
источник
1

в 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>';
Влад
источник
0

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


источник
0

Bootstrap + contenteditable + многострочный заполнитель

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

основываясь на ответах @cyrbil и @daniel

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

Используя javascript «замена местозаполнителя» и добавление «css-пробел: pre» в css, отображается многострочный заполнитель.

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;
}
Миха Пирнат
источник
-1

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

(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'));
              }
            }
          }
        }
      };
    });
}());
Юра Федоров
источник