Applying pseudo-class for a checkbox to a specific sibling

45 Views Asked by At

I am looking at realizing a CSS Native multilevel menu for a sidebar without using Javascript (or the setState in my current React implementation). I have done almost everything, but I am getting stuck with an additional feature, i.e. rotating the chevron 90 degrees when the checkbox is checked.

Each group opens to a level which can contain an additional level. I am trying to not use named groups/peers so that I can easily generate this from e.g. a JSON file.

I tried to change the peer position and using group without any luck. I could possibly refactor my code, to swap elements and achieve it, but that would probably not be the correct solution.

I have this code available. All works, but the chevron does not rotate.

<div class="container mx-auto flex h-screen">
  <div class="flex w-48 flex-col bg-slate-100">
    <div class="hover:bg-pink-300">Item 1</div>
    <div class="hover:bg-pink-300">Item 2</div>
    <div class="hover:bg-pink-300">Item 3</div>
    <label class="cursor-pointer">
      <input type="checkbox" class="peer hidden cursor-pointer select-none rounded-lg bg-slate-500 ease-in-out">
      <div class="flex items-center justify-between">
        <span>Group 1</span>
        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="h-4 w-4 peer-checked:rotate-90">
          <path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" /></svg
      ></div></input>

      <div class="relative hidden pl-4 peer-checked:block">
        <div class="hover:bg-pink-300">Item 1-1</div>
        <div class="hover:bg-pink-300">Item 1-2</div>
        <div class="hover:bg-pink-300">Item 1-3</div>
        <label class="peer cursor-pointer">
          <input type="checkbox" class="peer hidden cursor-pointer select-none rounded-lg bg-slate-500 ease-in-out" />
          <span class="flex items-center justify-between">
            <span>Group 2</span>
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="h-4 w-4">
              <path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" /></svg
          ></span>
          <div class="relative hidden pl-4 peer-checked:block">
            <div class="hover:bg-pink-300">Item 2-1</div>
            <div class="hover:bg-pink-300">Item 2-2</div>
            <div class="hover:bg-pink-300">Item 2-3</div>
          </div>
        </label>
      </div>
    </label>
  </div>
  <div class="flex flex-1 bg-lime-100"></div>
</div>
1

There are 1 best solutions below

0
Wongjn On

Peers of the <svg> would only be the <span> as peer- uses the sibling CSS combinator, +. To rotate the <svg> depending on the <input> you could consider using a group, with an arbitrary modifier,

<script src="https://cdn.tailwindcss.com/3.4.0"></script>

<div class="container mx-auto flex h-screen">
  <div class="flex w-48 flex-col bg-slate-100">
    <div class="hover:bg-pink-300">Item 1</div>
    <div class="hover:bg-pink-300">Item 2</div>
    <div class="hover:bg-pink-300">Item 3</div>
    <label class="cursor-pointer">
      <input type="checkbox" class="peer hidden cursor-pointer select-none rounded-lg bg-slate-500 ease-in-out">
      <div class="flex items-center justify-between group">
        <span>Group 1</span>
        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="h-4 w-4 group-[:checked+&]:rotate-90">
          <path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" /></svg
      ></div>

      <div class="relative hidden pl-4 peer-checked:block">
        <div class="hover:bg-pink-300">Item 1-1</div>
        <div class="hover:bg-pink-300">Item 1-2</div>
        <div class="hover:bg-pink-300">Item 1-3</div>
        <label class="peer cursor-pointer">
          <input type="checkbox" class="peer hidden cursor-pointer select-none rounded-lg bg-slate-500 ease-in-out" />
          <span class="flex items-center justify-between group">
            <span>Group 2</span>
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="h-4 w-4 group-[:checked+&]:rotate-90">
              <path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" /></svg
          ></span>
          <div class="relative hidden pl-4 peer-checked:block">
            <div class="hover:bg-pink-300">Item 2-1</div>
            <div class="hover:bg-pink-300">Item 2-2</div>
            <div class="hover:bg-pink-300">Item 2-3</div>
          </div>
        </label>
      </div>
    </label>
  </div>
  <div class="flex flex-1 bg-lime-100"></div>
</div>