mirror of
https://github.com/phuoc-ng/csslayout.git
synced 2025-08-06 14:16:50 +02:00
@@ -3,6 +3,7 @@ import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import Home from './Home';
|
||||
import Centering from './layouts/Centering';
|
||||
import Sidebar from './layouts/Sidebar';
|
||||
import StickyFooter from './layouts/StickyFooter';
|
||||
import StickyHeader from './layouts/StickyHeader';
|
||||
|
||||
@@ -12,6 +13,7 @@ const App = () => {
|
||||
<Switch>
|
||||
<Route exact={true} path='/'><Home /></Route>
|
||||
<Route exact={true} path='/centering'><Centering /></Route>
|
||||
<Route exact={true} path='/sidebar'><Sidebar /></Route>
|
||||
<Route exact={true} path='/sticky-footer'><StickyFooter /></Route>
|
||||
<Route exact={true} path='/sticky-header'><StickyHeader /></Route>
|
||||
</Switch>
|
||||
|
@@ -3,14 +3,13 @@ import { Link } from 'react-router-dom';
|
||||
|
||||
import Layout from './Layout';
|
||||
|
||||
const DetailsLayout = ({ name, children }) => {
|
||||
const DetailsLayout = ({ children }) => {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="mw8 center">
|
||||
<div className="mv4">
|
||||
<Link to="/" className="link black pa1 ba b--black-60">CSS Layout</Link>
|
||||
</div>
|
||||
<h1 className="f1 tc">{name}</h1>
|
||||
<div className="mb5">
|
||||
{children}
|
||||
</div>
|
||||
|
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import CenterCover from './covers/CenterCover';
|
||||
import SidebarCover from './covers/SidebarCover';
|
||||
import StickyFooterCover from './covers/StickyFooterCover';
|
||||
import StickyHeaderCover from './covers/StickyHeaderCover';
|
||||
import Layout from './Layout';
|
||||
@@ -30,6 +31,12 @@ const Home = () => {
|
||||
<h2 className="f2 lh-copy">Layouts</h2>
|
||||
|
||||
<div className="flex flex-wrap">
|
||||
<div className="pa2 w-20">
|
||||
<Link to="/sidebar" className="link flex flex-column items-center justify-center bg-black-05 br2 ph3 pv4">
|
||||
<SidebarCover />
|
||||
<h4 className="f4 mv0 pt3">Sidebar</h4>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="pa2 w-20">
|
||||
<Link to="/sticky-footer" className="link flex flex-column items-center justify-center bg-black-05 br2 ph3 pv4">
|
||||
<StickyFooterCover />
|
||||
|
@@ -11,22 +11,20 @@ const Layout = ({ children }) => {
|
||||
{children}
|
||||
</div>
|
||||
<div className="w-100 bt b--black-30">
|
||||
<div className="mw8 center pv4 flex justify-between">
|
||||
<div className="mw8 center pv5 flex justify-between">
|
||||
<div>
|
||||
<div className="f4 fw6 mb2">Other cool things</div>
|
||||
<ul className="flex items-center list ma0 pa0 lh-copy fw5">
|
||||
<ul className="list ma0 pa0 lh-copy fw5">
|
||||
<li className="pr2">
|
||||
<a href="https://formvalidation.io" className="link" target="_blank" title="FormValidation ~ best validation library for JavaScript">
|
||||
FormValidation
|
||||
</a>
|
||||
</li>
|
||||
<li className="pr2">∙</li>
|
||||
<li className="pr2">
|
||||
<a className="link" href="https://blur.page" title="BlurPage ~ a browser extension to hide sensitive element on page" target="_blank">
|
||||
BlurPage
|
||||
</a>
|
||||
</li>
|
||||
<li className="pr2">∙</li>
|
||||
<li className="pr2">
|
||||
<a className="link" href="https://react-pdf-viewer.dev" title="React PDF Viewer ~ a PDF viewer made for React" target="_blank">
|
||||
React PDF Viewer
|
||||
|
25
client/covers/SidebarCover.jsx
Normal file
25
client/covers/SidebarCover.jsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
import Frame from '../placeholders/Frame';
|
||||
import Line from '../placeholders/Line';
|
||||
|
||||
const SidebarCover = () => {
|
||||
return (
|
||||
<Frame>
|
||||
<div className="h-100 flex">
|
||||
<div className="b--black-30 br flex flex-column justify-end pa1 w-30">
|
||||
<div className="mb1"><Line /></div>
|
||||
<div className="w-80"><Line /></div>
|
||||
</div>
|
||||
<div className="flex-grow-1 pa2 b--black-30 br bw2">
|
||||
<div className="mb2"><Line /></div>
|
||||
<div className="mb2"><Line /></div>
|
||||
<div className="mb2"><Line /></div>
|
||||
<div className="w-80"><Line /></div>
|
||||
</div>
|
||||
</div>
|
||||
</Frame>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidebarCover;
|
@@ -5,7 +5,7 @@ import Line from '../placeholders/Line';
|
||||
|
||||
const StickyFooterCover = () => {
|
||||
return (
|
||||
<Frame size="medium">
|
||||
<Frame>
|
||||
<div className="h-100 flex flex-column">
|
||||
<div className="flex-shrink-0 b--black-30 br bw2">
|
||||
<div className="w-100 flex items-center pa2">
|
||||
@@ -13,7 +13,7 @@ const StickyFooterCover = () => {
|
||||
<div className="w1 ml-auto"><Line /></div>
|
||||
<div className="w1 ml1"><Line /></div>
|
||||
</div>
|
||||
<Line size="medium" />
|
||||
<Line />
|
||||
</div>
|
||||
<div className="flex-grow-1 b--black-30 br bw2">
|
||||
<div className="pa2">
|
||||
@@ -23,7 +23,7 @@ const StickyFooterCover = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<Line size="medium" />
|
||||
<Line />
|
||||
<div className="w-100 flex items-center pa2">
|
||||
<div className="w1"><Line /></div>
|
||||
<div className="w1 ml1"><Line /></div>
|
||||
|
@@ -5,7 +5,7 @@ import Line from '../placeholders/Line';
|
||||
|
||||
const StickyHeaderCover = () => {
|
||||
return (
|
||||
<Frame size="medium">
|
||||
<Frame>
|
||||
<div className="h-100 flex flex-column">
|
||||
<div className="flex-shrink-0">
|
||||
<div className="w-100 flex items-center pa2">
|
||||
@@ -13,7 +13,7 @@ const StickyHeaderCover = () => {
|
||||
<div className="w1 ml-auto"><Line /></div>
|
||||
<div className="w1 ml1"><Line /></div>
|
||||
</div>
|
||||
<Line size="medium" />
|
||||
<Line />
|
||||
</div>
|
||||
<div className="flex-grow-1 b--black-30 br bw2">
|
||||
<div className="pa2">
|
||||
|
2
client/helpers/random.js
Normal file
2
client/helpers/random.js
Normal file
@@ -0,0 +1,2 @@
|
||||
const random = (min, max) => min + Math.round(Math.random() * (max - min));
|
||||
export default random;
|
2
client/helpers/randomFromArray.js
Normal file
2
client/helpers/randomFromArray.js
Normal file
@@ -0,0 +1,2 @@
|
||||
const randomFromArray = (array) => array[Math.floor(Math.random() * array.length)];
|
||||
export default randomFromArray;
|
6
client/helpers/shuffe.js
Normal file
6
client/helpers/shuffe.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const shuffe = (array) => {
|
||||
array.sort(() => Math.random() - 0.5);
|
||||
return array;
|
||||
};
|
||||
|
||||
export default shuffe;
|
@@ -2,6 +2,8 @@ import React from 'react';
|
||||
|
||||
import DetailsLayout from '../DetailsLayout';
|
||||
import BrowserFrame from '../placeholders/BrowserFrame';
|
||||
import Dot from '../placeholders/Dot';
|
||||
import Rectangle from '../placeholders/Rectangle';
|
||||
import SampleCode from '../SampleCode';
|
||||
import useDocumentTitle from '../useDocumentTitle';
|
||||
|
||||
@@ -9,11 +11,15 @@ const Centering = () => {
|
||||
useDocumentTitle('CSS Layout ∙ Centering');
|
||||
|
||||
return (
|
||||
<DetailsLayout name="Centering">
|
||||
<DetailsLayout>
|
||||
<h1 className="f1 tc">Centering</h1>
|
||||
<BrowserFrame
|
||||
content={
|
||||
<div className="h-100 flex flex-column items-center justify-center">
|
||||
<div className="f1 b">CENTER</div>
|
||||
<Dot size={64} />
|
||||
<div className="w-40 mt3"><Rectangle /></div>
|
||||
<div className="w-30 mt2"><Rectangle /></div>
|
||||
<div className="w-20 mt2"><Rectangle /></div>
|
||||
</div>
|
||||
}
|
||||
source={
|
||||
@@ -23,10 +29,9 @@ code={`
|
||||
<div style="
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
">
|
||||
CENTER
|
||||
...
|
||||
</div>
|
||||
`}
|
||||
/>
|
||||
|
58
client/layouts/Sidebar.jsx
Normal file
58
client/layouts/Sidebar.jsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
|
||||
import DetailsLayout from '../DetailsLayout';
|
||||
import BrowserFrame from '../placeholders/BrowserFrame';
|
||||
import Block from '../placeholders/Block';
|
||||
import SampleCode from '../SampleCode';
|
||||
import useDocumentTitle from '../useDocumentTitle';
|
||||
|
||||
const Sidebar = () => {
|
||||
useDocumentTitle('CSS Layout ∙ Sidebar');
|
||||
|
||||
return (
|
||||
<DetailsLayout>
|
||||
<h1 className="f1 tc">Sidebar</h1>
|
||||
<div className="lh-copy mb3">Try to scroll the main content!</div>
|
||||
<BrowserFrame
|
||||
content={
|
||||
<div className="h-100 flex">
|
||||
<div className="b--black-30 br flex flex-column justify-end pa3 w-30">
|
||||
<div className="mb3"><Block numberOfBlocks={5} /></div>
|
||||
<div className="w-80"><Block numberOfBlocks={4} /></div>
|
||||
</div>
|
||||
<div className="flex-grow-1 pa3 overflow-scroll">
|
||||
<div className="mb4"><Block numberOfBlocks={20} /></div>
|
||||
<div className="mb4"><Block numberOfBlocks={20} /></div>
|
||||
<div className="mb4"><Block numberOfBlocks={20} /></div>
|
||||
<div className="mb4"><Block numberOfBlocks={20} /></div>
|
||||
<div className="w-80"><Block numberOfBlocks={10} /></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
source={
|
||||
<SampleCode
|
||||
lang="html"
|
||||
code={`
|
||||
<div style="display: flex;">
|
||||
<!-- Sidebar -->
|
||||
<aside style="width: 30%;">
|
||||
...
|
||||
</aside>
|
||||
|
||||
<!-- Main -->
|
||||
<main style="
|
||||
flex-grow: 1;
|
||||
overflow: scroll;
|
||||
">
|
||||
...
|
||||
</main>
|
||||
</div>
|
||||
`}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</DetailsLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
@@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
|
||||
import DetailsLayout from '../DetailsLayout';
|
||||
import Block from '../placeholders/Block';
|
||||
import BrowserFrame from '../placeholders/BrowserFrame';
|
||||
import Rectangle from '../placeholders/Rectangle';
|
||||
import SampleCode from '../SampleCode';
|
||||
import useDocumentTitle from '../useDocumentTitle';
|
||||
|
||||
@@ -9,21 +11,22 @@ const StickyFooter = () => {
|
||||
useDocumentTitle('CSS Layout ∙ Sticky footer');
|
||||
|
||||
return (
|
||||
<DetailsLayout name="Sticky footer">
|
||||
<DetailsLayout>
|
||||
<h1 className="f1 tc">Sticky footer</h1>
|
||||
<div className="lh-copy mb3">
|
||||
The footer always sticks to the bottom if the main content is short.
|
||||
</div>
|
||||
<BrowserFrame
|
||||
content={
|
||||
<div className="h-100 flex flex-column ba b--black-30 bw1">
|
||||
<div className="flex-shrink-0 bb b--black-30 bw1 pa3">
|
||||
Header
|
||||
<div className="h-100 flex flex-column">
|
||||
<div className="flex-shrink-0 bb b--black-30 pa3">
|
||||
<div className="w-50"><Rectangle /></div>
|
||||
</div>
|
||||
<div className="flex-grow-1 pa3">
|
||||
Content
|
||||
<Block numberOfBlocks={20} />
|
||||
</div>
|
||||
<div className="flex-shrink-0 bt b--black-30 bw1 pa3">
|
||||
Footer
|
||||
<div className="flex-shrink-0 bt b--black-30 pa3">
|
||||
<div className="w-40"><Rectangle /></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
|
||||
import DetailsLayout from '../DetailsLayout';
|
||||
import Block from '../placeholders/Block';
|
||||
import BrowserFrame from '../placeholders/BrowserFrame';
|
||||
import Rectangle from '../placeholders/Rectangle';
|
||||
import SampleCode from '../SampleCode';
|
||||
import useDocumentTitle from '../useDocumentTitle';
|
||||
|
||||
@@ -9,18 +11,19 @@ const StickyHeader = () => {
|
||||
useDocumentTitle('CSS Layout ∙ Sticky header');
|
||||
|
||||
return (
|
||||
<DetailsLayout name="Sticky header">
|
||||
<DetailsLayout>
|
||||
<h1 className="f1 tc">Sticky header</h1>
|
||||
<div className="lh-copy mb3">Try to scroll the main content to see the header sticks to the top of page.</div>
|
||||
<BrowserFrame
|
||||
content={
|
||||
<div>
|
||||
<div className="top-0 bg-white bb b--black-30 bw1 pa3" style={{ position: 'sticky' }}>
|
||||
Header
|
||||
<div className="top-0 bg-white bb b--black-30 pa3" style={{ position: 'sticky' }}>
|
||||
<div className="w-50"><Rectangle /></div>
|
||||
</div>
|
||||
<div className="pa3">
|
||||
<div className="lh-copy mb3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nulla facilisi morbi tempus iaculis urna id volutpat lacus. Urna id volutpat lacus laoreet non curabitur gravida. Eu mi bibendum neque egestas congue quisque egestas. Turpis egestas pretium aenean pharetra magna ac placerat. Proin sagittis nisl rhoncus mattis rhoncus urna. Est velit egestas dui id. Auctor neque vitae tempus quam pellentesque. Convallis a cras semper auctor neque. Consequat nisl vel pretium lectus quam id leo. Netus et malesuada fames ac. Dictum at tempor commodo ullamcorper a. Tellus in metus vulputate eu scelerisque. Morbi tristique senectus et netus et. Suscipit tellus mauris a diam maecenas sed enim. Eu facilisis sed odio morbi. Fermentum iaculis eu non diam phasellus.</div>
|
||||
<div className="lh-copy mb3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nulla facilisi morbi tempus iaculis urna id volutpat lacus. Urna id volutpat lacus laoreet non curabitur gravida. Eu mi bibendum neque egestas congue quisque egestas. Turpis egestas pretium aenean pharetra magna ac placerat. Proin sagittis nisl rhoncus mattis rhoncus urna. Est velit egestas dui id. Auctor neque vitae tempus quam pellentesque. Convallis a cras semper auctor neque. Consequat nisl vel pretium lectus quam id leo. Netus et malesuada fames ac. Dictum at tempor commodo ullamcorper a. Tellus in metus vulputate eu scelerisque. Morbi tristique senectus et netus et. Suscipit tellus mauris a diam maecenas sed enim. Eu facilisis sed odio morbi. Fermentum iaculis eu non diam phasellus.</div>
|
||||
<div className="lh-copy mb3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nulla facilisi morbi tempus iaculis urna id volutpat lacus. Urna id volutpat lacus laoreet non curabitur gravida. Eu mi bibendum neque egestas congue quisque egestas. Turpis egestas pretium aenean pharetra magna ac placerat. Proin sagittis nisl rhoncus mattis rhoncus urna. Est velit egestas dui id. Auctor neque vitae tempus quam pellentesque. Convallis a cras semper auctor neque. Consequat nisl vel pretium lectus quam id leo. Netus et malesuada fames ac. Dictum at tempor commodo ullamcorper a. Tellus in metus vulputate eu scelerisque. Morbi tristique senectus et netus et. Suscipit tellus mauris a diam maecenas sed enim. Eu facilisis sed odio morbi. Fermentum iaculis eu non diam phasellus.</div>
|
||||
<div className="lh-copy">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nulla facilisi morbi tempus iaculis urna id volutpat lacus. Urna id volutpat lacus laoreet non curabitur gravida. Eu mi bibendum neque egestas congue quisque egestas. Turpis egestas pretium aenean pharetra magna ac placerat. Proin sagittis nisl rhoncus mattis rhoncus urna. Est velit egestas dui id. Auctor neque vitae tempus quam pellentesque. Convallis a cras semper auctor neque. Consequat nisl vel pretium lectus quam id leo. Netus et malesuada fames ac. Dictum at tempor commodo ullamcorper a. Tellus in metus vulputate eu scelerisque. Morbi tristique senectus et netus et. Suscipit tellus mauris a diam maecenas sed enim. Eu facilisis sed odio morbi. Fermentum iaculis eu non diam phasellus.</div>
|
||||
<div className="mb4"><Block numberOfBlocks={20} /></div>
|
||||
<div className="mb4"><Block numberOfBlocks={40} /></div>
|
||||
<div><Block numberOfBlocks={30} /></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
23
client/placeholders/Block.jsx
Normal file
23
client/placeholders/Block.jsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
import random from '../helpers/random';
|
||||
import Rectangle from './Rectangle';
|
||||
|
||||
const Block = ({ numberOfBlocks }) => {
|
||||
return (
|
||||
<div className="flex flex-wrap w-100">
|
||||
{
|
||||
Array(numberOfBlocks).fill(0).map((_, i) => {
|
||||
const s = random(1, 5);
|
||||
return (
|
||||
<div key={i} className={`mr2 mb2 w-${s * 10}`}>
|
||||
<Rectangle height={8} />
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Block;
|
@@ -6,7 +6,7 @@ const BrowserFrame = ({ content, source }) => {
|
||||
|
||||
return (
|
||||
<div className="br2 ba b--black-20">
|
||||
<div className="flex pa3 bb b--black-20 items-center bg-black-05">
|
||||
<div className="flex ph3 pv2 bb b--black-20 items-center bg-black-05">
|
||||
<div className="br-100 mr1 w1 h1 bg-red" />
|
||||
<div className="br-100 mr1 w1 h1 bg-gold" />
|
||||
<div className="br-100 mr1 w1 h1 bg-red" />
|
||||
|
@@ -1,8 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
const Dot = () => {
|
||||
const Dot = ({ size = 16 }) => {
|
||||
return (
|
||||
<div className="bg-black-30 br-pill w1 h1" />
|
||||
<div
|
||||
className="bg-black-30 br-pill"
|
||||
style={{
|
||||
height: `${size}px`,
|
||||
width: `${size}px`,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -1,13 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
const Frame = ({ children, size }) => {
|
||||
const bw = (size === 'medium' ? '2px' : '1px');
|
||||
|
||||
const Frame = ({ children }) => {
|
||||
return (
|
||||
<div
|
||||
className="ba b--black-30 br2"
|
||||
style={{
|
||||
borderWidth: bw,
|
||||
height: '100px',
|
||||
width: '100px',
|
||||
}}
|
||||
|
@@ -1,12 +1,10 @@
|
||||
import React from 'react';
|
||||
|
||||
const Line = ({ size }) => {
|
||||
const h = (size === 'medium' ? '2px' : '1px');
|
||||
|
||||
const Line = () => {
|
||||
return (
|
||||
<div
|
||||
className="w-100 bg-black-30"
|
||||
style={{ height: h }}
|
||||
style={{ height: '1px' }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
12
client/placeholders/Rectangle.jsx
Normal file
12
client/placeholders/Rectangle.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
const Rectangle = ({ height = 8 }) => {
|
||||
return (
|
||||
<div
|
||||
className="w-100 bg-black-30 br-pill"
|
||||
style={{ height: `${height}px` }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Rectangle;
|
Reference in New Issue
Block a user