How do I get Flex to work in my react app? - javascript

Basically I have two divs setup up and im trying to use flex box to easily size them so they both equally take up half the screen vertically using react. For some reason they are turning out looking like this.
Iv'e tried reinstalling npm but that didn't work at all, and i'm pretty sure my syntax is just fine.
This is my App.css
.wrapper,html,body {
height: 100%;
margin: 0;
}
.wrapper {
display: flex;
flex-direction: column;
}
.nav {
background-color: red;
flex: 1;
}
.main {
background-color: blue;
flex: 1;
}
This is my App.js
import {Row, Col } from "react-bootstrap";
import React, { Component } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import './App.css'
class App extends Component {
render() {
return (
<div className = 'wrapper'>
<div className = 'nav'>
<text>hey</text>
</div>
<div className = 'main'>
<text>hey</text>
</div>
</div>
);
}
}
export default App;

They should work if you remove flex-direction: column; - you actually want flex-direction: row;, which is the default.

You're missing the flex: 1 prop inside the .wrapper css definition. The definition should look like this:
.wrapper {
display: flex;
flex:1;
flex-direction: column;
}
With flex: 1 you're telling the wrapper to use all the available space. Otherwise, it just use what it needs no matter the height.
Here's the entire CSS:
.wrapper,
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
display: flex;
flex: 1;
flex-direction: column;
}
.nav {
background-color: red;
flex: 1;
}
.main {
background-color: blue;
flex: 1;
}
See the result:
Anyway, I totally recommend using Bootstrap v4 which is flexbox based by default.

Your code is all fine, just need add flex:1 to wrapper class.
you can read more about flex here : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
.wrapper,
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
display: flex;
flex-direction: column;
flex: 1;
}
.nav {
background-color: red;
flex: 1;
}
.main {
background-color: blue;
flex: 1;
}
<div class='wrapper'>
<div class='nav'>
<text>hey</text>
</div>
<div class='main'>
<text>hey</text>
</div>
</div>

Related

Get ID of fully visible component

I tried to make code showing the number of component which is currently fully visible.
I used Intersection Observer API and to make it, used callback entry.intersectionRatio === 1.0.
I want to remark currently fully visible component at state currentView but it doesn't show anything.
I think currentView is not changed, althought I use useEffect
May I know which part is wrong and how to fix it??
code :
import styled from "styled-components";
import { useState, useEffect } from "react";
export default function App() {
const [currentView, setCurrentView] = useState();
useEffect(() => {
const components = document.querySelectorAll(".comp");
const componentObserver = new IntersectionObserver(function (
entries,
observer
) {
entries.forEach(function (entry) {
if (entry.isIntersecting && entry.intersectionRatio === 1.0) {
setCurrentView(entry.target.id);
}
});
});
components.forEach((comp) => {
componentObserver.observe(comp);
});
}, [currentView, setCurrentView]);
return (
<Wrap>
<div className="fixed">currentcomponent : {currentView}</div>
<div id="part-1" className="compo1 comp">
components 1
</div>
<div id="part-2" className="compo2 comp">
components 2
</div>
<div id="part-3" className="compo3 comp">
components 3
</div>
</Wrap>
);
}
const Wrap = styled.div`
border: 3px solid black;
width: 100vw;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
.fixed {
position: sticky;
top: 0;
}
.compo1 {
border: 3px solid red;
display: flex;
justify-content: center;
align-items: center;
width: 90vw;
height: 90vh;
}
.compo2 {
border: 3px solid blue;
display: flex;
justify-content: center;
align-items: center;
width: 90vw;
height: 90vh;
}
.compo3 {
border: 3px solid green;
display: flex;
justify-content: center;
align-items: center;
width: 90vw;
height: 90vh;
}
`;
CodeSandBox :
CodeSandBox

Changing style in JS and changing style in CSS leads to different results

When I define the style of a divider using CSS, the output is this (green cell takes up the entire row 👇):
When I define the style of a divider using JS, the output is this: Small green cube
Why are the results different despite the code essentially doing the same things?
JS version
function App() {
return (
<div class = "App" >
<div display = "flex" flexDirection = "row" flex = "1">
<div class = "cell"></div>
</div>
</div>
);
}
CSS version
function App() {
return (
<div class = "App" >
<div class = "row-container">
<div class = "cell"></div>
</div>
</div>
);
}
CSS code
.App {
text-align: center;
display: flex;
flex-direction: row;
}
.row-container {
display: flex;
flex-direction: row;
flex: 1;
/*justify-content: flex-center;*/
}
.row-container1 {
display: flex;
flex-direction: row;
flex: 1;
/*justify-content: flex-center;*/
}
.cell {
flex: 1;
padding: 10px;
margin: 10px;
background-color: green;
border: 1px solid red;
text-align: center;
}

