LINUX.ORG.RU

[css ninja required] идеальные формы


0

0

Привет, лор. В шаблонах много форм вида

                  ______________
поле номер один  |______________|
       ^                  ^
  название поля    собственно один <input>
                   они бывают разные, но 
                   чаще всего type="text"

 

Делал давно, на скорую руку — поэтому все обернуто в таблицы. Синтаксис xslt сам по себе не назовешь компактным, а тут еще эти километровые таблицы... в общем, надоело листать туда-сюда простыню текста.

На смысловую нагрузку наплевать (да-да, я знаю, что это плохо), хочется по минимуму убрать лишние теги из шаблона. Для этого нужно создать правила для тегов <form> и <input>.

Вопрос такой: возможно ли как-то выбрать с помощью селекторов бокс с текстом, при условии, что в разметке он не выделен?

Как видите, в css я мало что понимаю. Пока что сделал так:

form {
    display:block;
    float:left;
    padding: 0.5em;
}

.el {
    display:block;  // наверное можно и не применять, див же
    margin: 5px;
}

.el input {
    float:right;
    margin-left: 20px;
}

В шаблоне форма выглядит таким образом:

<form>
  <div class=el>название поля <input type="text"></div>
  <div class=el>название поля <input type="text"></div>
  <div class=el>название поля <input type="text"></div>
  <div class=el><input type="submit"></div>
</form>

Не идеально (остается лишний код <div class=el>), но уже на порядок лучше — шаблоны стали короче раза в два и читаются проще.

Помогите :Е

Ставь класс общему предку, для всех инпутов одного вида.

Если наплевать на IE6, то, input[type="text"] { blah blah } Не помню, работает ли это в IE7.

Deleted
()
Ответ на: комментарий от Deleted

>Ставь класс общему предку, для всех инпутов одного вида.

Поясни?


>input[type="text"] { blah blah }

Так у меня сейчас фактически тоже самое: инпуты я могу выбрать без проблем.


Я хочу, чтобы "название формы" и "<input> любого типа" подчинялись следующим правилам, если выразить их словами:


1) Если слева (т.е перед) <input> есть текст, то он
  — становится боксом с display: block; 
  — прижимается к левому краю родительского бокса 

2) <input> любого типа 
  — прижимается к правому краю родительского бокса
  — после него начинается новая строка


Может быть это невозможно? 

portalgun
() автор топика

<form>
    название поля <input type="text"><br>
    название поля <input type="text"><br>
    название поля <input type="text"><br>
    <input type="submit">
</form>

Не?

Ну и для form написать стиль, типа:

form {
    display:block;
    float:left;
    margin: 5px;
}

mavirtual
()
Ответ на: комментарий от portalgun

<form>
    <div class="foo">
        <div><label>название поля <input type="text"></label></div>
        <div><label>название поля <input type="text"></label></div>
        <div><label>название поля <input type="text"></label></div>
    </div>
    <div><input type="submit"></div>
</form>

.foo div {}
.foo input {}

label опционален, но позволяет при клике на текст фокусировать ассоциированный элемент автоматически.

P.S. На блоки display: block таки не надо ставить.

Deleted
()
Ответ на: комментарий от Deleted

А, понятно. Тогда раз от <div> все равно не избавиться, возьму какой нибудь ненужный тег из 1 символа.

portalgun
() автор топика
Ответ на: комментарий от mavirtual

>Не?

Не. Будет невыровнено по краям (если строки разные то получится лесенка), да и <br> тут немного не в тему.

portalgun
() автор топика
Ответ на: комментарий от portalgun

Вот так будет работать, проверил:

<html>
<head>
<style type="text/css">
form {
	width: 300px;
	line-height: 25px;
}

form input {
	margin-left: 300px;
	position: absolute;
}

</style>
</head>

<body>
<form>
  <input type="text">название поля<br>
  <input type="text">длинное название поля длинное название поля длинное название поля<br>
  <input type="text">название поля<br>
  <input type="submit">
</form>
</body>
</html>

Только нужно знать изначально ширину блока.

mavirtual
()
Ответ на: комментарий от portalgun

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<title>abc</title>
<style type="text/css">
form {
	width: 300px;
	line-height: 25px;
}

form input {
	margin-left: 300px;
	position: absolute;
}
</style>
</head>

<body>
<form action="/">
  <input type="text">название поля<br>
  <input type="text">длинное название поля длинное название поля длинное название поля<br>
  <input type="text">название поля<br>
  <input type="submit">
</form>
</body>
</html>

Теперь не будет :)

