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
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/
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)*
}
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.
The sidebar is not shown when you open the page. Instead, it appears with animation when you press the toggle button.
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.
Related
I am currently making a website with a fixed menu on top. When the page get's resized to the point where that menu don't fit, a new dropdown menu appear to take it's place. In order to open and close said dropdown menu you have to click a button with the following onclick JavaScript function:
function showMenu() {
var mb = document.getElementById("menu-bar");
if (mb.style.height != "505px") {
mb.style.height = "505px";
} else {
mb.style.height = "70px";
}
}
the issue I am having is when/if the user were to resize the page to the point where the button disapear while the dropdown menu is still open. My first thought was to change the menu-bar height using #media screen like this:
#media screen and (min-width: 1301px) {
#menu-bar {
height: 70px;
}
}
but due to the JavaScript already controlling the height of the menu-bar this doesn't work. Is there any other way I can achieve this?
I pulled a snippet of JS from a response to:
How can I make content appear beneath a fixed DIV element?
The JS works great but only when the page first loads, if the screen size changes for whatever reason, the rendered page is then in error until refreshed.
I currently have this:
$(document).ready(function() {
var contentPlacement = $('#topMenu').position().top + $('#topMenu').height();
$('body').css('margin-top',contentPlacement);
$('#navWindow, #searchWindow').css('margin-top',-contentPlacement);
});
Is there a way to have the outputted CSS dynamically change at the moment the screen size updates? This will also be helpful while developing the site.
This will be for displaying the content on my page underneath a fixed menu.
UPDATE
The sample of the site is located here: http://wp19.knowgreaterpartnership.com/
Additionally to the ready Callback function you can also use jquery.resize. You just have to execute the same code on the resize callback. Resize will be called every time the window size changes.
For the sake of less code redundancy I introduced a new method adjustContent:
$(document).ready(adjustContent);
$(window).resize(adjustContent);
function adjustContent() {
var contentPlacement = $('#topMenu').position().top + $('#topMenu').height();
$('body').css('margin-top',contentPlacement);
$('#navWindow, #searchWindow').css('margin-top',-contentPlacement);
}
I know you're asking about using jQuery to change CSS, but what you really should be doing is using Media Queries for your css so that it's declarative instead of script/event initiated.
Ex: (https://www.w3schools.com/Css/css3_mediaqueries_ex.asp )
/* Set the background color of body to tan */
body {
background-color: tan;
}
/* On screens that are 992px or less, set the background color to blue */
#media screen and (max-width: 992px) {
body {
background-color: blue;
}
}
/* On screens that are 600px or less, set the background color to olive */
#media screen and (max-width: 600px) {
body {
background-color: olive;
}
}
I've been fiddling around with my navigation menu and decided to add a feature when you scroll down past a certain point the NAV slides down into viewport so that the user doesn't have to scroll back up to the top of the page to navigate. This is something that's become quite popular lately.
So I fiddled around and this javascript did the trick (note that I am not fluent with jquery at all):
jQuery(document).ready(function($){
$(".menu_wrapper").before($(".menu_wrapper").clone().addClass("shrink"));
$(window).on("scroll", function () {
$("body").toggleClass("slidedown", ($(window).scrollTop() > 700));
});
});
Now I read that as ... duplicate or 'clone' (make another) .menu_wrapper element before the original + add the class .shrink to it ... AND only once we've scrolled past 700px, we'll see this duplicate NAV because of the class .slidedown
CSS:
.shrink { position:fixed; top:-400px; left:0; width:100%; border-top: 0px solid #35d3c3; z-index:99999}
.slidedown .shrink { top:0;}
Now this is working 100% and I'm stoked BUT (it's never smooth sailing is it!!!) now I've got a problem when I change my viewport to a screen width less than 767px - YES my website is responsive and this is where my NAV changes to the typical drop down (even without the javascript / effect above) by using css and javascript:
jQuery(document).ready(function($){
$('.menu_wrapper').prepend('<div id="menu-icon">Menu</div>');
$("#menu-icon").on("click", function(){
$("#menu").slideToggle();
$(this).toggleClass("active");
});
});
My problem is that there is now a duplicate dropdown prepended NAV (1 on top of the other), like so:
+ MENU
+ MENU
The one NAV works but the other doesn't ... anyway regardless, when my media query hits 'mobile status' (below 767px) and the NAV prepends to a dropdown, this is when I DON'T want the whole slide-down-effect-clone (first jquery posted above) thing anymore. I want that rule to almost not exist or not apply when I'm below 767px screen width. How can I do this?
I've tried one of the obvious like:
.shrink { display:none}
.slidedown .shrink { display:none}
which almost seems like I've hit the jackpot leaving me only 1 prepended menu:
+ MENU
but nothing happens when I click on it - it doesn't slidedown and show the menu list items.
but I'm thinking like adding a rule within for the javasacript:
jQuery(document).ready(function($){
$(".menu_wrapper").before($(".menu_wrapper").clone().addClass("shrink"));
$(window).on("scroll", function () {
$("body").toggleClass("slidedown", ($(window).scrollTop() > 700));
});
});
that when we get below a width of 767px, we ignore the clone() function / rule etc?
I've done some googling of removeclass etc but because I'm a bonehead at javascript, I'm probably doing it all wrong.
Any help I'd appreciate it?
Since you want to hide that menu based on certain viewport dimensions, why not use a media query?
#media all and (max-width: 766px){
.shrink{ display: none; }
}
or
.shrink{ display: none; }
#media all and (min-width: 767px){
.shrink{ display: block; }
}
(That might not be the best width values or CSS properties to use there, but that should get you started.)
Edit: If you wanted to do the entire thing in javascript, the matchMedia() API is there for you, too.
If the CSS media query approach that ajm posted does not work for you, you could try only executing your code if a media query is met. The code in handleMediaQuery() will only run if the width is above 767px;
//Media query listeners
var mql = window.matchMedia("(min-width: 767px)");
mql.addListener(handleMediaQuery);
handleMediaQuery(mql);
function handleMediaQuery(mql) {
if (mql.matches) {
// Do stuff here that you want done when the query matches
}
else {
// Do stuff here that you want done when the query does not match
}
}
See https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries for more info
Dear Stackoverflow community,
I'm very desperated about following setup:
- I have a Website with a Jquery onepagescroll design.
- If the width of the browsers window is below a certain point (769px) the onepagescroll disapears
- Instead a Gumby based design gets activated
But when happening so
... the third of the three sections overlays over the second one a
... after the first section is a gap
I researchead about four hours on this problem and couldn't solve it.
I hope you can help me.
Yours Sinceryl,
yooui
Code:
index.html (http://pastebin.com/6fMtkBbm)
jquery.onepage-scroll.js (http://pastebin.com/FnQWWe7J)
To fix the spacing and overlap, take a look at your CSS. The three "section" elements each have a height of 100%, you'll have to change that in your responsive styles.
So try adding something like this:
#media only screen and (max-width: 768px) {
.onepage-wrapper .section {
height: auto;
}
}
I'll try my best to set up my scenario so that you can understand my question.
My site is currently taking advantage of css media queries to span between screen resolutions. I have a main drilldown menu that can not be hidden on page load, otherwise the menu will not correctly calculate it's height, and will not display properly.
As a way to still be able to hide this menu when needed, I have found a workaround that hides the menu, yet still allows the menu to correctly calculate it's height on page load.
$(document).ready(function () {
$(".hide-menu").hide();
var $drillDown = $("#drilldown");
});
This is great for pages that do not require the main menu to be displayed initially on both mobile and desktop resolutions. However, for my product pages this solution will not work. I need the menu to hide on load for mobile resolutions, but also display on load for desktop resolutions. Can anyone think of a solution that will work? I'm stumped. Here is the HTML:
<div class="drill-down-wrapper hide-menu hide-on-load hide-pd-page">
<div id="drilldown-breadcrumbs" class="breadcrumbs skin-colorful"></div>
<div id="drilldown" class="skin-colorful">
<!-- #Include virtual="Menu.txt" -->
</div>
</div>
Use media queries to hide and show the menus based on screen resolutions.
Rather than jQuery, try using CSS to show/hide elements. You can use the display rule to do so. Just as an example:
.hide-menu-on-load {
display: none;
}
#media screen and (max-width: 680px) {
.hide-menu-on-load {
display: block;
}
}
Note: display: none removed the element from the flow of the page. visibility: hidden keeps the element's flow on the page, yet simply removes it from view