This is the fifth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

preface

Page layout is also a technique that is often used in actual development.

  • In the larger aspect, you can realize the layout of the whole page, such as the left navigation, header, footer…
  • In a small way, it can be content layout, such as articles.
  • When considering the layout, you need to take into account both the desktop browser and the mobile side, often referred to as responsive.

Implemented in React, it’s not that different from the classic implementation.

There are several ways to implement a layout:

  • Implementing CSS from zero is a must
  • With the CSS Grid system, you can use different screen sizes
  • Use component libraries, for exampleantd
    • Grid: 24 grid system
    • Layout: Overall layout at the page level

CSS implements the basic layout

Top, middle and bottom layout

.app-layout1 {
  width: 500px;
  height: 400px;
  position: relative;
  text-align: center;
}

.app-layout1 .header {
  line-height: 60px;
}
.app-layout1 .content {
  position: absolute;
  bottom: 60px;
  top: 60px;
  left: 0;
  right: 0;
}
.app-layout1 .footer {
  line-height: 60px;
  bottom: 0;
  left: 0;
  right: 0;
  position: absolute;
}
Copy the code

Sider + top, middle and bottom layout

Use left: 150px, leaving Sider in place

.app-layout2 {
  width: 500px;
  height: 400px;
  position: relative;
  text-align: center;
}
.app-layout2 .header {
  position: absolute;
  left: 150px;
  top: 0;
  right: 0;
}
.app-layout2 .content {
  position: absolute;
  bottom: 60px;
  top: 60px;
  left: 150px;
  right: 0;
}
.app-layout2 .footer {
  bottom: 0;
  left: 150px;
  right: 0;
  position: absolute;
}
.app-layout2 .sider {
  width: 150px;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
}
Copy the code

Advanced: The width of the sidebar can be dragged

Style layout

style.css

.layout {
  position: relative;
  width: 100%;
  height: 400px;
}
.sider {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  background-color: #ddd;
}
.header {
  background-color: #aaa;
  height: 60px;
}
Copy the code

index.js

Control the paddingLeft of the layout with the status siderWidth

import { useState } from 'react';
import './style.css';

export default function ResizeLayout() {
  const [siderWidth, setSiderWidth] = useState(150);
  const pxWidth = `${siderWidth}px`;

  return (
    <div className="layout" style={{ paddingLeft: pxWidth}} >
      <div className="sider" style={{ width: pxWidth}} >
        sider
      </div>
      <div className="header">header</div>
      <div className="content">content</div>
    </div>
  );
}
Copy the code

Drag and drop the logic

Visually, what we’re dragging is the right border of the sidebar Sider, but it’s not. We will place an “invisible” bar — sider- Resizer in the right border position:

.sider-resizer {
  position: absolute;
  width: 6px;
  top: 0;
  bottom: 0;
  cursor: col-resize;
}
Copy the code

When the mouse is on the sider- Resizer and onMouseDown is triggered, record the initial position of the mouse and mark the dragging status as true:

const handleMouseDown = (event) = > {
  setStartPageX(event.pageX);
  setDragging(true);
};
Copy the code

With the change of the dragging status, we will put a mask (resize-mask) on the page for the monitoring of subsequent events:

{
  dragging && (
    <div
      className="resize-mask"
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseUp}
    />
  );
}
Copy the code
.resize-mask {
  background: rgba(0.0.0.0);
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  cursor: col-resize;
}
Copy the code

OnMouseMove, update the siderWidth and startPageX in real time, and the drag-and-drop effect will be created.

Finally, at onMouseUp, the drag state ends.

const handleMouseMove = (event) = > {
  const currentSiderWidth = siderWidth + event.pageX - startPageX;
  setSiderWidth(currentSiderWidth);
  setStartPageX(event.pageX);
};
const handleMouseUp = () = > {
  setDragging(false);
};
Copy the code

LocalStorage Storage width

At the end of the drag, save the siderWidth to localStorage; When initializing siderWidth, check whether localStorage has a value.

const [siderWidth, setSiderWidth] = useState(
  localStorage.getItem('siderWidth') | |150,);const handleMouseUp = () = > {
  setDragging(false);
  localStorage.setItem('siderWidth', siderWidth);
};
Copy the code

The complete code

style.css

.layout {
  position: relative;
  width: 100%;
  height: 400px;
}
.sider {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  background-color: #ddd;
}
.header {
  background-color: #aaa;
  height: 60px;
}
.sider-resizer {
  position: absolute;
  width: 6px;
  top: 0;
  bottom: 0;
  cursor: col-resize;
}
.resize-mask {
  background: rgba(0.0.0.0);
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  cursor: col-resize;
}
Copy the code

index.js

import { useState } from 'react';
import './style.css';

export default function ResizeLayout() {
  const [siderWidth, setSiderWidth] = useState(
    localStorage.getItem('siderWidth') | |150,);const [dragging, setDragging] = useState(false);
  const [startPageX, setStartPageX] = useState(0);
  const pxWidth = `${siderWidth}px`;
  const handleMouseDown = (event) = > {
    setStartPageX(event.pageX);
    setDragging(true);
  };
  const handleMouseMove = (event) = > {
    const currentSiderWidth = siderWidth + event.pageX - startPageX;
    setSiderWidth(currentSiderWidth);
    setStartPageX(event.pageX);
  };
  const handleMouseUp = () = > {
    setDragging(false);
    localStorage.setItem('siderWidth', siderWidth);
  };
  return (
    <div className="layout" style={{ paddingLeft: pxWidth}} >
      <div className="sider" style={{ width: pxWidth}} >
        sider
      </div>
      <div className="header">header</div>
      <div className="content">content</div>
      <div
        className="sider-resizer"
        style={{ left: pxWidth }}
        onMouseDown={handleMouseDown}
      >
        {dragging && (
          <div
            className="resize-mask"
            onMouseMove={handleMouseMove}
            onMouseUp={handleMouseUp}
          />
        )}
      </div>
    </div>
  );
}
Copy the code