Mam stronę HTML zawierającą kilka przycisków radiowych i kilka powiązanych fieldset, każdy z własnym identyfikatorem. Chcę ukryć / wyświetlić div w zależności od konkretnego przycisku radiowego.

Załączone Fiddle wykonują swoje zadanie.

Oto kod HTML

<div id="FS1">External fieldset with radiobuttons

  <div class="row">
    <input checked="checked" id="R1" name="Group1" type="radio" value="1"/>
    <label for="R1">Element 1</label>
    <input id="R2" name="Group1" type="radio" value="2"/>
    <label for="R2">Element 2</label>
    <input id="R3" name="Group1" type="radio" value="3"/>
    <label for="R3">Element 3</label>
    <fieldset class="fs" id="FS1-1">
      <legend>Header element 1</legend>
      <div class="form-group">
        <input class="form-control" id="exampleInputText1" type="text"/>
        <label for="exampleInputText1">Input field in the first element</label></div>
    </fieldset>
    <fieldset class="fs" id="FS1-2">
      <legend>Header element 2</legend>
      <div class="form-group">
        <input class="form-control" id="exampleInputText2" type="text"/>
        <label for="exampleInputText2">This is the input field for the second</label>
      </div>
    </fieldset>
    <fieldset class="fs" id="FS1-3">
      <legend>Header element 3</legend>
      <div class="form-group">
        <input class="form-control" id="exampleInputText3" type="text"/>
        <label for="exampleInputText3">And this is the last input field</label>
      </div>
    </fieldset>
  </div>
</div>

I to jest CSS

#FS1 div input:not(:checked) ~ #FS1-1, #FS1-2, #FS1-3 { display: none; } /* to hide all the detail elements */
#FS1 div input[value="1"]:checked ~ #FS1-1 { display: block; } /* to show only the 1th elem */
#FS1 div input[value="2"]:checked ~ #FS1-2 { display: block; } /* to show only the 2nd */
#FS1 div input[value="3"]:checked ~ #FS1-3 { display: block; } /* to show only the 3rd */

Teraz, co chcę osiągnąć, to przenieść fieldset poza div, na końcu fragmentu, ale to zepsuje odniesienia css i fragment nie będzie już działać.

Poniżej znajduje się żądany fragment, który nie jest uruchomiony. Potrzebuję sugestii, jak przedefiniować CSS

<div id="FS1">External fieldset with radiobuttons

  <div class="row">
    <input checked="checked" id="R1" name="Group1" type="radio" value="1"/>
    <label for="R1">Element 1</label>
    <input id="R2" name="Group1" type="radio" value="2"/>
    <label for="R2">Element 2</label>
    <input id="R3" name="Group1" type="radio" value="3"/>
    <label for="R3">Element 3</label>
  </div>
  <fieldset class="fs" id="FS1-1">
    <legend>Header element 1</legend>
    <div class="form-group">
      <input class="form-control" id="exampleInputText1" type="text"/>
      <label for="exampleInputText1">Input field in the first element</label></div>
  </fieldset>
  <fieldset class="fs" id="FS1-2">
    <legend>Header element 2</legend>
    <div class="form-group">
      <input class="form-control" id="exampleInputText2" type="text"/>
      <label for="exampleInputText2">This is the input field for the second</label>
    </div>
  </fieldset>
  <fieldset class="fs" id="FS1-3">
    <legend>Header element 3</legend>
    <div class="form-group">
      <input class="form-control" id="exampleInputText3" type="text"/>
      <label for="exampleInputText3">And this is the last input field</label>
    </div>
  </fieldset>
</div>
0
Paolo Di Pietro 20 grudzień 2019, 00:36

1 odpowiedź

Więc to, o co prosisz, nie może zostać osiągnięte za pomocą zwykłego CSS, ale rozwiązanie można osiągnąć za pomocą Javascript.

Oto dlaczego nie jest to możliwe z twoją obecną strukturą HTML, ponieważ twoja aktualna struktura HTML wygląda tak:

enter image description here

Z odpowiednim (uproszczonym) kodem:

#FS1 div input:not(:checked) ~ #FS1-1, #FS1-2, #FS1-3 { display: none; } /* to hide all the detail elements */
#FS1 div input[value="1"]:checked ~ #FS1-1 { display: block; } /* to show only the 1th elem */
#FS1 div input[value="2"]:checked ~ #FS1-2 { display: block; } /* to show only the 2nd */
#FS1 div input[value="3"]:checked ~ #FS1-3 { display: block; } /* to show only the 3rd */
<div id="FS1">
  <div class="row">
    <input checked="checked" id="R1" name="Group1" type="radio" value="1"/>    
    <fieldset class="fs" id="FS1-1"></fieldset>
    <fieldset class="fs" id="FS1-2"></fieldset>
    <fieldset class="fs" id="FS1-3"></fieldset>
  </div>
</div>

Jako prosty przykład wyjaśnię dlaczego ta linia kodu działa:

#FS1 div input[value="1"]:checked ~ #FS1-1 { display: block; }
  1. Identyfikator dostępu FS1
  2. Uzyskuje dostęp do jednostki HTML div, która jest potomkiem FS1
  3. Uzyskuje dostęp do encji HTML input dla stanu :checked i wewnętrznego value="1"
  4. Dostęp do elementu sibling (~) o identyfikatorze FS1-1
  5. Ustawia właściwość display: block dla FS1-1

Kluczową rzeczą do zapamiętania jest to, że element sibling jest zaznaczony.

Z proponowanymi zestawami zmian w HTML (patrz poniżej), będziesz musiał uzyskać dostęp do elementu parent encji HTML input dla stanu :checked i wewnętrznego value="1", a następnie stamtąd uzyskaj dostęp do sibling, ponieważ FS1-1 nie znajduje się już w div class="row", a raczej poza nim.

Zgodnie z Wikipedią:

Niektóre zauważone ograniczenia obecnych możliwości CSS obejmują: Selektory nie mogą się wznieść. CSS obecnie nie oferuje możliwości wybrania rodzica lub przodka elementu, który spełnia określone kryteria.

Zostało to również poruszone tutaj: Czy istnieje selektor nadrzędny CSS?

Obecnie nie ma możliwości wybrania rodzica elementu w CSS. W międzyczasie będziesz musiał uciekać się do JavaScript, jeśli chcesz wybrać element nadrzędny.

Szczerze mówiąc, prawdopodobnie nie warto walczyć, jeśli to możliwe, zostaw fieldset wewnątrz div class="row".

Oto odpowiednie zasoby, jeśli chcesz przejść dalej i przekonwertować to na rozwiązanie Javascript:

0
EGC 20 grudzień 2019, 04:12
Dziękuję EGC za wyjaśnienie. Szukałem innego rozwiązania, używając odwołań bezwzględnych: chciałbym opisać regułę podobną do tej (wymyślono sintaks): #FS1-1 [#FS1 div input[value="1"]:checked] {display: block;}
 – 
Paolo Di Pietro
20 grudzień 2019, 11:52