Hi all XD
I have a bit of code from this css-tricks article:
https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
...which requires interaction with the DOM, like so:
// First we get the viewport height and we multiple it by 1% to get a value for a vh unit
let vh = window.innerHeight * 0.01;
// Then we set the value in the --vh custom property to the root of the document
document.documentElement.style.setProperty('--vh', `${vh}px`);
// We listen to the resize event
window.addEventListener('resize', () => {
// We execute the same script as before
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
});
...which then allows me to use the following css to override the egregious vh unit behavior of mobile safari, like so:
body {
height: calc(var(--vh, 1vh) * 100);
}
...and it works like a charm on a vanilla website, like so:
https://test-project-2f0b4.firebaseapp.com (view in mobile safari to see what I'm taking about XD )
Now I'm trying to figure out how to bring this technique to a Gatsby app, but I'm not sure where to even start, so any thoughts and/or suggestions would be most appreciated.
Thanks! XD
You should be able to place this inside gatsby-browser.js file (just dropping that in should be fine)
or if you want something closer to "home" you could change your layout.js to the following:
import React, { Component } from "react"
import PropTypes from "prop-types"
import Header from "./header"
import "../assets/layout.css"
class Layout extends Component {
constructor(props) {
super(props);
this.layoutRef = React.createRef();
}
componentDidMount() {
if (typeof window !== "undefined") {
window.addEventListener('resize',this.onResizeHandler)
}
}
componentWillUnmount() {
if (typeof window !== "undefined") {
window.removeEventListener('resize',this.onResizeHandler)
}
}
onResizeHandler=()=>{
let vh = window.innerHeight * 0.01;
console.log(vh);
this.layoutRef.current.style.setProperty('--vh', `${vh}px`);
}
render() {
const {children}= this.props
return (
<>
<Header siteTitle={"default site"} />
<div>
<main className="module" ref={this.layoutRef}>{children}</main>
<footer>
漏 {new Date().getFullYear()}, Built with
{` `}
<a href="https://www.gatsbyjs.org">Gatsby</a>
</footer>
</div>
</>
)
}
}
Layout.propTypes = {
children: PropTypes.node.isRequired,
}
export default Layout
or if you go with a functional approach:
import React, { useEffect ,useRef} from "react"
import PropTypes from "prop-types"
import Header from "./header"
import "../assets/layout.css"
const FunctionalLayout = ({ children }) => {
const myfuncLayoutRef=useRef(null)
const onResizeHandler = () => {
let vh = window.innerHeight * 0.01
myfuncLayoutRef.current.style.setProperty("--vh", `${vh}px`)
}
useEffect(() => {
if (typeof window !== "undefined") {
window.addEventListener("resize", onResizeHandler)
}
return () => {
if (typeof window !== "undefined") {
window.removeEventListener("resize", onResizeHandler)
}
}
}, [])
return (
<>
<Header siteTitle={"default site"} />
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `0px 1.0875rem 1.45rem`,
paddingTop: 0,
}}
>
<main className="module" ref={myfuncLayoutRef}>{children}</main>
<footer>
漏 {new Date().getFullYear()}, Built with
{` `}
<a href="https://www.gatsbyjs.org">Gatsby</a>
</footer>
</div>
</>
)
}
FunctionalLayout.propTypes = {
children: PropTypes.node.isRequired,
}
export default FunctionalLayout
This just of the top of my head should work. I haven't actually tested it.
wow, ok, awesome, thank you :-)
Looks like this is answered. Closing! Thank you all of you 馃帀