I want to accomplish something like this with a fixed footer.
--------------------------------
| HEADER |
--------------------------------
| | |
| | |
| SIDE | CONTENT |
| BAR | |
| | |
--------------------------------
| FOOTER |
--------------------------------
I'm using Ant Design layout and I added a position fixed to the footer but I'm getting a weird bug when the sidebar groups are expanded that block some of the sidebar links.
Here is an example:
https://codepen.io/HugoLiconV/pen/jONBLJQ?editors=0010
EDIT:
The main problem is that if I expand the sidebar group that says "expand me" because there is a lot of links, the footer will hide some of the links. This happens especially a 1366 x 768 resolution
Here is a codepen link https://codepen.io/sniperdumbooo/pen/pozeZJb?editors=0010 for how you wanted to achieve with a fixed footer and centered content and sidebar big fixed
The changes made are removed display: 'flex' from footer and added textAlign: 'center' to the header part and added textAlign: 'justify' to the center body as:
<Header style={{ background: '#DDD', padding: 0, textAlign: 'center' }} >Header</Header>
<Footer style={{
borderTop: '1px solid #e8e8e8',
position: 'fixed',
left: 0,
bottom: 0,
width: '100%',
backgroundColor: 'white',
textAlign: 'center'}} >
textAlign: 'justify' ### to the div inside the <Content />
And the blocked sidebar links when expanded is due to the position: 'fixed' in the
<Layout style={{
overflow: 'auto',
minHeight: '100vw', ## make it minHeight: '100vw'
width: '100%',
left: 0 ### Removed the position: 'fixed'
}}>
Also remove style="padding: 24px" from div in html id="container"
<div id="container"></div>
will give you what you want to achieve with the bug fixed as in this link of codepen : Desired solution
You can add margin bottom same as footer height in px , please add below css and check,
.ant-layout-sider-children {
height: 100%;
margin-top: -0.1px;
padding-top: 0.1px;
margin-bottom: 95px;
}
hi i red all answers and i think there is an easier way for only using antd instead of using extra css
just use this kind of affix around your footer :
<Affix offsetBottom={0}>
and the document if you need :
https://ant.design/components/affix/
Unfortunately this can not (easily) be solved with CSS, and your best bet is to simply move the footer out one level, to the bottom of the parent <Layout>:
<Layout> <!-- Core layout -->
<Layout> <!-- Layout with Header and Content -->
</Layout>
<Footer style={{
borderTop: '1px solid #e8e8e8',
position: 'fixed',
left: 0,
bottom: 0,
width: '100%',
backgroundColor: 'white',
textAlign: 'center',
display: 'flex',}}
>
Ant Design ©2018 Created by Ant UED
</Footer>
</Layout>
This can be seen here.
Here, i have made a little change in your footer css and it looks fine.
<Footer style={{
borderTop: '1px solid #e8e8e8',
position: 'fixed',
left: 0,
bottom: 0,
width: '100%',
backgroundColor: 'white',
textAlign: 'center',}}
>
Hope this helps !
I had figured out a hack solution
import React, { FC, useEffect, useMemo } from 'react';
import { Table } from 'antd';
import { useMeasure } from 'react-use';
...
export const App: FC = () => {
const dataSource = ...
const columns = ...
...
/** Render */
const [ref, { height }] = useMeasure<HTMLDivElement>();
const tableTitleRef = useRef<Element>();
const tableHeaderRef = useRef<Element>();
const tableBodyRef = useRef<Element>();
const tableFooterRef = useRef<Element>();
const refs = (e: HTMLDivElement) => {
ref(e);
// 攔截 ref 呼叫,找到 title, header, body, footer element
tableTitleRef.current = e?.getElementsByClassName('ant-table-title')?.[0];
tableHeaderRef.current = e?.getElementsByClassName('ant-table-header')?.[0];
tableBodyRef.current = e?.getElementsByClassName('ant-table-body')?.[0];
tableFooterRef.current = e?.getElementsByClassName('ant-table-footer')?.[0];
};
/** 38、48 分別是沒有換行時的基本高度,當作 element 找不到時的 fallback default 值 */
const scroll = useMemo(() => {
return {
x: 1200,
y:
height -
(tableTitleRef.current?.clientHeight || 38) -
(tableHeaderRef.current?.clientHeight || 38) -
(tableFooterRef.current?.clientHeight || 48)
}
}, [height]);
useEffect(() => {
if (scroll) {
// 直接指定高度
if (tableBodyRef.current) tableBodyRef.current.style = `overflow: auto scroll; height: ${scroll.y}px;`;
}
}, [height, scroll]);
return (
<div ref={refs} style={{ height: '100%' }}>
<Table
scroll={scroll}
sticky={true}
columns={columns}
dataSource={dataSource}
pagination={false}
showHeader={true}
...
title={() => (
<TaskTableTitle
...
/>
)}
footer={() => (
<TaskTableFooter
...
/>
)}
/>
</div>
);
}
Related
I am trying to display a small card basically over the google maps component that this https://www.npmjs.com/package/#react-google-maps/api package provides. I set the zIndex to 2 but the <div> still shows below this map component.
The card element is not supposed to respond to any click it's just displayed on first load with the Map component
return (
<div>
<GoogleMap
mapContainerStyle={mapContainerStyle}
zoom={8}
center={center}
></GoogleMap>
<Tracking style={{zIndex: 2}}/>
</div>
);
Tracking is the div that contains information.
Map container style is:
const mapContainerStyle = {
width: "100vw",
height: "100vh",
};
Actually, there are a lot of ways to do it.
Briefly:
You have to add position: 'relative' to the parent component.
You have to add position: 'absolute' and zIndex: 0 to the child component that you want to display as the background.
You have to add position: 'absolute' and zIndex: 1 (or more) to the child component that you want to display as the foreground.
If you use inline styling, you could do this:
Adding top: some_number, left: some_number, right: some_number, or bottom: some_number is optional (depends on what position you want)
Here is the working code sandbox https://codesandbox.io/s/compassionate-rhodes-qbm43
App.js
import "./styles.css";
import Map from "./Map.js";
import Tracking from "./Tracking";
export default function App() {
return (
<div
style={{
position: "absolute",
zIndex: 0,
width: "100%", // or you can use width: '100vw'
height: "100%" // or you can use height: '100vh'
}}
>
<Map />
<div
style={{
zIndex: 1,
position: "absolute",
top: 10,
left: 10,
backgroundColor: "white", // you can use any color value
width: "10%", // or you can use width: any_number
height: "90%" // or you can use height: any_number
}}
>
<Tracking />
</div>
</div>
);
}
Map.js
import React from "react";
import {
GoogleMap,
useLoadScript,
Marker,
InfoWindow
} from "#react-google-maps/api";
import Tracking from "./Tracking";
const libraries = ["places"];
const mapContainerStyle = {
position: "relative",
width: "100%",
height: "100%"
};
const center = {
lat: -33.86882,
lng: 151.20929
};
function Map() {
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY,
libraries
});
if (loadError) return "Error loading maps";
if (!isLoaded) return "Loading Maps";
return (
<div
style={{
position: "absolute",
zIndex: 0,
width: "100%", // or you can use width: '100vw'
height: "100%" // or you can use height: '100vh'
}}
>
<GoogleMap
mapContainerStyle={mapContainerStyle}
zoom={8}
center={center}
></GoogleMap>
</div>
);
}
export default Map;
Tracking.js
import React from "react";
const Tracking = () => {
return (
<div>
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
</div>
);
};
export default Tracking;
in this data table i decalre rows and colums only as simple variables so i cant give them style with 'style={{textAlign: center}}' and i tried adding css file but it didnt work on either tr or th when using this material ui table so im not so sure how to do it... this is my code
import * as React from 'react';
import { DataGrid } from '#material-ui/data-grid';
export default function DataTable({data, someColumns}) {
const columns = someColumns
const rows = data;
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid rows={rows} columns={columns} pageSize={5} checkboxSelection />
</div>
);
}
by default the data in columns is aligned left and not center how can i change it?
EDIT: i've managed to fix it with this css. thanks to fahad
.MuiDataGrid-colCellTitle {
display: block;
text-align:center;
width: 100%;
}
.MuiDataGrid-cell {
display: block;
position: relative;
text-align: center;
}
which will center both rows and columns.
For anyone else who comes across this, check out the implementation of ColDef here.
The way to do this 'correctly' would be like this:
const [columns, setColumns] = useState([
{
field: 'status',
width: 130,
// these properties can only be 'left' | 'center' | 'right'
// note that these only set text-align property.
headerName: 'Status',
headerAlign: 'center',
align: 'center',
renderCell: (params) => {
return (
<Chip label={params.value} />
)
}
},
]);
If you're rendering anything other than text (like in the example above) it won't center your content. The cells are display: flex and align-items: center but to center horizontally you need to add a justify-content for centered cells:
.MuiDataGrid-cellCenter {
justify-content: center;
}
You can do the same for MuiDataGrid-cellLeft or MuiDataGrid-cellRight if needed.
This worked for me.
In your style.css you can target th and tr by
this property .MuiDataGrid-colCellTitle. So to align it in center use this
Style.css
.MuiDataGrid-colCellTitle {
display: block;
text-align:center;
width: 100%;
}
After importing things
import { DataGrid } from '#material-ui/data-grid';
Declare your rows and columns data inside the function.
export default function DataGridDemo() {
const columns = [
Data in columns
];
const rows = [
Data in rows
];
//Apply your styles
return (
<div
style={{
height: 400,
width: "100%",
backgroundColor: "red",
textAlign: "center"
}}
>
<DataGrid rows={rows} columns={columns} pageSize={5} checkboxSelection />
</div>
);
}
Code Sandbox link : https://codesandbox.io/s/thirsty-leaf-izuhd?file=/src/App.js
I need some help merging an animation and a transition that occur at different times using react-spring.
When the component is mounted using useSpring I make the component appear, but I would like it so that when the button child is removed the container transitions smoothly upwards. Theres more details in the example.
https://codesandbox.io/s/naughty-dawn-r0e5x
PLEASE HELP :)
I created a solution. There is a new Spring animation mainly for the button, but we can use part of it for the original div. In this case the maxHeight property. So this way you can combine the animations.
import ReactDOM from "react-dom";
import React, { useState } from "react";
import { useSpring, animated } from "react-spring";
function WelcomeMessage() {
const [isStarted, setIsStarted] = useState(false);
const animation1 = useSpring({
right: "1%",
opacity: 1,
from: { right: "-20%", opacity: 0 },
delay: 300
});
const animation2 = useSpring({
opacity: isStarted ? 0 : 1,
maxHeight: isStarted ? 150 : 250,
transform: `translateY(${isStarted ? "-50px" : "0px"})`
});
return (
<animated.div
style={{
backgroundColor: "pink",
position: "fixed",
top: "2%",
right: "1%",
cursor: "default",
borderRadius: 5,
width: "90%",
maxWidth: 400,
...animation1,
maxHeight: animation2.maxHeight
}}
>
<div style={{ padding: "15px 25px" }}>
<span>
This is a toaster notification component. When you click the following
button it should disappear and the pink container's bottom section
should transition upwards when it decreases in height.
</span>
<br />
<br />
{
<animated.button
style={{ width: "100%", fontSize: 48, ...animation2 }}
onClick={() => {
setIsStarted(true);
}}
>
Get Started
</animated.button>
}
</div>
</animated.div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<WelcomeMessage />, rootElement);
Here is the example: https://codesandbox.io/s/green-star-nzfj8
Is this answer your question?
Using React & Material UI I'm trying to layout 3 divs within a <Card> <CardHeader/> such that it has a left, center and right alignment respectively as shown below.
The change is trivial, I need to remove the padding and change to display: inherit but it seems this <div> exists between the exposed style & titleStyle for <CardHeader> and <CardHeader title={someElement}/>
The hierarchy looks like:
...<div><div.myCardHeader><div><span><myTitleElement>...
Being so new to React and styles, I'm unsure how to get to it.
Some representative code follows.
Thanks for help.
// #flow
import React, { Component } from 'react';
import Paper from 'material-ui/Paper';
import { Card, CardActions, CardHeader, CardMedia, CardTitle, CardText } from 'material-ui/Card';
const style = {
paper: {
height: 250,
width: 200,
margin: 20,
},
card: {
header: {
container: {
display: 'flex', /* establish flex container */
justifyContent: 'space-between',
backgroundColor: 'lightblue'
},
padding: 1,
height: 26
}
}
};
const POCardTitle = () => (
<div className="myContainer" style={style.card.header.container}>
<div style={{ width: 25, height: 26, border: '2px dashed red' }}> - </div>
<div style={{ width: 25, height: 26, border: '2px dashed blue' }}> - </div>
<div style={{ width: 25, height: 26, border: '2px dashed green' }}> - </div>
</div>
);
export default class POCard extends Component {
render() {
return (
<div>
<Paper style={style.paper} zDepth={2} >
<Card >
<CardHeader className="myCardHeader"
style={style.card.header}
titleStyle={{ paddingRight: 0, display: 'inline' }}
title={<POCardTitle />}
/>
</Card>
</Paper>
</div>
);
}
}
I managed to get there courtesy of https://www.styled-components.com
and the following:
const StyledHeader = styled(CardHeader) `
padding: 0px !important;
height: 26px !important;
> div {
display: inherit !important;
padding-right: 0px !important;
}
`;
I could find no other way to get to the "first div" after the component through regular CSS...
I've made a sticky footer higher-level component that wraps other components inside itself:
Footer.js
//this is a higher-order component that wraps other components placing them in footer
var style = {
backgroundColor: "#F8F8F8",
borderTop: "1px solid #E7E7E7",
textAlign: "center",
padding: "20px",
position: "fixed",
left: "0",
bottom: "0",
height: "60px",
width: "100%",
};
const Footer = React.createClass({
render: function() {
return (
<div style={style}>
{this.props.children}
</div>
);
}
});
export default Footer;
Usage:
<Footer><Button>test</Button></Footer>
But it is hiding the contents of the page:
This looks like a common problem, so I searched a bit and found this issue, where is FlexBox is recommended for the sticky footer. But at this demo the footer is at the very bottom of the page, while I need the footer to be always displayed on the page and the content being scrolled inside the above area (like in SO chat). In addition to that, there is an advice to change all the other components with custom stylesheet rules. Is it possible to achieve what I need using styling only the footer component so the code will remain modular?
Here's an idea (sandbox example link).
Include a phantom div in your footer component that represents the footer's position that other dom elements will respect (i.e. affecting page flow by not being position: 'fixed';).
var style = {
backgroundColor: "#F8F8F8",
borderTop: "1px solid #E7E7E7",
textAlign: "center",
padding: "20px",
position: "fixed",
left: "0",
bottom: "0",
height: "60px",
width: "100%",
}
var phantom = {
display: 'block',
padding: '20px',
height: '60px',
width: '100%',
}
function Footer({ children }) {
return (
<div>
<div style={phantom} />
<div style={style}>
{ children }
</div>
</div>
)
}
export default Footer
Much easier idea (following the trend), i imported both bootstrap and reactstrap, used the bootstrap fixed bottom class and workaround with that like this.
class AppFooter extends Component{
render() {
return(
<div className="fixed-bottom">
<Navbar color="dark" dark>
<Container>
<NavbarBrand>Footer</NavbarBrand>
</Container>
</Navbar>
</div>
)
}
There is a much simpler way. I am creating a portfolio site with React, and some of my pages are not very long, so in some devices, like kindle fire hd for example, the footer would not stick to the bottom. And of course to set this up in the traditional fashion with would not work, because the would be wrapped in there. And we don't want that. So this is what I did:
In App.js:
import React, { Component } from 'react';
import {Header} from './components/Header';
import {Main} from './components/Main';
import {Footer} from './components/Footer';
class App extends Component {
render() {
return (
<div className="App Site">
<div className="Site-content">
<div className="App-header">
<Header />
</div>
<div className="main">
<Main />
</div>
</div>
<Footer />
</div>
);
}
}
export default App;
And then in _sticky-footer.css (I use POSTCSS):
:root {
--space: 1.5em 0;
--space: 2em 0;
}
.Site {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.Site-content {
flex: 1 0 auto;
padding: var(--space) var(--space) 0;
width: 100%;
}
.Site-content:after {
content: '\00a0';
display: block;
margin-top: var(--space);
height: 0;
visibility: hidden;
}
The original solution for this was created by Philip Walton: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/
You can fix this by adding margin-bottom: 60px; to the body of your website. With the 60px being the height of your footer.
.footer{
width: 100%;
position: fixed;
bottom: 0;
}
This should do the trick! Cheers! (:
.App will be the main component you load to your Root.
Assume that the footer is the last child of .App in the document flow
.App {
height: 100vh;
display: flex;
flex-direction: column;
}
footer {
margin-top: auto;
}
I found that if you wrap your 'footer' component in a standard html
<footer>
tag, it pretty much sorts out all of the positioning for you
I wanted to share this solution that worked. I cribbed this from https://react.semantic-ui.com/modules/sticky. Scroll to the bottom of this page and inspect the text 'This is the bottom' to see where I stole it. Its a site built on react so it should work for your situation.
Here it is:
{
padding-top: 50vh;
}
Conceptually, this solution is creating negative space like jacoballenwood's phantom div to push the footer down to the bottom and stick it there. Just add it to your css style class for the footer and adjust the value to taste.
Very late answer, but someone can find this useful. You can, instead of phantom style, set Toolbar. I have build some standard layout for the components, where {children} is component from the parent component - App.js. This is example:
import React from "react";
import { Route } from "react-router-dom";
import { makeStyles } from "#material-ui/core/styles";
import AppBar from "#material-ui/core/AppBar";
import CssBaseline from "#material-ui/core/CssBaseline";
import Toolbar from "#material-ui/core/Toolbar";
import Header from "../components/header";
import Footer from "../components/footer";
import SideBar from "../components/sidebar";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
},
content: {
flexGrow: 5,
padding: theme.spacing(3),
},
}));
const StandardLayout = ({ children }) => {
const classes = useStyles();
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Route path="/" component={Header} />
</AppBar>
<SideBar />
<main className={classes.content}>
<Toolbar />
<br />
{children}
<Toolbar/>
</main>
<AppBar className={classes.appBar}>
<Route path="/" component={Footer} />
</AppBar>
</div>
);
};
export default StandardLayout;
Its rule for me
<footer style={{position:"fixed",bottom:"0"}}>
Try this html code:
/public/index.html
<html lang="en" class="h-100">
<body class="h-100">
<div id="root" class="d-flex flex-column h-100"></div>
...
/src/App.js
<main role='main' className='flex-shrink-0'>
You can follow this template:
react-bootstrap-sticky-footer/public/index.html
react-bootstrap-sticky-footer/src/App.js