I have a website in which I can render a simple Html page on a route localhost:3000/static
and a 3d scene on the normal route localhost:3000/
. What I'm attempting to perform is, the media query transforms, which will only be applied if the route is localhost:3000/static
, but not in the iframe. Because mobile the iframe (route: localhost:3000/
) shows as it is on mobile, but I want it to show if it was on a deskop, without applying @medias.
Here is the css and how the page is being rendered in iframe:
.htmlScreen iframe {
width: 1500px;
height: 700px;
border: none;
background: #000;
}
<Html
transform
prepend
wrapperClass="htmlScreen"
scale={0.35}
distanceFactor={1.17}
zIndexRange={[0, 0]}
>
<div
onClick={(e) => {
if (!isFocusOnHtml) e.preventDefault();
}}
onPointerEnter={(e) => {
if (isFocusOnHtml) setIsPointerOnHtml(true);
}}
onPointerLeave={() => {
if (isFocusOnHtml) setIsPointerOnHtml(false);
}}
>
<iframe
src="https://niltonsf.dev/static"
title="myStaticWebsite"
style={{ width: isMobile ? 1200 : 1500 }}
/>
</div>
</Html>
This is the @media:
@media screen and (max-width: 708px) {
#root {
background-color: red;
}
}
As you can see on my 3d view, the background is being appplied, because I'm seeing this on mobile, but I don't want the media to be applied on this route, for the iframe.
Well, I found a workaround on how to use media queries according to what you need or specific environments. This way I have made it, you can apply according to the size, environments, and any other variables you would like.
Basically what I am using is a hook from usehooks-ts
library:
import { useMediaQuery } from "usehooks-ts";
import { useState } from "react";
export default function Header() {
const mediumDevices = useMediaQuery("(max-width: 768px)");
const smallDevices = useMediaQuery("(max-width: 350px)");
With this, I can keep track of the media queries, and apply them as I want. "This looks the same as applying normal queries", yes it looks! Although you can add variables, for example, isMobile
or isSpecialUser
, etc, meaning, you can change the styling data according to the type of user, or mobile environment. In my case, I'm using styled-components
to apply styles, and receive variables.
This is a piece of my component and a example on how I'm using it:
xport default function Header() {
const [toggleMenu, setToggleMenu] = useState(false);
const mediumDevices = useMediaQuery("(max-width: 768px)");
const smallDevices = useMediaQuery("(max-width: 350px)");
return (
<HeaderCP mediumDevices={mediumDevices}>
<Nav>
<span className="nav_logo">Nilton A Schumacher F</span>
<NavMenu
smallDevices={smallDevices}
mediumDevices={mediumDevices}
toggleMenu={toggleMenu}
>
<Ul smallDevices={smallDevices} mediumDevices={mediumDevices}>
On my styles I'm applying them as the following:
import styled from "styled-components";
interface MediaQuery {
mediumDevices?: boolean;
smallDevices?: boolean;
toggleMenu?: boolean;
}
export const HeaderCP = styled.div<MediaQuery>`
${(props) => {
let finalStyles = ``;
finalStyles += `
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: var(--z-fixed);
background-color: var(--body-color);
`;
if (props.mediumDevices) {
finalStyles += `
top: initial;
bottom: 0;
`;
}
return finalStyles;
}}
`;
export const Nav = styled.nav.attrs({
className: "container",
})`
height: calc(var(--header-height) + 1.5rem);
display: flex;
justify-content: space-between;
align-items: center;
column-gap: 1rem;
`;
export const NavMenu = styled.div<MediaQuery>`
${(props) => {
let finalStyles = ``;
if (props.mediumDevices) {
finalStyles += `
position: fixed;
bottom: ${props.toggleMenu ? 0 : `-100%`};
left: 0;
right: 0;
width: 100vw - 50px;
background-color: var(--body-color);
padding: 2rem 1.5rem 4rem;
box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.15);
border-radius: 1.5rem 1.5rem 0 0;
transition: 0.3s;
`;
}
if (props.smallDevices) {
finalStyles += `
padding: 2rem 0.25rem 4rem;
`;
}
return finalStyles;
}}
`;
This is just an example, I could add something like isMobile
, isSamsung
, isApple
, etc. Meaning I can apply different styles to different devices.
EDIT: In my case, I'm using Three.js
, and rendering an iFrame with another route from my website. This solution was the one I was expecting. The iframe is not applying the mobile media queries on the main route (3d route) although If I go to the static website route, the media query is applied!