Как вставить svg в input
How to Include SVG file as background
I’m a newbie to the SVG world, just started experimenting today. I’m trying to create a mobile site where the primary graphics are all scalable, thus supporting all display resolutions.
I created an svg file for my input (currently type=»image»), and suprisingly the results are as expected in my code editor (Coda). In testing (mobile Safari, DT Safari and DT FF), the input displays broken image path placeholder (the oath is correct because I can right-click to download the file).
How do I go about including my SVG file in the (html5) document?
3 Answers 3
See Using SVG in background-image. The CSS for placing a background image in an input is the same as for any other element:
Is not currently supported across all browsers rendering engines. Or, should I say it is not supported by the browsers that people are using.
4> iframe (causes a small performance hit as page is downloaded)
5> Google’s svgweb can also be used; I have not attempted to use svgweb as a background layer, although it should work fine.
If you are not doing anything more complex than an image, No scripts etc etc. SVGWeb would display correctly across almost every browser. It uses VML to include support with older IE browsers, uses native support when available, and last but not least uses a flash interface to display the SVG.
The «more complex» difficulty is when browsers have basic native support that does not include what svgweb can do and you want to do things not supported by those browser. Then you need to force flash mode.
Стилизация текстовых полей формы
В этой статье рассмотрим различные варианты стилизации текстовых полей HTML-форм. Сначала создадим базовый вариант оформления input, а затем множество других, дополняя каждый из них небольшим количеством CSS.
Введение
Веб-формы являются неотъемлемой частью многих веб-сайтов. Они позволяют пользователю ввести те или иные данные, которые затем отправляются на сервер или обрабатываются на стороне клиента, например, для изменения интерфейса.
Исходные коды примеров расположены на GitHub в папке text-field проекта «ui-components».
Нормализация стилей
Обычно хорошей практикой считается для всех элементов включая псевдоэлементы установить box-sizing: border-box :
В этом случае браузер при рассчитывании ширины и высоты элементов будет включать в них поля (padding) и границы (border). Как правило, это сильно упрощает работу с размерами элементов, и избавляет нас от множества проблем при размещении контента.
Для того чтобы в разных браузерах отображался как можно более одинаково необходимо добавить следующее:
Базовый вариант оформления input
Для удобного добавления к элементам стилей создадим следующую HTML-разметку:
Теперь напишем стили для этих элементов. А также сразу включим в них стили для нормализации, чтобы не добавлять их отдельно:
В результате получили следующее оформление:
Стили для в состоянии фокуса (получить это состояние можно с помощью псевдокласса :focus ):
Этот набор стилей будет у нас отправной точкой для создания других.
input с иконкой
Рассмотрим пример вставки в input иконки с помощью псевдоэлементов.
Для этого дополнительно обернём элемент в
Ещё один вариант оформления:
input с активной svg-иконкой
В этом примере поместим в input иконку, на которую можно нажать.
Для этого мы также как и в предыдущем примере обернули в
Оформление выполнили так:
Ещё пример вставки иконки в input :
input с кнопкой
HTML-разметка input с кнопкой:
Расположение кнопки справа от input выполним с помощью флексов:
input с плавающим label
Разметка input с плавающим label:
Ещё один вариант с «плавающей» меткой:
input со счётчиком символов
Пример в котором под input отображается количество набранных символов и максимальная длина:
Это выполняется посредством следующего кода:
Стили для отображения состояния валидации input
Отображать сообщения пользователю или подсказки можно через
Пример валидации формы с помощью JavaScript
Т.к. мы будем сами отображать сообщения, то необходимо отключить стандартные подсказки браузера. Для этого к тегу
Клиентская проверка формы после нажатия «Отправить»:
Как сделать поле для ввода текста на svg
Не так давно, работая над web-мордой одного интересного устройства (кстати, если что, я теперь принимаю заказы на создание web-интерфейсов на svg), мне пришлось решать задачу создания полей для ввода текста. В спецификации svg такие поля отсутствуют, в интернете адекватных решений найдено не было, так что пришлось изобретать велосипед самому (на самом деле я конечно делал это не один, посильную помощь оказывал Virtual, за что ему отдельное спасибо). Велосипед в итоге был изобретён и сегодня я хочу рассказать как и на каких граблях при этом пришлось попрыгать и что в конце-концов получилось.
Итак, как я уже сказал, в спецификации svg поля для ввода текста отсутствуют. Самым оптимальным и простым мне показалось решение инжектировать поля ввода из xhml. Делается это с помощью специального тега — foreignObject. Смотрим код примера и как это выглядит:
Этот код отлично работает почти во всех браузерах и, казалось бы, что тут ещё изобретать. Но не всё так просто. При попытке прочитать или записать введённый в поле input текст нас ожидают первые грабли. И заключаются они в том, что value — это не атрибут, а свойство объекта input.
Ещё раз повторюсь, value — это свойство, а значит правильный доступ к нему вот такой — document.getElementById(‘text_id’).value
Теперь давайте перепрыгнем на другие грабли, — попробуем расположить какой-нибудь svg-объект над нашим инжектированным объектом input. Скажем, сделаем выпадающее меню, которое при открытии будет перекрывать input. Смотрим код и пример ниже.
Как видите, судя по коду, выпадающее меню должно располагаться над инжектированным полем ввода. Однако легко убедиться, что на самом деле этого не происходит (покликайте на кнопке Menu). Вместо этого объект input «просвечивает» через svg-элементы и оказывается на переднем плане.
Здесь всё оказалось немного сложнее. Как выяснилось, перекрыть поле input не удаётся вообще никакими svg-элементами. Тогда было решено, что раз нельзя это поле перекрыть, то его нужно стереть. В svg для этого есть специальный атрибут — display, который при установке значения в none просто не отрисовывает соответствующий объект на экране вместе со всеми дочерними объектами (выше мы им уже пользовались для скрытия пунктов выпадающего меню).
То есть, идея следующая, — будем показывать на экране поле input не постоянно, а только тогда, когда нам это действительно нужно (когда реально нужно отредактировать текст). Всё остальное время, будем показывать на месте поля input обычный svg-текст, содержимое которого совпадает с содержимым поля input (а само поле input будем с экрана стирать).
Сразу замечу, что скрывать поле ввода, делая его невидимым с помощью свойства visible или атрибута opacity смысла не имеет, — оно всё равно будет располагаться над всеми остальными элементами, просто вы не будете видеть, что туда вводите (невидимость же, ага).
Итак, осталось только решить, как определять, когда пользователю нужно отредактировать текст, а когда нет (то есть когда нужно менять местами на экране поле input и svg-текст).
Я предлагаю следующий вариант. Если пользователь пытается кликнуть по тексту мышью (событие onclick объекта svg-текст) — значит нужно переключаться в режим редактирования (скрывать svg-текст и показывать поле input), если поле ввода потеряло фокус (событие onblur объекта input) — нужно переключаться в режим отображения svg-текста (и скрывать поле input).
Сразу скажу, что тут есть ещё несколько видов граблей.
Первые связаны с тем, что для того, чтобы потерять фокус — нужно сначала получить фокус. А если мы при клике по svg-тексту будем просто выключать svg-текст и включать xhtml поле input, то это вовсе не означает, что оно сразу получит фокус. Не получит. Фокус перейдёт на это поле только после того, как вы по нему кликните, а пока вы его просто включили.
Следовательно и потерять фокус поле input сможет не раньше, чем вы по нему кликните и передадите ему таким образом фокус. Помните, как в «Простоквашино», — Чтобы продать что-нибудь ненужное, — нужно сначала купить что-нибудь ненужное, а у нас денег нет!
Думаю не нужно долго объяснять к чему это может привести. Если вы, к примеру, кликнули по svg-тексту (и включили таким образом отображение поля input), а затем передумали и кликнули по выпадающему меню, — поле input не сможет снова поменяться местами с svg-текстом (оно же не теряло фокус) и опять будет просвечивать через меню.
Чтобы избежать возникновения подобной коллизии, — нужно принудительно устанавливать фокус на поле input в той же функции, которая делает это поле видимым. Делается это вызовом метода focus() для объекта input.
Вторые грабли связаны с переменными размерами svg-текста, зависящими от размера и количества символов в этом тексте. То есть, если мы в поле input введём пустое значение (сотрём в нём весь текст) и потом это пустое значение перезапишется в svg-текст, то этот svg-текст будет иметь нулевую ширину. Ну и как потом по нему кликнуть, чтобы снова перейти в режим редактирования?
Для решения этой проблемы можно сделать над svg-текстом прозрачную накладку фиксированной ширины (равной размеру поля ввода) и выполнять переход в режим редактирования после клика по этой накладке, а не по svg-тексту. Естественно, эту накладку нужно включать и выключать вместе с svg-текстом.
Ниже приведён пример полностью рабочего кода и того, как это будет выглядеть на экране.
Вот и всё, надеюсь эта информация кому-нибудь пригодится. Если просто захотите обсудить те или иные аспекты работы с svg — жду на форуме или в комментариях. Тема достаточно обширная и интересная.
Понравилась статья? Поделись с друзьями!
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.
How to add a SVG icon within an input?
I need to place icons within the inputs for creating a new user. It’s probably a really easy task for someone who knows their way around front end code. However I don’t. Here is the wireframe and then I show my code.
WIREFRAME
As you can see. There are icons on the left side of the inputs. Right now I have the SVG’s in my directory and ready to go I just need to know how to place them within the input. Here is the code for the form
So I have the placeholder with a string which currently just printing that string. I need to put the icons within that I think? Here is the css I have for the icons.
Is there a way I can place these classes within the place holder?
4 Answers 4
You can add a pseudo element in the tag, and use some position and padding tricks for the visual. Using a svg for background is just the same as using an image.
You can create an SVG spritesheet for svg icons.
Now, to address your question. I see a few issues with your setup.
I believe you’re trying to do this the wrong way, using a instead of handling this with CSS directly on the input itself. If you can provide the above information then I’ll be able to provide a more appropriate solution.
Спойлер: Вставка SVG иконок одним единственным способом
В статье будет обсуждаться проблема вставки SVG иконок в веб — страницу.
Что мы имеем, и как мы используем это. Глобально есть три способа:
Приведу пример:
Есть у нас иконка — звездочка для рейтингов. Где-то она белая, где-то желтая, большая и маленькая. Плюс может быть обрезанная половинка звездочки, скажем, для обозначения рейтинга 2.5 или 4+.
Для реализации данного примера нам нужно как минимум четыре PNG иконок для каждого цвета и формы, но если у нас SVG, то вместо четырех мы спокойно можем обойтись и одной единственной, специально оформленной для данной задачи и не только.
Нашу звездочку можно прямо вставить в DOM и с помощью стилей оформить ее так, как нам нужно. Это первый вариант, знакомая нам практика.
В первом варианте из достоинств можно перечислить удобное управление элементами графики, анимацию отдельных частей иконки и т.п., полное управление SVG тегами. Из недостатков первое, что в этом случае мы получаем большой размер DOM, что по некоторым причинам является не совсем хорошим феноменом. Вторым недостатком, по сравнению с третьим вариантом, является то, что размер, позиционирования (центровка по вертикали и горизонтали) является в некоторых случаях не тривиальной задачей.
А что насчет второго варианта, то он самый избыточный, так как не имеет ни одного из достоинств двух других вариантов.
Что у нас получается? Мы имеем два варианта вставки иконок, у которых есть свои достоинства и между которыми иногда бывает сложно сделать выбор.
А теперь представьте, что вы можете использовать почти все достоинства (кроме анимации отдельных частей иконки) первого варианта наряду с третьим вариантом.
То есть вставлять иконки с помощью CSS background-image, или HTML тега IMG, и по вашему усмотрению изменить цвет каждого тега в SVG, будь то path, polygon или circle, не имеет значения.
Вот как это будет выглядеть:
Думаю, что идея ясна, синтаксис уже зависит от настроек сервера, а над реализацией еще надо поразмышлять.
Тут ссылка того, как я решил для себя эту проблему. Приветствуются любые решения, если они крутые.
Как это работает
Пример использования данной реализации.
С точки зрения перформанса это не самая лучшая идея, даже если будет кэш, все равно это уже не будет выдача статика, там уже все равно будет работать скрипт, хотя можно использовать такую вставку только тогда, когда нужен другой цвет для иконки, но для больших проектов, где иконки становятся головной болью и в этом притоне не найдешь даже родного брата, то как по моим наблюдениям для таких проектов, пока что такой вариант может считаться — best practice.