1

I'm having a problem changing the status indicator of elements in an html form. Pseudo-code as below:

<div class="master">
    /*Section 1*/
    <div>
        <input type="checkbox" /> /*Display .content div*/
        <label> Label of this section <span class="done"></span></label>
        <div class="content">
            <p>Content that is initially hidden</p>
            <div class"check>
                <input type="checkbox" /> /*Change .done span*/
            </div>
        </div>
    </div>

    /*Section 2*/
    <div>
        /*As above, 30 different sections*/
    </div>
</div>

The .content div is initially hidden. When the user clicks the first checkbox, this .content div is shown.

I have been using the css snippet below to handle displaying the .content div (using general sibling selectors):

.content{ eg. opacity: 0;}
.master input:checked ~ .content{ eg. opacity: 1;}

This is working fine, however I haven't been able to figure out anything similar for the second checkbox to target the .done span.

The .done span within label is initially a red cross. When the user clicks the second checkbox I would like to be able to target this span so I can restyle it into a green tick.

As there are many sections I only want to target the particular .done span that the checkbox relates to.

Is this possible with the way I have my html set up?

If so, how would I go about implementing what I would like to do?

If not, what would your recommendations be?

Should I just use a bunch of unique id's for the spans instead of a class?

Thanks!

EDIT

I ended up using jQuery for this since the css was going to get so messy.

If anyone is curious, here is what ended up working:

$(".check").click(function(){
    //Basically just goes up the hierarchy to find the label then toggles the class as appropriate
    $(this).parent().parent().parent().children("label").children("span").toggleClass('done').toggleClass('notDone');
});
Ampersand
  • 426
  • 1
  • 6
  • 12
  • 1
    The `span` is above the second checkbox in the DOM and you ***cannot target it*** using CSS selectors. CSS selectors can only select elements that are children/descendant or siblings present below the reference element. – Harry Nov 18 '16 at 04:57
  • You need to change your HTML structure – Afsar Nov 18 '16 at 05:00
  • It sounds like you are looking for the [mythical parent selector](https://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector?rq=1). This would be trivial with jquery but much harder, or impossible, without some form of scripting. – Jon P Nov 18 '16 at 05:00
  • You are going to want to use JavaScript. – StackSlave Nov 18 '16 at 05:03

1 Answers1

1

If you're willing to change your html around, there is a html+css only solution without JavaScript.
You are right about needing a bunch of unique ids though.

.master .content {opacity: 0;}
.master input:checked ~ .content {opacity: 1;}
.flip {display: none}
.done::before {color: red; content: '\2613'}
.flip.done:checked + .done::before {color: green;content: '\2713'}

.master > div {border: 1px solid #7F7F7F;margin: .5em 0;padding: .5em}
.flip + label, .flip.done + span + p + div label {color: #00F}
.flip + label:hover, .flip.done + span + p + div label:hover {text-decoration: underline}
.flip:checked + label, .flip.done:checked + span + p + div label {color: #309;}
<div class="master">
  /*Section 1*/
  <div>
    <input type="checkbox" id="s1_show" class="flip">
    <label for="s1_show">Click to show/hide section below</label>
    <!-- Display .content div -->
    <div class="content">
      <input type="checkbox" class="flip done" id="s1_done"> <span class="done"></span>
      <p>Content that is initially hidden</p>
      <div class="check">
        <label for="s1_done">Click to flip "done"</label>
      </div>
    </div>
  </div>

  /*Section 2*/
  <div>
    /*As above, 30 different sections*/
  </div>
</div>
Mr Lister
  • 45,515
  • 15
  • 108
  • 150