mavirtual
()
Ответ на: комментарий от mavirtual

Насколько я помню, это и для HTML верно.

Deleted
()

в общем, финальный вариант оставил такой: 


.superform  {
    display:block;
    float:left;
}

.superform i{
    font-style:normal;
    display:block;
    margin: 5px;
}

.superform i input {
    float:right;
    margin-left: 20px;
}



Соответственно,

<form class="superform">
     <i>1st <input type="text"></i>
     <i>2nd <input type="text"></i>
     <i>3rd <input type="text"></i>
     <i>4th <input type="text"></i>
     <i>5th <input type="text"></i>
     <i><input type="submit"></i>
</form>


Жаль все-таки, что через css нельзя выбрать "предыдущий к выбранному бокс". Тогда можно было бы убрать теги совсем.

portalgun
() автор топика
Ответ на: комментарий от portalgun

Зачем тебе убирать тэги совсем? Твои клиенты сидят на 9600 бит/с?
Если нет, то некоторая избыточность в твоём случае была бы даже полезной.

Например, я бы сделал так (многа букаф):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Избыточная вёрстка формы</title>
    <style type="text/css">
      .form-wrap {
        width: 80%;
      }
      .form {
        width: 60%;
	margin: 20px auto;
	padding: 5px;
      }
      .form-row {
        overflow: hidden;
        margin-bottom: 5px;
      }
      .form-label-wrap {
        float: left;
	width: 30%;
      }
      .form-input-wrap {
        text-align: right;
        margin-left: 33%;
      }
      .form, .form-row, .form-label-wrap, .form-input-wrap {
        padding: 5px;
	border: 1px solid #ccc;
      }
      .align-center {
        text-align: center;
      }
    </style>
  </head>
  <body>
    <div class="form-wrap">
      <form class="form" action="/submit.php">
      
        <div class="form-row">
          <div class="form-label-wrap">
            <label for="input-1" class="form-label">Текстовое поле</label>
          </div>
          <div class="form-input-wrap">
            <input id="input-1" class="form-input-text" type="text"/>
          </div>
        </div>
	
        <div class="form-row">
          <div class="form-label-wrap">
            <label for="input-2" class="form-label">Чекбокс</label>
          </div>
          <div class="form-input-wrap">
            <input id="input-2" class="form-input-checkbox" type="checkbox"/>
          </div>
        </div>
	
	<div class="form-row">
	  <div class="form-label-wrap">
	    <label for="input-3">Текстареа</label>
	  </div>
	  <div class="form-input-wrap">
	    <textarea id="input-3" class="form-input-textarea" rows="5" cols="20"></textarea>
	  </div>
	</div>
	
	<div class="form-row align-center">
          <input class="form-submit" type="submit" value="Послать"/>
          <input class="form-reset" type="reset" value="Сбросить"/>
	</div>
	
      </form>
    </div>
  </body>
</html>

Преимущества:
  — максимальная отделённость вёрстки от представления (стилей)
  — возможность максимально гибко управлять отображением формы
  — для изменения вида формы не нужно лезть код, её генерирующий, достаточно изменить стиль
  — проще организовать совместную работу программера и дизайнера/верстальщика
  — длинные названия классов позволяют избежать дублирования при внедрении своего кода в существующие проекты
  — структура классов упрощает поиск элементов с помощью библиотек типа jQuery
  — блоки-обёртки позволяет избежать переопределения инлайн-элементов (label, input) как блочных
  — все валидно, семантично и кросс-платформенно.

Дело, конечно, сугубо индивидуальное, но я за свою 5-летнюю практику пришёл именно к такому подходу.

Кстати, у меня такие формы (и ещё более навороченные) замечательно строятся с помощю XSLT.

theSoul ★★★
()
Ответ на: комментарий от portalgun

.superform { display:block; float:left; }

Зачем это? Форма и так блочный элемент. И float:left для решения данной задачи никак не поможет.

Вместо <i> используй тег <label>. Он именно для этого и предназначен, да и блочный он искаропки, в отличие от.

А вообще формы удобнее всего верстать в <dl/>.

anonymous4
()
Ответ на: комментарий от anonymous4

>.superform { display:block; float:left; } >Зачем это? Форма и так блочный элемент.

А мужики то не знают. Это для того, чтобы открыть <form>, а потом сделать в три столбика формы, в последний столбик поставить сабмит и закрыть </form>

>Вместо <i> используй тег <label>. Он именно для этого и предназначен, да и блочный он искаропки, в отличие от.

ололо

portalgun
() автор топика
Ответ на: комментарий от theSoul

