zendframework / zend-form

Form component from Zend Framework
BSD 3-Clause "New" or "Revised" License
69 stars 87 forks source link

Input element rendered inside label element screws up Twitter Bootstrap #149

Closed bitwombat closed 7 years ago

bitwombat commented 7 years ago

While it's valid HTML for the label to contain the input element, or not, Bootstrap seems to be opinionated and not correctly render an input element that's inside a label element.

See: http://codepen.io/gbell12/pen/ZerEwq

If I use $this->formLabel and formElement instead of $this->formRow, I can control this, but that's a lot of places to unroll $this->formRow...

bitwombat commented 7 years ago

I see in the source that if there's an id attribute, it won't wrap the input element inside the label.

What is the purpose of that behavior?

Creating a unique id for all of my fields in each fieldset and/or form doesn't sound too appealing.

froschdesign commented 7 years ago

Creating a unique id for all of my fields in each fieldset and/or form doesn't sound too appealing.

You can use the id attribute or create your own formRow view helper.

bitwombat commented 7 years ago

Thanks @froschdesign. I think the logic is that a label doesn't know which input element it belongs to unless:

1) It wraps that element 2) It has a for= pointing to the id of that element.

That's fine, but the HTML spec doesn't require a label to know its element.

I'm happy to create my own formRow and/or use id's everywhere. Just wondering if this behavior is what the devs desired (or if the Bootstrap hiccup is worth caring about).

froschdesign commented 7 years ago

…but the HTML spec doesn't require a label to know its element.

Sorry, I don't understand what you mean.

The label element is required to associate text labels with a form control. Otherwise the text has no semantic meaning and no relation to a form element. The HTML spec are defined two options for the creation a relation between a label and a form control:

  1. implicit – the label element as wrapper for the input element
  2. explicit – the label element with a for attribute

Just wondering if this behavior is what the devs desired

This is the desired behaviour.

bitwombat commented 7 years ago

The label element is required to associate text labels with a form control.

Labels can be unassociated and still be valid HTML. The codepen I posted originally validates.

From the spec:

"The caption can be associated with a specific form control..." "Except where otherwise specified by the following rules, a label element has no labeled control..."

zend-form is forcing a conformance that isn't required by the spec, and that Bootstrap isn't expecting. That's my point. The semantic meaning of a label adjacent to an input is still clear.

froschdesign commented 7 years ago

Labels can be unassociated and still be valid HTML. … The semantic meaning of a label adjacent to an input is still clear.

Fine, here we have the same opinion.

zend-form is forcing a conformance that isn't required by the spec, and that Bootstrap isn't expecting.

What do you want to change?

bitwombat commented 7 years ago

What do you want to change?

I'm not sure. If the logic is trying to enforce something that's not part of the spec, why does it? Maybe it shouldn't.

Plus, the element having an 'id' attribute isn't sufficient... there needs to be a for= in the label for them to be connected.

Maybe there should be a label option called "enclose" that determines whether it encloses the input element or not.

froschdesign commented 7 years ago

If the logic is trying to enforce something that's not part of the spec…

Sorry, but must ask again: What is not a part of the spec? What makes zend-form wrong?

bitwombat commented 7 years ago

It is not a requirement that labels enclose input elements when there is no id/for matching.

froschdesign commented 7 years ago

It is not a requirement that labels enclose input elements when there is no id/for matching.

Sure, but without a for attribute on an explicit label you have no association between caption and element. And do not forget, this label is associated to the element:

$form->add(
    [
        'name'       => 'foo',
        'type'       => 'text',
        'options'    => [
            'label' => 'Foo',
        ],
    ]
);

And Bootstrap does the same:

<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">

<label>
    <input type="checkbox"> Check me out
</label>

http://getbootstrap.com/css/#forms


There is no reason to introduce these very special use case in a library, where a label is required without any relation to an element. If you have special cases, then create your own formRow view helper or use the formLabel helper directly.