13

I'm trying to make a form that has a list of default options, and which can also expand to show a couple of exta options. I do this with the following CSS code:

.myForm .moreOpts {display:none;}
.myForm #more:checked +*+ .moreOpts {display:block;}

with the following HTML:

<form action="#" class="myForm">
  <ul>
    <li>
      <input type="checkbox" id="pref-1" name="pref-1" value="1">
      <label for="pref-1">Foo</label>
    </li>
    <li>
      <input type="checkbox" id="pref-2" name="pref-2" value="2">
      <label for="pref-2">Bar</label>
    </li>
    <li>
      <input type="checkbox" id="more" name="more" value="true">
      <label for="more">More options</label>
      <ul class="moreOpts">
        <li>
          <input type="checkbox" id="pref-3" name="pref-3" value="3">
          <label for="pref-3">Baz</label>
        </li>
        <li>
          <input type="checkbox" id="pref-4" name="pref-4" value="3">
          <label for="pref-4">Qux</label>
        </li>
      </ul>
    </li>
  </ul>
</form>

Demo

This code works perfectly in every browser, except for Android Browser and Dolphin. I've found an article that recommends adding this "bugfix", but that only fixes my problem in Dolphin.

Is there any way to make this work for the default Android Browser too?

Community
  • 1
  • 1