>Зачем тебе убирать тэги совсем? Твои клиенты сидят на 9600 бит/с? >Если нет, то некоторая избыточность в твоём случае была бы даже полезной.

Ребят, я конечно понимаю, что чукча не читатель и это лор где принято вместо ответа типа "да\нет" выдавать свой вариант, когда он никому не нужен:) но зачем мне это я написал в 1 посте.

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

portalgun
() автор топика
Ответ на: комментарий от portalgun

> чукча не читатель

Сам ты чукча.

> зачем мне это я написал в 1 посте.

Интересно посмотреть твой код. Если у тебя «простыня текста», то скорее всего ты свои формы хардкодишь вручную, и для каждого элемента формы тебе приходится повторять все окружающие тэги. Тогда получается, что либо ты используешь XSLT не по назначению, либо просто не умеешь им пользоваться.

Нормальные люди сначала описывают структуру данных, для которой требуется построить форму, а потом пишут шаблоны для преобразования этой структуры в код формы. Тогда абсолютно никакого значения не имеет количество окружающих тэгов, т.к. они задаются один раз в одном-двух шаблонах. Для изменения самой формы надо просто изменить её описание, не трогая сами шаблоны.

Впрочем, не флейма ради. Я ничего не навязываю, в конечном счёте с твоим кодом тебе самому работать. Просто ИМХО.

theSoul ★★★
()
Ответ на: комментарий от theSoul

Мне стало интересно, что ты имеешь ввиду. Да, у меня формы все вручную забиты и их очень много. Дай линк какой-нить.

portalgun
() автор топика
Ответ на: комментарий от portalgun

Например, создаем какую-нибудь текстовую запись. 

Код грубо говоря такой:


<xsl:template match=класс and (method=создать or method=редактировать)]/result">
  <form>
    <input name=заголовок>
    <input name=автор>
    <input name=текст>
    <input type=submit>
  </form>
</xsl:template>

что я делаю не так? 

portalgun
() автор топика
Ответ на: комментарий от portalgun

Линк не дам, т.к. сам инфу искал давно, букмарков нет. Дам простой пример, но не сейчас, а ближе к вечеру, сейчас нет времени всё обстоятельно изложить. Так что до вечера.

theSoul ★★★
()
Ответ на: комментарий от portalgun

осталось понять, как исключить их из потока... флоат они, кажется, не наследуют.

portalgun
() автор топика
Ответ на: комментарий от Deleted

Правда от этого элемент не становится блоковым. Только его отображение.

Deleted
()
Ответ на: комментарий от Deleted

>Ну, если тебя не тревожит то, что input type="submit" тоже будет блок, то можно и так

Мне нужно все было блоковое и побольше, побольше:)

portalgun
() автор топика
Ответ на: комментарий от theSoul

Сорри, вчера не успел.

Итак, православный метод построения веб-форм с помощью XSLT.

