Flexbox make each element fill screen width - css

I have multiple AgGrid tables that should be displayed side-by-side, but each table should take up the width of the entire screen.
I accomplished this by setting width of the parent element to ${tables.length}00%, but is there a more elegant/pure .css way to accomplish this?
Codesandbox link: https://codesandbox.io/s/multi-grid-width-8jqurj
const App = () => {
const rowData = [
{ make: "Toyota", model: "Celica", price: 35000 },
{ make: "Ford", model: "Mondeo", price: 32000 },
{ make: "Porsche", model: "Boxter", price: 72000 }
];
const tables = [rowData, rowData];
return (
<div
className="ag-theme-alpine"
style={{
display: "flex",
width: `${tables.length}00%`
}}
>
{tables.map((data) => (
<div style={{ width: "100%", height: 400 }}>
<AgGridReact rowData={data}>
<AgGridColumn field="make" />
<AgGridColumn field="model" />
<AgGridColumn field="price" />
</AgGridReact>
</div>
))}
</div>
);
};

Updated Answer:
I've updated my snippet as follows
Add width "max-content" to the parent and width: 100vw to each child element
<div
className="ag-theme-alpine"
style={{
display: "flex",
width: "max-content"
}}
>
{tables.map((data) => (
<div style={{ width: "100vw", height: 400 }}>
<AgGridReact rowData={data}>
<AgGridColumn field="make" />
<AgGridColumn field="model" />
<AgGridColumn field="price" />
</AgGridReact>
</div>
))}
</div>
Updated Snippet: ttps://codesandbox.io/s/multi-grid-width-forked-rx7chu
ORIGINAL ANSWER: I tried you snippet with:
width: `${tables.length}00vw`
I made this change to ensure that I covered all the viewport/window width instead of 100% of the parent container
Heres a fork of your snippet https://codesandbox.io/s/multi-grid-width-forked-rx7chu

Related

Proper height of a child area of the draggable allotment pane

I have made a draggable split panel by https://github.com/johnwalley/allotment.
There is a main area (in yellow) and a console area; the console area has a title line (in blue) and the content area (in green). The splitting line between the main area (in yellow) and the title line (in blue) is draggable. The content area (in green) should be scrollable.
At the moment, I set height: "70%" for the content area. If I set height: "100%" (relative to its parent which is the second Allotment.Pane), it would exceed the screen.
However, I would like to set properly the height of the content area such that the content area always covers the rest of the page. In other words, the height of the content area will be the height of the viewport - the height of the main area (which is changeable) - the height of the console title line (which does not change).
Does anyone know how to amend the code to achieve that?
https://codesandbox.io/s/reset-forked-jb86xu?file=/src/App.js
import React from "react";
import { Allotment } from "allotment";
import "allotment/dist/style.css";
import styles from "./App.module.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
toExpand: true
};
this.myRef = React.createRef();
}
handleChange = (sizes) => {
if (sizes.length > 1) {
if (sizes[1] < 31) {
this.setState({ toExpand: true });
} else {
this.setState({ toExpand: false });
}
}
};
render() {
return (
<div>
<div className={styles.container}>
<Allotment vertical onChange={this.handleChange} ref={this.myRef}>
<Allotment.Pane>
<div style={{ backgroundColor: "yellow", height: "100%" }}>
Main Area
</div>
</Allotment.Pane>
<Allotment.Pane preferredSize="0%">
<div
onClick={() => {
if (this.state.toExpand) {
this.myRef.current.resize([50, 50]);
} else {
this.myRef.current.resize([10000, 0]);
}
}}
style={{ backgroundColor: "blue" }}
>
Console Title
{this.state.toExpand ? "ArrowUp" : "ArrowDown"}
</div>
<div
style={{
backgroundColor: "green",
height: "70%",
overflow: "scroll"
}}
>
Content1
<br />
Content2
<br />
Content3
<br />
Content4
<br />
Content5
<br />
</div>
</Allotment.Pane>
</Allotment>
</div>
</div>
);
}
}
Not sure if I fully understand the preferred result, but perhaps consider to wrap the 2 area boxes in the second panel in one flex container with height: 100%. This way, the green "content" area could be styled to take the remaining space with flex-grow instead of percentage.
Forked demo with modifications: codesandbox (it seems that the forked demo need to run in a new tab to avoid showing a page scrollbar).
<div className={styles.container}>
<Allotment vertical onChange={this.handleChange} ref={this.myRef}>
<Allotment.Pane>
<div style={{ backgroundColor: "yellow", height: "100%" }}>Main Area</div>
</Allotment.Pane>
<Allotment.Pane preferredSize="0%">
<section
style={{
height: "100%",
display: "flex",
flexDirection: "column",
}}
>
<div
onClick={() => {
if (this.state.toExpand) {
this.myRef.current.resize([50, 50]);
} else {
this.myRef.current.resize([10000, 0]);
}
}}
style={{ backgroundColor: "blue" }}
>
Console Title
{this.state.toExpand ? "ArrowUp" : "ArrowDown"}
</div>
<div
style={{
backgroundColor: "green",
flexGrow: "1",
overflow: "auto",
}}
>
Content1
<br />
Content2
<br />
Content3
<br />
Content4
<br />
Content5
<br />
</div>
</section>
</Allotment.Pane>
</Allotment>
</div>

