Does anyone have a generic CSS rule set for styling Drupal forms so that the field labels appear inline with their fields? I've worked on some projects where forms needed to be styled that way and while I've been able to get them working I've not been overly satisfied with the end result. I'm hoping that someone with more CSS chops might have already conquered the problem and be willing to share their solution.
I wrote a rough proof-of-concept Drupal module to apply Uni-Form CSS markup to Drupal forms, but for a variety of reasons (see "Uni-form Cons" below), it ended up being more kludgey than I had hoped. Does anyone have a more Drupal-specific CSS file, that I might use in the module instead of Uni-Form? If not, is anyone interested in working with me to come up with one?
Uni-form Cons
* Drupal's default form output isn't what Uni-Form expects, so there was a fair amount of theme overriding required.
* The Uni-Form inlineLabel styling doesn't seem to work well for fields with more than 2 or 3 checkboxes or radio buttons.
* Uni-Form's "blockLabels" style is similar to Drupal's default style, so about half of the Uni-Form CSS is superfluous within Drupal.
* Uni-Form is CreativeCommons licensed, so it would have to be downloaded separately.
* Uni-Form also includes a jquery script for highlighting fields, but it requires that the Jquery Update module be applied in order to work properly.
Comments
overriding a theme function
Not only the css can be tweaked, but you can override the way drupal output each form item.
on api.drupal.org, look for the theme function that create the form item :
http://api.drupal.org/api/function/theme_form_element/5
it looks like this :
<?php
function theme_form_element($element, $value) {
$output = '<div class="form-item">'."\n";
$required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
if (!empty($element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' <label for="'. $element['#id'] .'">'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
else {
$output .= ' <label>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
}
$output .= " $value\n";
if (!empty($element['#description'])) {
$output .= ' <div class="description">'. $element['#description'] ."</div>\n";
}
$output .= "</div>\n";
return $output;
}
?>
Now you just need to drop this into your template.php file, replace 'theme_form_element' by '[name of your theme]_form_element' to activate it for your theme, and adapt the output markup as needed.
Then you can add your custom css :)
The Drupal Agency >> www.raincitystudios.com <<
Me on the Web >> www.couzinhub.com <<
thanks
Thanks for the response. I was aware of the ability to override theme output, but have you used that technique to output form field labels to appear inline with their fields. If so, do you have any code examples for that? It appears that the code above is the original theme_form_element() function, not an override example.
Also, when doing the overriding at the theme layer like that, is there an easy way to avoid having it rewrite all form output? In most cases, I'd like to avoid overriding Drupal's built-in administration forms.
When you're using a theme
When you're using a theme function, you just define what's going to be output by this function. So if you just need to change the label, find which theme function outputs them, and just twaek it in your template.php.
The thing is that if you only want to modify the template of the label, you have to use the entire theme function that contains the output for the label. You can't, in drupal 5, only decide to modify the label. But the function above is really only for label and descrption, so it's very close to what you want I think.
for example, in the following, I just modify the function so the label is just a span, so it becomes inline :
<?php
function theme_form_element($element, $value) {
$output = '<div class="form-item">'."\n";
$required = !empty($element['#required']) ? '<span class="form-required" title="'. t('This field is required.') .'">*</span>' : '';
if (!empty(
$element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' <span>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</span>\n";
}
else {
$output .= ' <span>'. t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</span>\n";
}
}
$output .= " $value\n";
if (!empty(
$element['#description'])) {
$output .= ' <div class="description">'. $element['#description'] ."</div>\n";
}
$output .= "</div>\n";
return
$output;
}
?>
Hi
Hi,
Can we apply uniform- css to drupal forms.Just i tried it.I am not getting any idea about this.If you don't mine,please send some of the samples.
How I applied uniform-css in drupal themes?
Thanks in advance Matt
Regards,
Raj.
one example...
(Tested in Drupal 6)
For a specific field I just use
.field-class label, .field-class
{
display: inline;
}
For multiple fields you can try replacing .field-class with something more generic, like .form-item. Each field is structured more or less like this:
<div class="form-item" id="edit-field-name-wrapper">
<label for="edit-field-name">Name: </label>
<input maxlength="x" name="name" id="edit-field-name" size="y" value="z" class="form-text" type="text">
</div>
Where "field-name" is your field's name as it appears in the $form (between brackets [ and ]).
You could also prefix and suffix the form element with your class of choice if you have control over the form.
Depending on the needs, I either put the CSS in the theme, or in a separate CSS file and add it in my module only on specific pages. Hope this helps!
I'm no CSS expert, so if anyone has better suggestions, feel free to jump in.
Drupal 5 css version
I needed to do this for the user registration form without changing any other forms, and used this CSS:
#user-register label, #user-register .form-text {
display: inline;
}
#user-register .form-text {
position: absolute;
left: 320px;
}
(using Drupal 5.11, tested in FF3 and IE6, not got round to testing IE7 yet)
Hi Matt, I'm just in the
Hi Matt,
I'm just in the process of styling inline forms using CSS only. Here's what I'm using. This is sized for my particular needs and the only non-standard thing is that description is hidden as I'm using JQuery to show the description when the user hovers over the field.
.form-item {
position: relative;
display: block;
width: 100%;
font-size: 80%;
padding-top: 3px;
clear: both;
}
.form-item label {
width: 50%;
float: left;
display: inline;
text-align: right;
}
.form-item .form-text {
width: 40%;
float: left;
margin-left: 10px;
display: inline;
border: 1px solid #ccc;
}
.form-item textarea {
clear: both;
width: 100%;
display: block;
font-size: 110%;
border: 1px solid #ccc;
}
.form-item .description {
position: absolute;
left: 10%;
width: 200px;
display: none;
background-color: #caff9b;
}
.form-item .form-select {
margin-left: 10px;
}
Rearranging '*' and title
What if I wanted the required asterisk (*) to come before the label for the field instead of after?
I thought I could just rearrange the items in the array; e.g.:
change:
<?php
if (!empty($element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' <label for="'. $element['#id'] .'">'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
else {
$output .= ' <label>'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
}
?>
to:
<?php
if (!empty($element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' <label for="'. $element['#id'] .'">'. $t('!title: !required', array('!required' => $required, '!title' => filter_xss_admin($title))) ."</label>\n";
}
else {
$output .= ' <label>'. $t('!title: !required', array('!required' => $required, '!title' => filter_xss_admin($title))) ."</label>\n";
}
}
?>
But that didn't have any affect. Any ideas?
UPDATE
Doh! Here's the solution for anyone else who is looking:
<?php
if (!empty($element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' <label for="'. $element['#id'] .'">'. $t('!required!title:', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
else {
$output .= ' <label>'. $t('!required!title:', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
}
?>
That last little block worked
That last little block worked for me . Thanks.
some jscript is required?
i think :
- api > first required
- css> 2nd
- and need some script to it seem as dynamic and awesome style?
are you sure?
(im just a noob :D)
húyon
Style input parent's label when input:checked, and remove input
I'm trying to get this hover and checked effect on my Drupal site's left columns forms.
I've searched all over the web and found:
None of the above could helped me achive it, or, possibly, I'm not reading well!
The code I'm getting with firebug is as follow:
<div>
<label>
<input />
</label>
</div>
What I'm looking for is to syle label when input:checked.
I've read the post, and if I were to rearange my fields... where I have to do it?
Kayo Graco
Interesting solution for D6
Here's what worked for us:
<div class="form-radios-horiz">
<div class="clear"></div></div>
.form-radios-horiz .form-item label {
float: left;
margin-right: 0.5em;
}
.form-radios-horiz .form-item .form-radios .form-item label {
float: left;
margin-right: 2em;
}
.clear {
clear: both;
}
function theme_form_element($element, $value) {
// This is also used in the installer, pre-database setup.
$t = get_t();
$output = '<div class="form-item"';
if (!empty($element['#id'])) {
$output .= ' id="'. $element['#id'] .'-wrapper"';
} elseif (!empty($element['#parents'][0])) {
// !!! supply an alternate div ID for field collections
$output .= ' id="'. form_clean_id($element['#parents'][0]) .'-wrapper"';
}
$output .= ">\n";
$required = !empty($element['#required']) ? '<span class="form-required" title="'. $t('This field is required.') .'">*</span>' : '';
if (!empty($element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' <label for="'. $element['#id'] .'">'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
else {
// !!! New D6 implementation to target aggregate/fieldgroup labels: if the element has no #id, add a class to the label (using the "parent" id to get fieldgroup name)
$labelClassShim = (empty($element['#parents'][0])) ? '' : ' class="' . $element['#type'] . '-label ' . $element['#type'] . '-label-' . form_clean_id($element['#parents'][0]) . '"';
$output .= ' <label' . $labelClassShim . '>'. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."</label>\n";
}
}
$output .= " $value\n";
if (!empty($element['#description'])) {
$output .= ' <div class="description">'. $element['#description'] ."</div>\n";
}
$output .= "</div>\n";
return $output;
}
.radios-label-field-some-fieldname {
min-width: 10em;
}
I'm still working on how to get labels to wrap when the text exceeds a certain width.
For D7 I used
For D7 I used this for views - maybe helpful for someone:
.views-label {font-weight:bold; float-left;margin-right:5px;}
The usual problem is that the
The usual problem is that the labels, when placed inline, have different width, thus making the forum look ugly. To correct the mickC's code:
.views-label {
font-weight: bold;
float: left;
margin-right: 5px;
width: 200px;
/* width: 64em; */
}
Inline labels
Another great thread that has solved the problems with my D7 site. Thanks to allow.
Overriding the standard "label" tag for inline labels affects all the labels, and generally screws up login forms, admin forms and so on. I wanted to override the labels on my customised node forms only.
Einschit's solution above worked for me. Instead of overriding "label", I overrode .xxx label in the template css file, using Firebug to identify the label names and the associated fields.
For example, this gives a nicely aligned set of edit fields for my node.
.form-item-title label,
.form-item-field-status-und label,
(...etc...)
{
margin-top: 0em;
clear: none;
float: left;
width: 10em;
display:inline;
}
This will help for a specific
This will help for a specific form where you know the width of the labels. Otherwise, will have to have fingers crossed that the label text does not stretch further than the 10em. Which criticism also applies to my response above, of course.
Agreed
The width depends on the label size and needs to be checked. But this should be a "once-only" design decision?
Unless client will create forms
It may change if you are building a website for the client, who will want to add more forms. But that is a separate occasion that will need to be treated separately, I agree.