Hello my frontend developer friends, today i will be discussing an awesome thing with you guys which we could help you in writing less javascript code to create interactive elements.

  • I will be using tailwind css v4 for the styling
  • I'll be creating my code snippets on Scribbler.live first, which is a fantastic platform that allows you to run a JavaScript Notebook, Online Compiler, and Editor without the need for manual setup.
  • Additionally, I am including a link to code snippets that includes all of the code examples so you can open the snippet and run it yourself to see the results.
  • I will be using scrib.show from scribbler.live, it is equivalent to console.log

Lets dive in...
Table of contents

How to create interactive elements without JS?

We will be using few new css selectors which has good browser support now. Using these selectors in a creative way could help in creating many interactive elements like modal, dropdown, popup, sidebar nav, etc.

  • has() - it allow us to check the states of the child elements and do the styling to the parent or child itself
  • [&] - parent selector which allow us to select a element or state of element using class, ids, data attributes, etc and style itself or the child elements.
  • Syntax:
class="has-[h2]:bg-slate-900>
   note">


 class="[&_.warning]:bg-warning-600>
   warning">

Notification component

class="!p-1 rounded-xl bg-white flex justify-between items-center gap-x-5 has-checked:hidden mb-14">
       class="!text-slate-900">This notification is interactive and could be closed without Javascript
       for="close-btn" class="text-red-400 text-xl cursor-pointer">
        X
         id="close-btn" type="checkbox" class="appearance-none w-0 h-0 hidden" />
  • This is a simple logic, here we are checking on the parent element that if it has an input with checked state, then hide the entire element. Clicking the "X" will check the input and hide the element just like a notification element.

Dropdown component

class="!p-2 rounded-xl bg-white h-12 overflow-hidden has-checked:h-fit has-checked:overflow-visible w-fit mb-14">
     class="flex justify-between items-center gap-x-5">
       for="dropdown-btn" class="text-blue-400 text-xl cursor-pointer">
        Dropdown
         id="dropdown-btn" type="checkbox" class="appearance-none w-0 h-0 hidden" />
      
    
     class="mt-5 space-y-2">
      Content 1
      Content 2
      Content 3
      Content 4
      Content 5
  • In the dropdown component, we will have a initial height just to show the dropdown heading, when we check the input, it will increase the height of the parent element showing the dropdown content. On clicking it again will uncheck the input and hide the content.

Modal component

class="[&:has(.modal-btn:checked)_.modal-content]:!block [&:has(.modal-btn:checked)_.modal-backdrop]:!block ">
       class="flex justify-between items-center gap-x-5">
           for="modal-btn" class="text-blue-400 text-xl cursor-pointer">
             class="right-arrow">Open modal
             id="modal-btn" type="checkbox" class="appearance-none w-0 h-0 hidden modal-btn" />
          
      
       class="hidden fixed z-20 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 modal-content bg-white w-1/2 h-40 rounded-xl">
          class="absolute right-3 top-3 flex justify-between items-center gap-x-5">
           for="modal-btn" class="text-blue-400 text-xl cursor-pointer">
             class="text-red-500">X
             id="modal-btn" type="checkbox" class="appearance-none w-0 h-0 hidden" />
          
        
         class="p-3 space-y-3">
          Modal without javascript
          This modal is created with tailwind css has selector and no javascript is used for the interactivity
        
      
       class="hidden fixed z-10 inset-0 bg-slate-900/50 modal-backdrop">
  • This one is a bit tricky, here we are combining parent selector and has selector to check if the parent element has an input with class name "modal-btn" and if it is checked then show the content with class name "modal-content".
  • Inside the modal content, we have another input checkbox with same class name, clicking it will uncheck the input and close the modal.
  • We also has a backdrop element covering the entire screen when the modal is visible, it is also shown using the same way as modal.
  • Breakdown of the classname: [&:has(.modal-btn:checked)_.modal-content]
    • [&:has(.modal-btn:checked)] - this part is used to check whether the element has input with class name modal-btn with a checked state
    • _.modal-content - Here underscore ( _ ) checks the element at nested level, it is checking for the modal-content classname using ".modal-content" dot notation.

Sidebar navigation component

class="fixed top-5 left-0">
       class="flex gap-x-5 transition-all duration-200 ease-in -translate-x-24 has-checked:translate-x-4 w-fit has-checked:[&_.left-arrow]:block has-checked:[&_.right-arrow]:hidden">
         class="mt-5 space-y-2 bg-slate-100 p-3 rounded-xl">
           class="space-y-5 max-h-60 overflow-auto">
            Content 1
            Content 2
            Content 3
            Content 4
            Content 5
            Content 6
            Content 7
          
        
         class="absolute -right-10 flex justify-between items-center gap-x-5">
           for="sidebar-btn" class="text-blue-400 text-xl cursor-pointer">
             class="right-arrow text-xl">→
             class="left-arrow text-xl hidden">←
             id="sidebar-btn" type="checkbox" class="appearance-none w-0 h-0 hidden" />
  • This one is also a simple one, here we are setting the translate x property with negative value to move it outside the screen on the left side. When we click the right arrow icon, it will check the input and add the positive translate x value to make it visible on the screen.
  • has-checked:[&_.left-arrow]:block has-checked:[&_.right-arrow]:hidden - These classes just hide and show the left/right arrows based on the sidebar visibility.

Check out all the examples on scribbler.live and run it yourself to see the output from each of the examples above

🎯 Conclusion

Handling interactivity without javascript is kind of difficult task and we should be using javascript in case of complex elements having multiple operations doing with interactivity. We could use no-js approach for simpler elements like dropdown and notification elements.

That's it for this post, Let me know if i could do any improvements in this article. Also, do check Scribbler.live website.

You can contact me on -

Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

You can help me with some donation at the link below Thank you👇👇
https://www.buymeacoffee.com/waaduheck

Also check these posts as well