-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider allowing the user to pass a string media query rather than just a max width value #35
Comments
Same here. It states it's a mobile first approach but uses max-width for breakpoint recognition. An option for min-width would be great. |
Yes, please add this. I just spent a while trying to figure out why things weren't working correctly. I was just trying to set the breakpoints to be the same as my tailwind configuration:
It took me longer than I would like to admit to realize that this library was using max width while tailwind and most other CSS frameworks use min width. It will be easier to take the configuration directly from tailwind and use it within vue if they are all min width. |
What I ended up doing is just using window.matchMedia and setting some state inside of Vuex (or just a Vue component instance when I’m not using vuex) for whatever breakpoints match the framework I’m using, or some other special cases. It’s not as nice as using this lib would be, but I don’t need the breakpoints too often in templates / js so it’ll do for now. |
I just adjusted the settings to be max-width but still correspond to the css min-width breakpoints
Not as convenient, but it seems to work fine, unless I'm missing something? |
I would really like to switch to vue-mq, but this specific issue is keeping me from doing so. As of now approach that I'm using is pretty similar to what @stephantabor has described. I created a store module and a mixin called media: media store
media mixin
that way I can get exactly the behavior I want. The only caveat to this solution is that I have to subscribe to
|
Yes, please! I use min-width media queries and this doesn't support that: I have the following breakpoints:
but there's no way to match those with vue-mq. |
@nathanchase can't you just adjust the |
@flyingL123 it can work for some simple cases, but the main reason that I made this issue was because using matchMedia and allowing any media queries has a few other advantages:
These are just some things i've personally done with my home rolled solution, i'm sure there are a bunch of others I haven't considered |
@flyingL123 No, because my design is built around the breakpoints being "larger than" a certain size, not "less than" a certain size. |
@nathanchase I think the person meant you could convert your min-width to max-width, e.g. @custom-media --larger-than-desktop-hd (min-width: 1200px);
@custom-media --full-size (min-width: 1440px); becomes ue.use(VueMq, {
// These are max-width settings
breakpoints: {
largerHd: 1339,
fullSize: Infinity,
}
}); conversion might be off, just an example But it's not perfect and annoying that you have to then mentally convert your css mq to the js one, being able to have the same exact media queries would be waaaaaay better |
That doesn't work because I need the change (show/hide of a component) to happen exactly at the minimum width, not at the last pixel before the next breakpoint. |
Decided to switch libraries to the much more full-featured https://github.com/reegodev/vue-screen instead. Cheers. |
@nathanchase good find, thanks! |
@nathanchase wow, that lib looks really awesome! Thanks for the link! |
Well, vue-screen also causes SSR/client hydration errors (Using Nuxt), so now I don't know what to do. Stuck trying to come up with an implementation that works, but nothing exists. |
@nathanchase I am still confused why you can't adjust your values so that mq will work. For example, my css breakpoints are:
Using that as an example, Then, for mq, they are defined like this:
Going through the same example, now these are max-width settings, which means mq treats |
Either way, I can't actually use them in a computed property the way I need to. I need to be able to do
Instead of something that figures out anything bigger than the named breakpoint. Not ideal. |
Not ideal sure but it’s a one time inconvenience to write a small object that includes a method to check those ugly conditionals for each breakpoint and return true or false. Then use it in whatever components need it. Either through the provide inject api or directly as a separate import. |
@nathanchase you will get hydration errors anyway, there's no cure from that since it's how Nuxt works, it's not related to one lib or another. The actual problem is that in SSR phase you don't have a window object thus no media queries so Nuxt will always render "mobile" version of your app first, but once client phase kicks in - the lib changes your DOM structure and you get a hydration error. The rules here are simple - try to use vue-screen in v-if as less as possible. The better way is to apply some specific class that will alter the look. I think it will also work good if you will provide the same structural element in v-else, you can just put a display:none on it with a class, but the goal here is to always try to keep identical DOM structure on all breakpoints. |
That's the problem though, is that I want to be able to lazy load Vue components as needed. There are components specific to a mobile view that don't need to be loaded for a desktop user, and vice-versa. Yes, I can (and have) been using CSS to show/hide content, but it still loads both sets of content and just hides some of it - wasting time downloading content that will likely not be shown UNLESS the user changes their viewport. In addition, I do need SSR to fetch and render out information for SEO purposes, and by default, Googlebot uses a mobile user agent as its primary crawler. This is problematic, as the content will not be the same (and shouldn't be) for mobile as it would be on desktop - so I do still need what amounts to two customized versions of the site depending on a "Smartphone" crawler or a "Desktop" crawler. My hope is that there's some way to be able to use It's a difficult problem to solve! |
@nathanchase I understand your pain but can't give you a straight solution to the problem. If you will find something that can mitigate this issue - let me know, please. I'm also curious about how can it be fixed in the right way :) |
@nathanchase @AndrewBogdanovTSS Hey guys, I think I've solved a problem with vue-mq and SSR. Think you might be interested. So I was searching for a solution, and as you found none. So I've spent the whole day on this and finally I've got a working solution (it seems so). My idea: we render component with ssr, but don't hydrate it on the client immediately. We check if the breakpoint on the client matches the defaultBreakpoint / breakpoint on a server (I use <template>
<div>
<LazyHydrate never :trigger-hydrate="doHydration" v-if="doHydration">
<slot></slot>
</LazyHydrate>
<NoSsr v-else>
<slot></slot>
</NoSsr>
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import LazyHydrate from 'vue-lazy-hydration';
import NoSsr from 'vue-no-ssr';
import { isServer } from '@vue-storefront/core/helpers';
import detectBreakpoint from 'theme/utils/detect-breakpoint';
@Component({
components: {
LazyHydrate,
NoSsr
}
})
export default class ResponsiveHydrate extends Vue {
public name: string = 'ResponsiveHydrate';
public doHydration: boolean = isServer;
mounted() {
this.doHydration = this.$mq === detectBreakpoint();
}
}
</script> Ps: Device detector would've been enough by itself for solving hydration issue (cause it's good at detecting mobile / tablet / desktop), but we can't 100% guarantee that the user of tablet will have the screen resolution we will set it to (768-1024 by default) or that the user on desktop won't use dev tools to make screen smaller. Thus this solution above. Let me know if this was any help to you! |
would solve issues like #18, #34
What i'm looking to do personally is just use min-width media queries so i can easily match them up with our predefined in our css
The text was updated successfully, but these errors were encountered: