views:

224

answers:

3

What I have is a form with one fieldset containing several other fieldsets. For each fieldset, the user can check a box next to the legend and expand that fieldset (in theory, at least). I was thinking it would be cool to try using pure CSS for the effect, but I'm getting hung up on how to write the rule based on the two elements position to one another in the DOM. Here's the HTML:

 <fieldset id="areasofinterest">
     <legend>Areas of Interest Survey</legend>

 <p>Please Check The Areas Applicable to you and Answer the Coorepsonding Questions.</p>

<!--Area 1 Checkbox and Questions -->
<fieldset class="area">
 <legend>
  <input type="checkbox" value="area1" id="area1" />
  <label for="area1"> Area 1 :</label>
 </legend>
 <ul>
  <li>
   <label for="area1_q1">Q1</label>
   <input type="text" name="area1_q1" id="area1_q1" />
  </li>
  <li>
   <label for="area1_q2">Q2</label>
   <input type="text" name="area1_q2" id="area1_q2" />
  </li>
 </ul>
</fieldset>

<!--Area 2 Checkbox and Questions -->
<fieldset class="area">
 <legend>
  <input type="checkbox" value="area2" id="area2" />
  <label for="other"> Area 2 :</label>
 </legend>

 <ul>
  <li>
   <label for="area2_q1">Q1</label>
   <input type="text" name="area2_q1" id="area2_q1" />
  </li>
  <li>
   <label for="area2_q2">Q2</label>
   <input type="text" name="area2_q2" id="area2_q2" />
  </li>
 </ul>
</fieldset>

  </fieldset>

At first the idea seemed a bit hack-ish to me, but I ran it through the w3c validator, and yipiee it passed with inputs embedded within legends. So I'm sure I can get what I'm after using javascript/jquery, but I'd hate to at least have a proof of concept for doing it with CSS, even if older browsers may not support it.

I tried this rule:

.area ul {
    color: red;
 }

 .area input:checked + ul {
    color: blue;
 }

But with no luck. I confirmed with a much simpler test that both browsers I'm working with (Chrome, FF 3.5) can do input:checked + ul if it's simply an input followed by a ul. And it does toggle colors if I have both rules (in the simplified version).

But I'm not sure if there is a way to refer to the UL if the checked element is whithin the legend tag and thus not a direct sibling of the UL. Is there maybe a way to say "siblings of legends which contain inputs which are checked..."?

Thanks for the help.

+3  A: 

Nope.

"siblings of legends which contain inputs which are checked..."

Your problem is at the "contain" step. You can't move up the DOM like that. An element can't be selected in CSS based on children (or the children's contents or attributes).

You are also using a form element for visual interaction (and a legend), which is odd. I think you are better off with javascript. I can imagine other CSS-only solutions, but none that I would expect to be browser-compatible enough to trust with hiding and showing forms.

Eric Meyer
If I want to be really stubborn and keep the visual interaction within CSS as much as possible, I could simply have the class of the entire fieldset change to "visible" or "checked" (via js) and have the rules in place for the expanded fieldset to be visible to that class in CSS...
Anthony
I think what is really throwing people off about this idea is the check-able fieldsets. That's why the first thing I did was validate it. Imagine a medical form where you have to choose types of family history. Semantically, in my mind, the way to keep it simple and minimize overwhelming the user is to have a list of basic groups: "Cancer", "Mental Illness", "Heart Failure", and then if they choose one of those, ask for more details. So it's not just an interactive device, the main groups are actual choices to a larger question...
Anthony
Which raises sub-questions. So if I want my form to be as laid-out as possible (meaning checking a box doesn't suddenly change that choice in the DOM --turning it into a header, for instance) and also keeps the sub-questions actually as children of the major question (rather than tack on an extra fieldset floating next to the first question), then what makes sense to me is to have each choice expand out into a full fieldset, and the best role for the initiating choice--at that point-- is as the legend for that fieldset. Plus it LOOKS visually correct once it expands out. So says me, at least.
Anthony
I buy that. Interesting use case. And simply changing the class with js is exactly what I would recommend. Good luck!
Eric Meyer
A: 

My first thought, is that this won't work with CSS alone. I don't think you'll be able to do this without javascript. You can use the selectors in jQuery, for example and get the parent node through Javascript.

Also, I wondered if, after 'checking' a checkbox, a CSS pattern would match input[checked='checked'] ... like:

.area input + ul{ // not expanded }

.area input[checked='checked'] + ul{ // expanded }

It didn't work though so you'd need to use javascript just to implement the change in checked / unchecked. I'd uses something other than a checkbox as suggested previously too.

Lewis
The attribute `[checked="checked"]` doesn't work, but you can simply do `input:checked` which I didn't know until today, which is what spurred a lot of this on.
Anthony
didn't know that myself. That's interesting!
Lewis
A: 

The adjacent selector (+) obviously selects adjacent elements. You need a parent selector, which unfortunately doesn't exist (despite some proposals made to the w3c in the past).

Javascript (parentNode) is the only choice.

vise