Creating an Isomorphic/Universal website with React — part 2
In the first part of this series of post we saw how I refactored the data flow in my website.
Now we are going to see how to create the design and I solved certain problems in the React-way.
Menu
I have to admit, in a website small like this one the menu is kinda useless, but at the same time it just adds a nice touch. (this gif has some glitches, sorry)
Of course the whole menu is a react component, that has the sitemap as prop.
pages/index.jsrender(){
return (
....
<Menu
sections={sitemap}
/>
...
}
To create this menu I used React Motion which allowed me to create the bouncing effect very easily.
Let’s jump to the code!
As you can see, this is very straightforward. I change the height of the menu based on the number of elements, and I use react motion to create the wobbly effect.
Sections
In this design, every section has the same height of the viewport. Of course this behavior is expected also when the user resizes the page.
To obtain this effect, height and width of the viewport are calculated inside the index.js page (/pages/index.js) and passed to all the sections.
As you can notice this behavior is partially disabled for mobile to avoid an unpleasant defect when the address bar appears or disappears.
Now that every section knows the viewport dimensions we can concentrate on styling.
Overriding styles in React
This design is pretty basic, we have one fixed column and a scrollable column. For me was very important to avoid messing up the scroll system overusing absolute positioning.
It’s very important to maintain good compatibility so that the browser knows the exact dimension of the webpage.
In order to switch from a fixed position to an absolute position (to make the sidebar disappear when the section is concluded), I had to override the default style of my component.
One nice approach I found here:
https://medium.com/@jviereck/modularise-css-the-react-way-1e817b317b04 This helped me a lot in achieving this effect without losing my mind.
First, I created a component that can handle the 2 columns (Section.jsx) then the component to handle every sidebar behavior.
var styles = _.cloneDeep(this.constructor.styles);
Allows me to clone the style and altering it without messing the original object.
let isCurrent =
this.props.elementBox
&& this.props.elementBox.top!==undefined
&& ( this.props.elementBox.top <=0
&& this.props.elementHeight+this.props.elementBox.top>=0
&& this.props.elementHeight != this.props.windowHeight
);
let isAtEnd = this.props.elementBox
&& this.props.elementBox.bottom<this.props.windowHeight;
Calculate if the section is still in the viewport and if the user can see the start of the other section.
Than is just matter of switching between absolute/fixed positioning. Of course if the element is at the end we will have to set also bottom:0px in order to make it work.
Browser Resizing
In order to have a responsive website I had to use stylesheets; you know, I think that React is amazing, but Stylesheets are just perfect to handle media queries. They are simply the right tools for the job.
In the next part we are going to see how to create a simple Navigation system with smooth scrolling, pushState and browser refresh support.