React flexbox is overflowing screen size

I'm trying to get a div to render until the bottom of the screen/page (and no further than that).
I'm able to do that successfully as long as this div is the only thing in the entire page. However, it's overflowing the page whenever I have anything above it (in this example, the text Some Header).
https://codesandbox.io/s/keen-bird-phx1f?file=/src/App.js
The React code:
import "./styles.css";
import React, { Fragment } from "react";
export default function App(props) {
return (
<Fragment>
<div>Some Header</div>
<div className="test1">
<div className="dashbar">Dash</div>
<div className="other-content">Other</div>
</div>
</Fragment>
);
}
The CSS code:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.test1 {
display: flex;
height: 100vh;
border: 10px solid green;
}
.dashbar {
flex: 1 0 10%;
background: dodgerblue;
}
.other-content {
flex: 1 0 90%;
background: papayawhip;
}
How can I make it so that this div will stop at the bottom of the page and not overflow like this?
If I remove <div>Some Header</div>, then it behaves as expected:
.test1 has a height of 100vh, meaning you are forcing it to be exactly as tall as the viewport. But it has a header above it! So, the header necessarily pushes it down and it overflows the screen. You need a bit more of Flexbox trickery to get it right, especially flex-grow:1.
* {
box-sizing: border-box;
}
body {
margin: 0;
}
#root {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.test1 {
display: flex;
flex-grow: 1;
border: 10px solid green;
}
.dashbar {
flex: 1 0 10%;
background: dodgerblue;
}
.other-content {
flex: 1 0 90%;
background: papayawhip;
}
<body>
<div id="root">
<div>
Some Header<br>
with a couple<br>
of lines in it
</div>
<div class="test1">
<div class="dashbar">Dash</div>
<div class="other-content">Other</div>
</div>
</div>
</body>
It's because "test1" has height as 100vh and there is a static header text which has some height. Try this to fix:
* {
box-sizing: border-box;
line-height: 15px;
}
.test1 {
display: flex;
height: calc(100vh - 15px);
border: 10px solid green;
}
--- Dynamic solution:
https://codesandbox.io/s/stupefied-agnesi-x496f?file=/src/App.js

Can't render project cards properly. Reactjs Gatsbyjs Graphql

