0

I have a react sidebar with pure css for expand/collapse animations that I really like. Except for that by default, every time I open my page / jsfiddle in this case, the sidebar will always be closed by default.

https://jsfiddle.net/martinradio/x1dz80a6/2/

I've collected all the @media queries in my css file, and have changed it so when the window is big, the sidebar turns yellow. if the window becomes small, the sidebar gets colored red.

My sidebar expand/collapse logic is pure css, I want my sidebar to collapse if the window is too small (sidebar color = red), can I add a .sidebar value to collapse the sidebar?


/* ----------------------
@media queries
 ---------------------- */

/* if screen is big: show sidebar */
@media (min-width: 30em) {
  .sidebar {
    background:yellow;
    color:yellow;
  }
}

/* if screen is too small: hide sidebar */
@media (max-width: 31em) {
  .sidebar {
  background:red;
  color:red;
  }
  /* add something here to toggle sidebar as higgen */
}

is there a way, that by adding css, I can have my sidebar start expanded if the user is viewing the page on say a desktop monitor dimensions? But keep the sidebar hidden for smaller browser windows such as mobile

Joshua
  • 3,055
  • 3
  • 22
  • 37
Martin
  • 1,336
  • 4
  • 32
  • 69
  • You can certainly do this with Media queries. And with React, you can probably conditionally add a class to toggle the sidebar menu according to the user agent screen sizes – Joshua Jul 27 '22 at 01:11
  • Edited my question, I've been able to add these @media queries to change the sidebar color so i know its working. but I cant figure out what css logic to add such that the sidebar collapses – Martin Aug 02 '22 at 04:37
  • @Martin For a large screen, just hide the sidebar menu with `display: none` and while on a small screen, you do the opposite by hiding the navigation and show the sidebar menu instead – Joshua Aug 02 '22 at 06:17
  • @konekoya, you seem certain this can be done with pure CSS, please show us how. The solution needs to open/close the sidebar when changing the media query interval but still allow the sidebar to be opened/closed on both mobile and desktop. Basically, the behavior displayed in my answer. I'm quite certain this cannot be achieved without JavaScript. Please, prove me wrong. – tao Aug 08 '22 at 08:41
  • @Martin Your question is effectively unrelated to React, because you require a CSS only solution, and React in your code is just outputting static HTML. The fiddle works exactly the same [when you don't use React](https://jsfiddle.net/xd2nv043/1/). – inwerpsel Aug 08 '22 at 10:25
  • @inwer, the fact they use react to render the app is a good indication on their preference regarding framework. Considering what they ask for is only possible using JS, a React solution is likely to be more appropriate than an angular, svelte or solidjs one. Perhaps also preferable to a vanilla js solution, since implementing vanilla code into React is not always straight forward. IMHO, the tag is appropriate and relevant. – a.h.g. Aug 08 '22 at 17:30

3 Answers3

2

You want the :checked value of your input to determine the current expanded state of you sidebar.
At the same time, you want the size of the viewport to determine the same state.

This means you have to find a way to allow the size of the viewport to set the :checked value of the checkbox.

The bad news is you can't change or set the value of a checkbox using CSS alone.

The good news is it can be done using JavaScript. And you can link it to a media query.

Here's how to do it in React:

  // define media query:
  const mediaQuery = window.matchMedia("(min-width: 42rem)");

  // track query state (if it applies or not)
  const [query, setQuery] = React.useState(mediaQuery);

  // keep query state updated (+ cleanup)
  React.useEffect(() => {
    mediaQuery.addListener(setQuery);
    return () => mediaQuery.removeListener(setQuery);
  }, [mediaQuery]);

  // track sidebar expanded state
  const [expanded, setExpanded] = React.useState(query.matches);

  // update checkbox value when the query state changes
  React.useEffect(() => {
    setExpanded(query.matches);
  }, [query]);

  // everything else stays the same 
  // (except binding the expanded state to the checkbox)

See it working: https://jsfiddle.net/websiter/td9rgcpq/

tao
  • 82,996
  • 16
  • 114
  • 150
  • im trying to acomplish this with pure css if possible – Martin Aug 05 '22 at 20:48
  • 1
    @Martin. As I said, there's technically no way to change or set the value of a checkbox via CSS. And that's the gist of what you're asking. I'd wish you good luck if I knew there's a chance. But there are exactly zero chances of getting this behavior using CSS alone. – tao Aug 05 '22 at 21:04
  • I understand, thanks. i guess that is the limit for pure css – Martin Aug 08 '22 at 04:51
  • @Martin, there are multiple limits to CSS. CSS and JS don't compete with each other, they should work together. The goal is not to develop without one or the other. The goal is to develop beautiful, accessible, maintainable and scalable websites as quickly as possible. – tao Aug 08 '22 at 10:01
0

You can use CSS Media Queries to determine what action to do based on the screen size. Here, you would want to change the behavior of the sidebar based on the screen size.

@media (max-width: 600px) { 

*This is for phones, for example (you might need to find more accurate pixel counts)*

}

@media (min-width: 601px) { 

*This is for laptops, for example (you might need to find more accurate pixel counts)*

}
Pratyush
  • 108
  • 8
  • What would I add inside the brackets? Could I tell it to change a css attribute value for a class? Such as `@media (max-width: 600px) { .sidebar-visible: visibile:none }` not sure how to implement a media query in my react jsfiddle – Martin Aug 02 '22 at 03:44
  • Edited my question, I've been able to add these @media queries to change the sidebar color so i know its working. but I cant figure out what css logic to add such that the sidebar collapses – Martin Aug 02 '22 at 04:37
  • I believe you would simply change the width of the sidebar, unless I'm misunderstanding something. – Pratyush Aug 02 '22 at 13:54
0

When I worked on my answer, I realized that the requirements were not clear to me.

What do you want to have on a big screen? I can think of two different options.

  1. The sidebar is not shown when you open the page. Instead, it appears with animation when you press the toggle button.
  2. The sidebar is visible when you open the page and disappears when you press a toggle button. Should it appear with animation on page load?

And in both cases, you do not want the sidebar on the small screen.

I still do not understand the following requirement.

I can have my sidebar start expanded if the user is viewing the page on say a desktop monitor dimensions?

When a user opens the page on the big screen, what should it look like? What is the initial state of the sidebar on the big screen? Do you want the sidebar to open with animation on page load?

Anyway, please find my suggestion below.

Main idea

The sidebar becomes visible when they check the #sidebar-checkbox checkbox. I suggest limiting this behaviour to only large enough screens. In other words, we bind the checkbox state with the sidebar visibility only for big screens.

On small screens sidebar is always hidden because we place the rules under the media query for the big screens.

1. Initially hidden but appears when toggled

The code speaks for itself.


@media (min-width: 30em) {
  #sidebar-checkbox:checked + .sidebar {
    z-index: 10;
    visibility: visible;
  }

  #sidebar-checkbox:checked ~ .sidebar, #sidebar-checkbox:checked ~ .wrap, #sidebar-checkbox:checked ~ .sidebar-toggle {
  -webkit-transform: translateX(0rem);
      -ms-transform: translateX(0rem);
          transform: translateX(0rem);
  }

  #sidebar-checkbox:checked ~ .wrap {
  -webkit-transform: translateX(14rem);
      -ms-transform: translateX(14rem);
          transform: translateX(14rem);
  }
}

I think we also should show the label for the checkbox only on big screens. But I do not want to mess with your styles too much and try to make the minimal working change.

2. Initially shown on the big screen

We must replace the :checked selector with the :not(:checked) selector. In this case, the sidebar is visible by default on the big screen.

We can also show animation for the sidebar sliding from left to right on the page load. You might find some explanation in the answer to the question 'css3 transition animation on load?'.

Please check the updated JSFiddle with the suggestions for the second case.

Please let me know if I have got your requirements right.

Victor Smirnov
  • 3,450
  • 4
  • 30
  • 49