Layout looks correct on my phone (Android) but not friend's (iPhone)

I finished the layout of the website I'm working on, and like how it looks...
But...when my friend opens it on her iPhone, it looks like this.
I can't figure out what's causing this. If I use Chrome Developer Tools and set it to a responsive mobile format, or iPhone X, it resizes properly. Can anyone help me figure out what I'm doing wrong here?
I also had a third person look at it who told me the video isn't playing. So I'm pretty lost, not sure what I'm doing wrong since I can't reproduce the issue myself.
Here is the link if anyone wants to check.
And this is the code for the header.
import React, { useState } from "react"
import styled from "styled-components"
import { Link } from "gatsby"
import logo_image from "../../static/logo_white_trans.png"
import title_image from "../../static/title.png"
const MenuIcon = //Removed
const MenuLinks = //Removed
const Header = () => {
const [nav, showNav] = useState(false)
return (
<div id='header' style={{ height: '100%', backgroundColor: 'black', display: 'grid', gridTemplateColumns: '20% 60% 20%' }}>
<div id='logo' style={{ width: '100%' }} >
<img alt='logo' src={logo_image} style={{ maxHeight: '15vh', maxWidth: '100%', width: 'auto !important' }} />
</div>
<div id='title' style={{ position: 'relative', margin: 'auto', textAlign: 'center' }}>
<img alt='title' src={title_image} style={{ maxHeight: '15vh', maxWidth: '100%', width: 'auto !important' }} />
</div>
<div id='menu' style={{ width: '100%' }}>
<MenuIcon nav={nav} onClick={() => showNav(!nav)}>
<div />
<div />
<div />
</MenuIcon>
<MenuLinks nav={nav}>
<ul>
//Removed
</ul>
</MenuLinks>
</div>
</div >
)
}
export default Header
And here is the index code.
import React, { useState } from "react"
import Header from "./header"
import Footer from "./footer"
import "./style.css"
import VideoFile from "../../resources/vide_file.mp4"
const Index = () => {
const [nav, showNav] = useState(false)
return (
<div style={{ display: "flex", flexDirection: "column" }}>
<Header style={{ alignItems: "flex-start" }}>
</Header >
<video loop autoPlay muted style={{ preload: 'auto', height: "75vh", objectFit: "cover", display: "block", margin: "0 auto", alignItems: "stretch" }}>
<source src={VideoFile} type="video/mp4" />
</video>
<Footer style={{ alignItems: "flex-end" }}>
</Footer>
</div>
)
}
export default Index
A slight tweak to the margin property on your div id='title' element fixes the issue:
margin: '0 auto'
Remember that margin: 'auto' centers elements horizontally and vertically. I believe what's happening is Chromium is properly centering the element within the direct parent container, in this case:
<div id="header" style="height:100%;background-color:black;display:grid;grid-template-columns:20% 60% 20%"></div>
Safari instead is going a level up and centering the element on the grandparent, which is the full viewport height:
<div style="display:flex;flex-direction:column"></div>
Specifying a '0' margin above and below the element forces Safari to move the logo back to the top of the parent element.

Display navbar ontop of react-window

I'm trying to display a navbar on top of react window list. I'm using react-window and react-virtualized-auto-sizer. The problem is that when I add the navbar outside the AutoSizer it creates another scroll bar. sandbox. How could I position the navbar ontop of the list without another scroll bar being created?
Code:
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);
const Homepage = () => (<>
<div style={{ width: "100%", height: "100vh", overFlow: "hidden"}}>
<Navbar /> // this causes a second scroll bar
<AutoSizer>
{({ width, height }) => (
<>
<List
height={height}
itemCount={1000}
itemSize={35}
width={width}
>
{Row}
</List>
</>
)}
</AutoSizer>
</div>
</>
);
Change your dom architecture so your header is outside the AutoSizer
For example:
const App = () => (
<div style={{ width: "100%", height: "100vh" }}>
<div style={{ height: "10vh", backgroundColor: "lightgrey" }}>
header here
</div>
<div style={{ height: "80vh" }}>
<AutoSizer>
{({ width, height }) => (
<>
<List height={height} itemCount={1000} itemSize={35} width={width}>
{Tester}
</List>
</>
)}
</AutoSizer>
</div>
<div style={{ height: "10vh", backgroundColor: "lightgrey" }}>
footer here
</div>
</div>
);
Demo
In you style.css file you could add
body {
overflow: hidden;
}
it s not the most elegant solution but I guess it works.

How to adjust modal height with inline CSS in React