I'm trying to make a portfolio site using gatsbyjs and I'm currently having problems creating project cards using graphql and gatsby image sharp. I'm not sure if it's just my css or my js.
Basically I have a projects page that is getting data from a local JSON file and then passing the data to a card component which is then rendered on the projects page. I have css grid for the card container but the problem is the cards component doesn't seem to recognize the grid and just spills out or they just goes down/across the page. Kinda hard to explain. Still learning aha. I just want 3 cards on top and then 3 on the bottom.
https://github.com/verv0022/portfolio
they seem to take up the entire grid space even though i have a width?
Project Page
const Projects = () => {
const data = useStaticQuery(graphql`
query ProjectsQuery {
allProjectsJson {
edges {
node {
id
name
description
url
image {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
`)
const projects = data.allProjectsJson.edges
console.log(projects)
return (
<section className="projects">
<main className="projects-content">
<ScrollAnimation
className="projects-title"
animateOnce={true}
animateIn="slideInLeft"
animatePreScroll={false}
initiallyVisible={false}
>
<h2>Here are some of my projects...</h2>
</ScrollAnimation>
<section className="project-preview-container">
<div className="project-preview-item-container">
{projects.map(({ node: project }) => {
return (
<ProjectPreviewItem
key={project.id}
name={project.name}
description={project.description}
imageData={project.image.childImageSharp.fluid}
url={project.url}
/>
)
})}
</div>
</section>
</main>
</section>
)
}
export default Projects
Card Component
import React from "react"
import Image from "gatsby-image"
import "./Projects.css"
const ProjectPreviewItem = ({ name, imageData, description, url }) => {
return (
<div className="project-item">
<div className="image-container">
<Image fluid={imageData} alt={name} className="project-img"></Image>
</div>
<div className="project-item-details">
<h2 className="project-url">
<a href={url}>{name}</a>
</h2>
<p className="project-description">{description}</p>
</div>
</div>
)
}
export default ProjectPreviewItem
CSS
body,
html {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.projects {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(6, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
display: grid;
height: 100vh;
}
.projects-content {
grid-area: 2 / 2 / 6 / 6;
}
.projects-title {
font-size: 26px;
}
.project-preview-container {
grid-area: 3 / 2 / 6 / 6;
margin-top: 6rem;
background-color: lightgray;
}
/* .project-preview-item-container {
} */
.projects-title {
width: 40rem;
}
.project-item {
display: flex;
flex-direction: column;
justify-content: center;
border: black solid 2px;
padding: 1rem;
margin: 1rem;
width: 250px;
height: auto;
}
.project-item-details {
margin-top: 20px;
}
#keyframes slideInLeft {
from {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
visibility: visible;
}
to {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
Your markup looks something like this currently.
.projects
.projects-content
.project-preview-container
.project-item
.project-item
.project-item
But should be something like.
.projects
.project-item
.project-item
.project-item
Grid items must be children of the grid.
.projects {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
background-color: lightgray;
}
.project-item {
border: 1px solid black;
height: 80px;
background: white;
}
<div class="projects">
<div class="project-item">One</div>
<div class="project-item">Two</div>
<div class="project-item">Three</div>
<div class="project-item">Four</div>
<div class="project-item">Five</div>
<div class="project-item">Six</div>
</div>
Have a read of the Basic Concepts of Grid Layout

How to reorder divs using flex box?

I am trying to keep a seo friendly and semantic structure for my DOM, without repeating whole elements to display them in various positions.
My layout is based on display: flex items. I try to achieve the following:
Important things to know:
I do not want to show/hide divs based on the window width (to avoid unnecessary duplicates)
None of the divs has a known or fixed height
On desktops the divs should be vertical centered, while the right column builds a tag-team (behaves like one single div)
The layout needs to support at least IE11+
Is there a css only solution to achieve this?
If not, it would be easy to cut out the green div and paste its content into the pink one using javascript. But I do have concerns about the performance and "flickering" using this, although resizing the browser makes it more complicated. Do I make this needlessly complicated?
Here is fiddle showing a working solution but with javascript:
CODEPEN DEMO
In general, you can't do this with Flexbox alone, though there might be a compromise based on each given case.
With Flexbox alone, using fixed height, you can accomplish this
* {
box-sizing: border-box;
}
body, html {
margin: 0;
}
.flex {
width: 90%;
margin: 5vh auto;
height: 90vh;
background: rgba(0, 0, 0, 0.05);
display: flex;
flex-flow: column wrap;
}
.flex div {
flex: 1;
width: 50%;
}
.flex div:nth-child(2) {
order: -1;
}
.flex::before {
content: '';
height: 100%;
}
#media (max-width:768px) {
.flex div {
width: auto;
}
.flex::before {
display: none;
}
.flex div:nth-child(2) {
order: 0;
}
}
/* styling */
.flex-child {
color: white;
font-size: 2em;
font-weight: bold;
}
.flex-child:nth-child(1) {
background: #e6007e;
}
.flex-child:nth-child(2) {
background: #f4997c;
}
.flex-child:nth-child(3) {
background: #86c06b;
}
<div class="flex">
<div class="flex-child">
<div>Top/Right</div>
</div>
<div class="flex-child">
<div>Center/Left</div>
</div>
<div class="flex-child">
<div>Bottom/Right</div>
</div>
</div>
In this case, where no fixed height is allowed, you can combine Flexbox and float.
By set up it for mobile using Flexbox where you add the center item first in the markup and then, with order, move it between the top and bottom.
With a media query you then simply make the flex container a block element and use float to position the left to the left and the right to the right.
* {
box-sizing: border-box;
}
body, html {
margin: 0;
}
.flex {
max-width: 1024px;
width: 90%;
margin: 5vh auto;
height: 90vh;
background: rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
}
.flex-child {
color: white;
font-size: 2em;
font-weight: bold;
padding: 5%;
flex-basis: 33.333%;
display: flex;
align-items: center;
}
.flex-child:nth-child(1) {
background: #e6007e;
order: 1;
}
.flex-child:nth-child(2) {
background: #f4997c;
}
.flex-child:nth-child(3) {
background: #86c06b;
order: 2;
}
#media (min-width: 768px) {
.flex {
display: block;
}
.flex-child {
width: 50%;
}
.flex-child:nth-child(1) {
float: left;
height: 100%;
}
.flex-child:nth-child(2),
.flex-child:nth-child(3) {
float: right;
height: 50%;
}
}
<div class="flex">
<div class="flex-child">
<div>Center/Left</div>
</div>
<div class="flex-child">
<div>Top/Right</div>
</div>
<div class="flex-child">
<div>Bottom/Right</div>
</div>
</div>
Update
Here is another version combining Flexbox with position: absolute, which also vertically center the items in desktop mode
Updated, added a script to control so the absolute positioned element won't get bigger than the right items, and if so, adjust the flex containers height.
Note, the script is by no means optimized, it is only there to show how a fix in certain situations
(function() {
window.addEventListener("resize", resizeThrottler, false);
var fp = document.querySelector('.flex');
var fi = fp.querySelector('.flex-child:nth-child(1)');
var resizeTimeout;
function resizeThrottler() {
// ignore resize events as long as an actualResizeHandler execution is in the queue
if ( !resizeTimeout ) {
resizeTimeout = setTimeout(function() {
resizeTimeout = null;
actualResizeHandler();
// The actualResizeHandler will execute at a rate of 15fps
}, 66);
}
}
function actualResizeHandler() {
// handle the resize event
if (fp.offsetHeight <= fi.offsetHeight) {
fp.style.cssText = 'height: '+fi.offsetHeight+'px';
} else {
fp.style.cssText = 'height: auto';
}
}
window.addEventListener('load', function() {
actualResizeHandler();
})
}());
* {
box-sizing: border-box;
}
body, html {
margin: 0;
}
.flex {
position: relative;
max-width: 1024px;
width: 90%;
margin: 5vh auto;
height: 90vh;
background: rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
}
.flex-child {
color: white;
font-size: 2em;
font-weight: bold;
padding: 5%;
}
.flex-child:nth-child(1) {
order: 1;
}
.flex-child:nth-child(3) {
order: 2;
}
.flex-child:nth-child(1) div {
background: #e6007e;
}
.flex-child:nth-child(2) div {
background: #f4997c;
}
.flex-child:nth-child(3) div {
background: #86c06b;
}
#media (min-width: 768px) {
.flex {
justify-content: center;
}
.flex-child {
width: 50%;
}
.flex-child:nth-child(1) {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.flex-child:nth-child(n+2) {
margin-left: 50%;
}
}
<div class="flex">
<div class="flex-child">
<div>Center/Left<br>with more<br>content<br>than any<br>of the<br>other items<br>other items<br>other items<br>other items<br>other items</div>
</div>
<div class="flex-child">
<div>Top/Right<br>with more<br>content</div>
</div>
<div class="flex-child">
<div>Bottom/Right<br>with more</div>
</div>
</div>
With script one can also reorder/move items between elements.
Stack snippet
You can also combine this with a media query, and use it to do the actual re-order of the elements
$( document ).ready(function() {
$(window).resize(function() {
if ($( window ).width() < 600 ) {
$(".one").insertBefore("#b");
} else {
$(".one").insertBefore(".two");
}
});
});
.outer, #flex, #flex2 {
display: flex;
flex-direction: column;
}
#a {
order: 4;
background: #ccc;
}
#b {
order: 1;
background: #aaa;
}
#c {
order: 3;
background: #d33;
}
.one {
order: 2;
background: #aaa;
}
.two {
order: 5;
background: #aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer">
<div id="flex">
<div id="a">A</div>
<div id="b">B</div>
<div id="c">C</div>
</div>
<div id="flex2">
<div class="one">Show me 2nd</div>
<div class="two">Show me 5th</div>
</div>
</div>
Update 2 (answered at another question but later moved here)
If we talk about smaller items, like a header or smaller menus, one can do what many website platform providers like "squarespace", "weebly", "wordpress", etc does. Their templates holds different markup structures, where an item sometimes exist twice, one visible for desktop, another for mobile.
Also, being so small, there will be less to nothing when it comes to performance (and personally I don't see anymore issue with this than having duplicate CSS rules, one for each screen size, and happily do this instead of introducing script).
Fiddle demo
Stack snippet
.container {
display: flex;
}
.container > div {
width: 50%;
}
.container div:nth-child(-n+2) {
border: dashed;
padding: 10px;
}
.container > div:nth-child(1) {
display: none; /* hide outer "Flower" */
}
#media (max-width:768px) {
.container {
flex-direction: column;
}
.container div {
width: auto;
}
.container div:nth-child(1) {
display: block; /* show outer "Flower" */
}
.container div:nth-child(3) div:nth-child(1) {
display: none; /* hide inner "Flower" */
}
}
<div class="container">
<div>Flower</div>
<div>Tree</div>
<div>
<div>Flower</div>
<div>Bee</div>
</div>
</div>

Categories