Joeytje50
  • 18,636
  • 15
  • 63
  • 95
  • Really? That works in every browser? Even IE? I recommend using some king of JavaScript/jQuery script/plugin – Adrian Florescu Jan 25 '14 at 23:45
  • @AdrianFlorescu well not IE8 and lower, but that's expected. My problem is that Android Browser is supposed to support this, yet it doesn't work there. [this example](http://jsbin.com/ojOwUYA/1) works fine in Android Browser, so I don't see why the code in my question wouldn't. For IE8- I will just automatically show all of the options, as a fallback. – Joeytje50 Jan 25 '14 at 23:49
  • Android Gingerbread doesn't work. Good thing I have JellyBean. +1 – Nicholas Hazel Jan 26 '14 at 04:05
  • 5
    Try replacing '+*+' with '~' – Danield Jan 26 '14 at 08:09
  • Also, did you try other answers there like replacing `'+*+'` with `+*:nth-child(n)+'` – Danield Jan 26 '14 at 08:14
  • @Danield Nope, both of those didn't work either. I tried http://jsbin.com/oTEWAmeS/4/ and it still didn't toggle the other options. [Adding the bugfix to that](http://jsbin.com/oTEWAmeS/5/) doesn't solve it either. – Joeytje50 Jan 26 '14 at 12:11
  • Please include your demo code inline. If that demo link dies, your question becomes impossible to answer. – Charles Jan 26 '14 at 23:36
  • I tried the above and found that pseudo class checked itself is not working on my android browser 4.0.4. It is not the issue of sibling selectors, it is the :checked which doesnot work in android – sree Jan 28 '14 at 05:09
  • @sree According to [this](https://developer.mozilla.org/en-US/docs/Web/CSS/:checked#Browser_compatibility) table (click the Mobile tab), `:checked` is supposed to work in versions 2.1 and up. For me on version 4.2.3 simpler selectors such as [this demo](http://jsbin.com/ojOwUYA/1) work fine. So simpler selectors like that don't work for you? – Joeytje50 Jan 28 '14 at 07:44
  • I don't have the Android browser to test with (I've got KitKat on a Nexus 5 and Nexus 7), but this *feels* (from reading the question) similar to the problem I described here: http://stackoverflow.com/questions/17219286/why-does-the-general-sibling-combinator-allow-toggling-pseudo-elements-content (though I'm unsure if the answers will be of use to you). – David Thomas Jan 28 '14 at 07:57
  • @Joeytje50 selectors as ~ works. I tried with :first-child. that too works. :checked doesnot work – sree Jan 28 '14 at 09:15
  • ohh.. this is surprising. ~ works for me and :checked also works. Only this particular combination. And also font-style change does not work but margin works. Why is it like that – sree Jan 28 '14 at 10:02
  • @sree exactly. It looks like this is a webkit bug, going by david thomas' comment, but I still wouldn't know how to fix it. Weird stuff though. – Joeytje50 Jan 28 '14 at 10:36
  • I wouldn't say it's a webkit bug, I'd say it's a bug with how the Android Browser implements Webkit. It works fine everywhere else. – JacobTheDev Sep 30 '14 at 16:03
  • @Rev well Android browser ran the webkit version of chrome 12 at the time, (or something, I recall), which could just as well mean it's just an old webkit bug. – Joeytje50 Sep 30 '14 at 19:05

3 Answers3

6

You can achieve this with the help of the details element. Android supports it since version 4. However, you will have to deal with IE and Firefox, but fortunatly these browser support the CSS3 pseudo states, including :checked.

Two merge these two, just use the checkbox hack in browsers that don't support details. Here's the process explained in code: http://jsfiddle.net/hF6JP/1/

EDIT: this is the final solution, putting label inside the summary resolves the problem of having a forced checkbox to toggle the options: http://jsfiddle.net/mYdsT/

Gianluca Mancini
  • 1,302
  • 9
  • 10
  • Your second link doesn't seem to work on Android. The click event on the `label` doesn't seem to be inherited by the `summary`. I'll just implement browser-detection (since feature-detection doesn't work for this bug, since [the selector does seem to work when it's used on initial pagerender](http://jsbin.com/IvicihIM/1/). I'll then change the DOM for the default android browser and Dolphin (which both seem to use the same user agent string). I'll mark this as accepted if there's no better answers (which I don't really expect, but I do want to wait for it first). Thanks very much! – Joeytje50 Feb 01 '14 at 17:44
2

I wouldn't trust :checked for all browsers. I'd capture the click event of #more and just add a class to the parent. It's easy with jQuery. This option will work in Android and IE8.

$("#more").on("click", toggleCheckboxes);
var toggleCheckboxes = function(evt){
  var $this = $(this);
  $this.parents("li").toggleClass("show-more-options");
  evt.preventDefault()
}



.myForm .moreOpts {
  display:none;
}
.myForm .show-more-options .moreOpts {
  display:block;
}

:checked isn't supported in IE8, which is sadly still a big deal

https://developer.mozilla.org/en-US/docs/Web/CSS/:checked

Jason Lydon
  • 7,074
  • 1
  • 35
  • 43
1

http://quirksmode.org/css/selectors/mobile.html#t60

:checked apparently doesn't work in any version of Android. I'm not sure why so many webpages report that it should work (apparently from 2.1 up), but this is false.

The nice thing about QuirksMode is that every feature is actually tested in a real browser before they post it on the web.

JavaScript appears to be your best solution. I would even recommend javascript because if a user checks the "more" box, then selects some of the extra options, and then unchecks the "more" box... the extra selections will still be "checked" and will get submitted if a user hits a "submit" button. You will have to un-check those boxes every time the "more" box is un-checked. The only way to do this is with javascript.

UPDATE: QuirksMode has written a flawed test for the :checked selector:

:checked {
    display: inline-block;
    width: 3em;
}

You will notice that on Android the width never changes... but this is due to the fact that Android does not apply a width to checkboxes and radios (while desktop browsers do).

The following does work, even in my Android 2.3:

:checked {
    display: inline-block;
    margin: 3em;
}

So, as stated in other comments, the problem is with the combination of the checked selector and the adjacent sibling selector:

:checked + .test { /* does not work on android :( */ }
:checked ~ .test { /* does not work on android :( */ }
Ryan Wheale
  • 26,022
  • 8
  • 76
  • 96
  • Then quirksmode is partially wrong. I've tested `:checked` myself, and it works just fine when it's not being used in complicated situations like in this question. [This JSBin](http://jsbin.com/IZOZeDe/1/edit/) renders as [this](http://i.imgur.com/apPjCdr.png), and it will even [change dynamically](http://i.imgur.com/XeA57RQ.png), because this bin uses such simple selectors. [This JSBin](http://jsbin.com/IZOZeDe/2/edit/) however uses `:checked` together with `~`, so Android Browser [just doesn't handle it anymore](http://i.imgur.com/6OY6c3a.png). So, `:checked` does work, just not fully. – Joeytje50 Feb 04 '14 at 01:06
  • In reply to your later edit concerning the fact the checkboxes will still be checked when the user hides the "more options" box, that's **really** easy to check for on the server, by just putting it in an `if` block that checks if the form's `more` parameter is set to `"true"` (which is why that input also has a `name` and `value` set to it). That's not at all an issue. – Joeytje50 Feb 04 '14 at 01:08
  • Cool, I was just making you aware that hiding !== un-checking ;). And QuirksMode writes tests for each of the selectors, but their tests for this feature are flawed. I've updated my answer. – Ryan Wheale Feb 04 '14 at 01:22