Схема структуры данных (http://pastebin.ca/1494409):

<?xml version="1.0" encoding="UTF-8"?>
<form>
	<field type="text" id="input-one" name="one" label="Текстовое поле"/>
	<field type="checkbox" id="input-two" name="two" label="Чекбокс"/>
	<field type="textarea" id="input-three" name="three" label="Текстареа"/>
</form>

--------------------

Шаблон (http://pastebin.ca/1494410):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

	<xsl:output encoding="UTF-8" indent="yes" method="xml" omit-xml-declaration="yes"/>

	<xsl:param name="form-action" select="'/submit.php'"/>
	<xsl:param name="form-class" select="'form'"/>
	<xsl:param name="wrap-form-class" select="'form-wrap'"/>
	<xsl:param name="wrap-row-class" select="'form-wrap-row'"/>
	<xsl:param name="wrap-buttons-class" select="'form-wrap-buttons'"/>
	<xsl:param name="wrap-label-class" select="'from-wrap-label'"/>
	<xsl:param name="wrap-input-class" select="'form-wrap-input'"/>
	<xsl:param name="label-class" select="'form-label'"/>
	<xsl:param name="input-class" select="'form-input'"/>

	<xsl:template match="/">
		<xsl:apply-templates select="form" mode="wrap-form"/>
	</xsl:template>
	
	<xsl:template match="form" mode="wrap-form">
		<div class="{$wrap-form-class}">
		<xsl:apply-templates select="."/>
		</div>
	</xsl:template>
	
	<xsl:template match="form">
		<form action="{$form-action}" class="{$form-class}">
		<xsl:apply-templates select="*" mode="wrap-row"/>
		<div class="{$wrap-buttons-class}">
		<input type="submit"/>
		<input type="reset"/>
		</div>
		</form>
	</xsl:template>
	
	<xsl:template match="field" mode="wrap-row">
		<div class="{$wrap-row-class}">
		<xsl:apply-templates select="." mode="wrap-label"/>
		<xsl:apply-templates select="." mode="wrap-input"/>
		</div>
	</xsl:template>
	
	<xsl:template match="field" mode="wrap-label">
		<div class="{$wrap-label-class}">
		<xsl:apply-templates select="." mode="label"/>
		</div>
	</xsl:template>

	<xsl:template match="field" mode="wrap-input">
		<div class="{$wrap-input-class}">
		<xsl:apply-templates select="." mode="input"/>
		</div>
	</xsl:template>
	
	<xsl:template match="field" mode="label">
		<label for="{@id}" class="{$label-class}">
		<xsl:value-of select="@label"/>
		</label>
	</xsl:template>
	
	<xsl:template match="field" mode="input">
		<input type="{@type}" id="{@id}" class="{$input-class}-{@type}"/>
	</xsl:template>
	
	<xsl:template match="field[@type = 'textarea']" mode="input">
		<textarea id="{@id}" class="{$input-class}-{@type}">
		<xsl:text><![CDATA[]]></xsl:text>
		</textarea>
	</xsl:template>

</xsl:stylesheet>

-----------------

Результат (http://pastebin.ca/1494412):

<div class="form-wrap">
  <form action="/submit.php" class="form">
    <div class="form-wrap-row">
      <div class="from-wrap-label">
        <label for="input-one" class="form-label">Текстовое поле</label>
      </div>
      <div class="form-wrap-input">
        <input type="text" id="input-one" class="form-input-text"/>
      </div>
    </div>
    <div class="form-wrap-row">
      <div class="from-wrap-label">
        <label for="input-two" class="form-label">Чекбокс</label>
      </div>
      <div class="form-wrap-input">
        <input type="checkbox" id="input-two" class="form-input-checkbox"/>
      </div>
    </div>
    <div class="form-wrap-row">
      <div class="from-wrap-label">
        <label for="input-three" class="form-label">Текстареа</label>
      </div>
      <div class="form-wrap-input">
        <textarea id="input-three" class="form-input-textarea"></textarea>
      </div>
    </div>
    <div class="form-wrap-buttons">
      <input type="submit"/>
      <input type="reset"/>
    </div>
  </form>
</div>

-----------------

Проверяется так: xsltproc sample.xsl sample.xml

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

На первый взгляд может показаться слишком навороченным, но это не так, да и намного лучше километровых рулонов кода.

— чтобы добавить новые поля в форму, достаточно изменить схему
— можно добавлять новые типы (см. последний шаблон)
— названия классов вынесены в параметры шаблона, думаю, не надо объяснять, зачем
— изменить структуру выводимой формы тоже не составляет труда, надо только поправить шаблон в соответствующей части
— самое нетрвиальное, но вполне реализуемое — это наполнение формы данными для редактирования (здесь не показано)
— лейблы и инпуты связаны, то есть при клике на лейбл, инпут получает фокус

Структура файла схемы — личное дело каждого. Я, например, использую XML Schema, хотя оно и громоздко.

PS: возможно, в ближайшие месяц-два выложу в открытый доступ свою библиотеку с блэкджеком и шлюхами
(http://pic.ipicture.ru/uploads/090714/VDJylVoVGx.png).

theSoul ★★★
()
Ответ на: комментарий от Deleted

Библиотеку для генерирования (X)HTML кода форм из описания структуры данных в XML Schema. То есть:

XML Schema -> XSLT -> (X)HTML

Валидация, табы, поддержка тем и другие приятные и полезные штуки также имеются. По ссылке в моём предыдущем посте можно увидеть результать её работы.

theSoul ★★★
()
Ответ на: комментарий от theSoul

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

Deleted
()
Ответ на: комментарий от theSoul

Охщи~, спасибо. В таком случае наверное стоит извиниться за резкость ^_^ Будем разбираться.

portalgun
() автор топика
Ответ на: комментарий от Deleted

> Свисти громче, коли выкладывать будешь — поглядим что там, глядишь, пригодится когда-нибудь.

Ок. В принципе, либа готова, API более-менее устаканен, осталось только сделать под неё сайт, а на это катастрофически не хватает времени.

theSoul ★★★
()
Ответ на: комментарий от portalgun

Гуглокод пойдёт, но кому оно надо без описания и примеров? Вот для этого и надо найти время.

theSoul ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.