Currently, the modal is too small to contain all email inputs when adding multiple users, overflowing the modal. Tried to apply CSS's height 100% property with no success. Here's some of the code:
const divEmail = {
content: {
position: "relative",
display: "block",
margin: "0 50px 0 30px",
background: "transparent"}
};
class PageAssistantSplitCourrielsCollaborateurs extends Component {
render() {
ayantDroits.push(
<div style={{ height: "100%" }}>
<div key={`champ--courriel__${elem}`}>
<Label style={divEmail} htmlFor={`champ--courriel__${elem}`}>
{_aD.name}
</Label>
<Translation>
{t => (
<Input
style={divEmail}
name={`champ--courriel__${elem}`}
id={_aD.rightHolderId}
defaultValue={_aD.email}
placeholder={t("flot.split.inscription.exemple")}
required={this.state.requis}
autoFocus={this.state.autoFocus}
type="email"
onChange={this.onChange}
/>
)}
</Translation>
</div>
</div>
);
});
return (
<div style={{ height: "100%" }}>
<Translation>
{t => (
<div>
{ayantDroits}
</div>
)}
</Translation>
</div>
);
}
}

How to align the two buttons to the center of a div of 'position:absolute' using flexbox? [duplicate]

This question already has answers here:
How can I vertically center a div element for all browsers using CSS?
(48 answers)
Flexbox: center horizontally and vertically
(14 answers)
How to center a "position: absolute" element
(31 answers)
How can I horizontally center an element?
(133 answers)
How can I center an absolutely positioned element in a div?
(37 answers)
Closed 4 years ago.
This is the outcome of my code so far:
What I actually want to achieve is to move the two button to the center horizontally. But at the moment they are aligned to the left.
This is the result I want to achieve:
I have tried alignItems but it has no effect. I don't want to use any margin because the container size may vary.
Here is my code:
const H = "540px";
const W = "720px";
const ContentView = ({ width, height }) => (
<div style={{ width, height, border: "1 solid red" }}>Hello! Alt View!</div>
);
const ControlView = ({ width, height, onReveal, onCopy }) => {
const container = {
width,
height,
position: "relative"
};
const controlsContainer = {
width,
height,
position: "absolute",
left: 0,
top: 0,
border: "5px solid green",
display: "flex"
};
return (
<div style={container}>
<img style={{ width, height }} src="https://i.imgur.com/MQcuk3n.jpg" />
<div style={controlsContainer}>
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
}}
>
<div>
<button
style={{
width: "400px",
height: "60px",
minWidth: "200px",
display: "block"
}}
onClick={onReveal}
>
Reveal
</button>
</div>
<div>
<button
style={{ width: "400px", height: "60px", minWidth: "200px" }}
onClick={onCopy}
>
Copy Meta
</button>
</div>
</div>
</div>
</div>
);
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = { playing: false };
}
_onReveal() {
this.setState({ playing: true });
}
_onCopy() {
window.alert("Meta data copied");
}
renderAltView() {
return <AltView />;
}
render() {
const { width, height } = this.props;
if (!this.state.playing) {
return (
<div>
<h2>Controls</h2>
<ControlView
width={width}
height={height}
onReveal={() => this._onReveal()}
onCopy={() => this._onCopy()}
/>
</div>
);
}
return (
<div>
<ContentView />
</div>
);
}
}
ReactDOM.render(<App width={W} height={H} />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Unfortunately I cannot get it to work in SO code snippet. A working version is here at codepen https://codepen.io/kongakong/pen/EpRKPx
What flex directive I can use to position the buttons as I want?
You also need to center all the child elements in the parent div. So in your case you need to set the flexbox properties to the controlsContainer.
const controlsContainer = {
width,
height,
position: 'absolute',
left: 0,
top: 0,
border: '5px solid green',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center'
};
Working example:
const H="540px";
const W="720px";
const ContentView = ({width, height}) => (
<div style={{width, height, border: '1 solid red'}}>Hello! Alt View!</div>
)
const ControlView = ({width, height, onReveal, onCopy}) => {
const container = {
width,
height,
position: 'relative',
};
const controlsContainer = {
width,
height,
position: 'absolute',
left: 0,
top: 0,
border: '5px solid green',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center'
};
return (
<div style={container} >
<img style={{width, height}} src="https://i.imgur.com/MQcuk3n.jpg" ></img>
<div style={controlsContainer}>
<div style={{display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center'}}>
<div>
<button style={{ width: '400px', height: '60px', minWidth: '200px', display:'block'}}
onClick={onReveal}>Reveal</button>
</div>
<div >
<button style={{width: '400px', height: '60px', minWidth: '200px'}}
onClick={onCopy}>Copy Meta</button>
</div>
</div>
</div>
</div>
)
}
class App extends React.Component{
constructor(props){
super(props);
this.state = {playing: false};
}
_onReveal() {
this.setState({playing: true})
}
_onCopy() {
window.alert('Meta data copied')
}
renderAltView() {
return (
<AltView />
)
}
render(){
const { width, height } = this.props;
if (!this.state.playing){
return (
<div>
<h2>Controls</h2>
<ControlView width={width} height={height}
onReveal={() => this._onReveal()}
onCopy={() => this._onCopy()}
/>
</div>);
}
return (<div><ContentView /></div>);
}
}
ReactDOM.render(<App width={W} height={H}/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Add justify-content: center; to the absolute positioned DIV (controlsContainer)

Resources