css flex-box nested layout have issue - css

I can't using flex-box well.
This is current state :
I want this flex layout :
This is my code :
Lobby.js (Container)
const TopBlock = styled.div`
display: flex;
`;
const Lobby = () => {
return (
<>
<TopBlock>
<CreateRoom />
<Profile />
</TopBlock>
</>
)
}
Profile.js
const ProfileBlock = styled.div`
`;
const Profile = () => {
return (
<ProfileBlock>
<p>hello0</p>
<p>hello1</p>
<p>hello2</p>
</ProfileBlock>
)
}
What should I do? ..T_T

I think , ProfileBlock should be wrapped and put into your <p>hello</p>. Because if using flexbox for ProfileBlock look like a container in this case for grouping inside the container we need wrapper. working example
Lobby.js (Container)
const TopBlock = styled.div`
display: flex;
height: 100vh;
`;
export const Lobby = () => {
return (
<>
<TopBlock>
<CreateRoom />
<Profile />
</TopBlock>
</>
);
};
Profile.js
const ProfileBlock = styled.div`
width: 100%;
height: 100%;
display: flex;
align-items: flex-start;
border: 3px solid red;
div {
display: flex;
flex-wrap: wrap;
}
p {
width: 200px;
display: flex;
color: black;
padding: 15px;
border: 2px solid blue;
}
`;
export const Profile = () => {
return (
<ProfileBlock>
<div className="profile-wrapper">
<p>hello0</p>
<p>hello1</p>
<p>hello2</p>
</div>
</ProfileBlock>
);
};

Related

Use a style for react.js map without using CSS

So I have this css code:
.tab-top {
padding-left: 12%;
padding-top: 2%;
color: var(--cloudy-white);
display: flex;
flex-direction: row;
font-family: "NTR Regular";
font-size: 15px;
}
.tab-top > div {
text-align: center;
margin-left: 3%;
border: 1px red solid;
}
How would I do this in react.js with the following code:
function Navigation() {
const topTabs = tabs.map(tab =>
<div>
{tab}
</div>
);
return (
<div className="tab-top">
{topTabs}
</div>
);
}
(tabs is declared)
Also I'm fairly new to react.js so if I can improve the following code in any way please leave suggestions.
you can use style of react if you want create mutiple css style do like this
function Navigation() {
const styles={ tabtop:{
textAlign: "center",
marginLeft: "2%",
marginTop: "1%",
},
anohter:{ width:"100%"},
}
const topTabs = tabs.map(tab =>
<div>
{tab}
</div>
);
return (
<div style={styles.tabtop}>
{topTabs}
</div>
);
}
or you can do it like that for single usage
function Navigation() {
const topTabs = tabs.map(tab =>
<div>
{tab}
</div>
);
return (
<div style={{
textAlign: "center",
marginLeft: "2%",
marginTop: "1%",
}}>
{topTabs}
</div>
);
}
or
i think it should be like this
import React from "react";
import styled from "styled-components";
const Thing = styled.div.attrs(() => ({ tabIndex: 0 }))`
.tab-top {
padding-left: 12%;
padding-top: 2%;
color: var(--cloudy-white);
display: flex;
flex-direction: row;
font-family: "NTR Regular";
font-size: 15px;
}
.tab-top > div {
text-align: center;
margin-left: 3%;
border: 1px red solid;
}
`;
function Navigation() {
const topTabs = tabs.map(tab =>
<div>
{tab}
</div>
);
return (
<Thing className="tab-top">
{topTabs}
</Thing>
);
}

how to align a component at the bottom of the page

below in App.js i am displaying a Todo app where Todo Component displays each Todo task and TodoForm is used display a input through which we can add task
import "./App.css";
import Todo from "./Components/Todo";
import React, { Component } from "react";
import TodoForm from "./Components/TodoForm";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
todos: [
{ id: 1, name: "First Todo", completed: true },
{ id: 2, name: "Second Todo", completed: false },
{ id: 3, name: "Third Todo", completed: false },
],
};
}
addTodo = (todo) => {
todo.id = this.state.todos.length + 1 || 0;
let todoList = [...this.state.todos, todo];
this.setState({ todos: todoList });
};
completeTodo = (id) => {
let todoList = [...this.state.todos];
const index = todoList.findIndex((todo) => todo.id === id);
todoList[index].completed = !todoList[index].completed;
this.setState({ todos: todoList });
};
deleteTodo = (id) => {
console.log(id);
let todoList = [...this.state.todos];
const index = todoList.findIndex((todo) => todo.id === id);
todoList.splice(index, 1);
this.setState({ todos: todoList });
};
render() {
return (
<div className="App">
<div className="developer">
<span>Developer</span>
<br />
<p>Kishore Pantra</p>
</div>
<h1 className="header">Todo React Component</h1>
<div className="todos">
{this.state.todos.map((todo) => (
<Todo
key={todo.id}
todo={todo}
completeTodo={this.completeTodo}
deleteTodo={this.deleteTodo}
/>
))}
</div>
<TodoForm addTodo={this.addTodo} />
</div>
);
}
}
here in App.css i am providing the css required for App.js
body,
html {
margin: 0;
padding: 0px;
box-sizing: border-box;
background-color: skyblue;
height: 100%;
overflow-y: hidden;
overflow-x: hidden;
}
.header {
color: white;
text-align: center;
}
.todos {
height: 400px;
overflow: auto;
margin: 5px;
padding: 5px;
border-radius: 5px;
background-color: yellowgreen;
}
.developer {
background-color: gold;
width: 150px;
text-align: center;
color: white;
transform: rotate(-45deg);
position: absolute;
top: 10px;
left: -10px;
}
Todo.js
import React, { Component } from "react";
import "./Todo.css";
export default class Todo extends Component {
completeTodo = (id) => {
this.props.completeTodo(id);
};
deleteTodo = (id) => {
this.props.deleteTodo(id);
};
render() {
return (
<div className="todo">
<p
style={{
textDecoration: this.props.todo.completed ? "line-through" : "",
}}
>
{this.props.todo.name}
</p>
<div className="status">
<button
className="completed"
onClick={() => this.completeTodo(this.props.todo.id)}
>
{this.props.todo.completed ? "Reinitialize Todo" : "Todo Completed"}
</button>
<button
className="remove"
onClick={() => this.deleteTodo(this.props.todo.id)}
>
X
</button>
</div>
</div>
);
}
}
Todo.css
.todo {
background-color: white;
display: flex;
flex-direction: row;
align-items: center;
margin: 10px;
padding: 10px;
border-radius: 5px;
}
.todo p {
width: 89%;
}
.status button {
margin: 2px;
border-radius: 100px;
outline: none;
border: 1px solid grey;
}
.completed {
background-color: rgb(6, 250, 38);
color: white;
}
.remove {
background-color: rgba(238, 15, 15, 0.884);
color: white;
}
TodoForm.js
import React, { Component } from "react";
import "./TodoForm.css";
export class TodoForm extends Component {
constructor(props) {
super(props);
this.state = {
todotext: "",
};
}
addTodo = (e) => {
e.preventDefault();
this.props.addTodo({ name: this.state.todotext, completed: false });
this.setState({ todotext: "" });
};
render() {
return (
<form className="todoform" onSubmit={this.addTodo}>
<input
type="text"
value={this.state.todotext}
onChange={(e) => this.setState({ todotext: e.target.value })}
placeholder="Add your Todo here..."
/>
</form>
);
}
}
export default TodoForm;
todoForm.css
.todoform {
display: flex;
justify-content: center;
}
.todoform input {
outline: none;
width: 98%;
padding: 10px;
margin: 10px;
border: none;
border-radius: 10px;
}
i want to align Todoform component at the bottom of the screen how can i align it.
To align TodoForm component to the bottom, You can use flexbox or grid. In this case, I used the grid because it is lighter (less code)
In App.css file on .App class selector You need to set this few properties.
.App {
min-height: 100vh;
margin: 0;
display: grid;
grid-template-rows: auto 1fr auto;
}
Before change =>
After change =>

Custom style on navbar when a section is active on the same page in Gatsby

I am trying to create a simple landing page with React. As per the title I have tried to get the active section heading (in the navbar) to be highlighted (change color) when the user scrolls to that section on the page, no success so far even after searching online for a long time. Really stuck. Following the tutorial, I am using styled-components for styling, different files for each component. Here is the code for my Navbar:
import React, { useState, useEffect } from 'react'
import styled from 'styled-components'
import { FaBars, FaTimes } from 'react-icons/fa'
import { IconContext } from 'react-icons/lib'
import { Link } from 'gatsby'
import Icon from '../images/Icon.png'
import { ButtonOne } from './Button'
import ScrollSpy from 'react-scrollspy-navigation';
import './layout.css'
const Navbar = () => {
const [click, setClick] = useState(false)
const [scroll, setScroll] = useState(false)
const handleClick = () => setClick(!click)
const changeNav = () => {
if (window.scrollY >= 130){
setScroll(true)
} else {
setScroll(false)
}
}
useEffect(() => {
changeNav()
window.addEventListener('scroll', changeNav)
}, [])
return (
<>
<IconContext.Provider value={{ color: '#fabf49'}}>
<Nav active={scroll} click={click}>
<NavbarContainer>
<NavLogo to='/'>
<NavIcon>
<img src={Icon} height={100} width={100} alt='Icon' />
</NavIcon>
</NavLogo>
<MobileIcon onClick={handleClick}>{click ? <FaTimes /> : <FaBars />}</MobileIcon>
<NavMenu onClick={handleClick} click={click}>
<ScrollSpy offsetTop={80} duration={1500}>
<a href='/#s1' ref={React.createRef()}>
<NavItem>
<NavLinks to='/#s1' activeClassName={`active`}>Company</NavLinks>
</NavItem>
</a>
<a href='#s4' ref={React.createRef()}>
<NavItem>
<NavLinks to='/#s4' activeClassName={`active`}>Features</NavLinks>
</NavItem>
</a>
<a href='#s7' ref={React.createRef()}>
<NavItem>
<NavLinks to='/#s7' activeClassName={`active`} >Partners</NavLinks>
</NavItem>
</a>
<a href='#s6' ref={React.createRef()}>
<NavItem>
<NavLinks to='/#s6' activeClassName={`active`}>Updates</NavLinks>
</NavItem>
</a>
<a href='#s8' ref={React.createRef()}>
<NavItem>
<NavLinks to='/#s8' activeClassName={`active`}>Careers</NavLinks>
</NavItem>
</a>
<a href='#s8' ref={React.createRef()}>
<NavItem>
<NavLinks to='/#s8' activeClassName={`active`}>Contact Us</NavLinks>
</NavItem>
</a>
<NavBtn>
<ButtonOne a href='#s8' ref={React.createRef()} style={{scrollBehavior: "smooth"}}>BOOK NOW</ButtonOne>
</NavBtn>
</ScrollSpy>
</NavMenu>
</NavbarContainer>
</Nav>
</IconContext.Provider>
</>
)
}
export default Navbar
const Nav = styled.div`
background: ${({ active }) => (active ? '#1b2227' : 'transparent')};
height: 80px;
display: flex;
justify-content: center;
align-items: center;
font-size: 1rem;
position: sticky;
top: 0;
z-index: 999;
#media screen and (max-width: 1120px) {
background: ${({ click }) => (click ? '#1b2227' : 'transparent')};
transition: 0.8s all ease;
position: sticky;
background: ${({ active }) => (active ? '#1b2227' : 'transparent')};
height: 80px;
display: flex;
justify-content: center;
align-items: center;
font-size: 1rem;
position: sticky;
top: 0;
z-index: 999;
}
`
const NavbarContainer = styled.div`
display: flex;
justify-content: space-between;
height: 80px;
z-index: 1;
width: 100%;
`
const NavLogo = styled(Link)`
color: white;
justify-content: flex-start;
cursor: pointer;
text-decoration: none;
font-size: 1.5rem;
display: flex;
align-items: center;
margin-left: 2.5rem;
`
const NavIcon = styled.div`
margin: 0 0.5rem 0 2rem;
`
const MobileIcon = styled.div`
display: none;
#media screen and (max-width: 1120px) {
display: block;
position: absolute;
top: 0;
right: 0;
transform: translate(-100%, 60%);
font-size: 1.8rem;
cursor: pointer;
}
`
const NavMenu = styled.ul`
display: flex;
align-items: center;
list-style: none;
text-align: center;
#media screen and (max-width: 1120px) {
display: flex;
flex-direction: column;
width: 100%;
height: 90vh;
position: absolute;
top: ${({ click }) => (click ? '100%' : '-1000px')};
opacity: 1;
transition: all 0.2s ease;
background: #1b2227;
color: #fabf49;
}
`
const NavLinks = styled(Link)`
color: #fff;
display: flex;
align-items: center;
text-decoration: none;
padding: 0.5rem 1rem;
height: 100%;
&:hover {
color: #fabf49;
}
#media screen and (max-width: 1120px) {
text-align: center;
padding: 2rem;
width: 100%;
display: table;
color: #fabf49;
&:hover {
color: white;
transition: all 0.3s ease;
}
}
`
const NavItem = styled.li`
height: 80px;
margin-right: 2rem;
#media screen and (max-width: 1120px) {
width: 100%;
}
`
const NavBtn = styled.div`
display: flex;
align-items: center;
margin-right: 3rem;
#media screen and (max-width: 1120px) {
display: none;
}
`
and here is my index page where all the different sections are assembled into the landing page:
import * as React from "react"
import Layout from "../components/layout"
import Seo from "../components/seo"
import Hero from "../components/Hero"
import SectionTwo from "../components/SectionTwo"
import SectionThree from "../components/SectionThree"
import SectionFour from "../components/SectionFour"
import SectionFive from "../components/SectionFive"
import SectionSix from "../components/SectionSix"
import Partners from "../components/Partners"
const IndexPage = () => (
<Layout>
<Seo title="CARNIVAL" />
<section id='s1'><Hero /></section>
<section id='s2'><SectionTwo /></section>
<section id='s3'><SectionThree /></section>
<section id='s4'><SectionFour /></section>
<section id='s5'><SectionFive /></section>
<section id='s6'><SectionSix /></section>
<section id='s7'><Partners /></section>
</Layout>
)
export default IndexPage
For additional info here is the Layout component:
import * as React from "react"
import Footer from "./Footer"
import { GlobaStyle } from "./GlobalStyles"
import Navbar from "./Navbar"
const Layout = ({ children }) => {
return (
<>
<GlobaStyle />
<Navbar />
<main>{children}</main>
<section id='s8'><Footer /></section>
</>
)
}
export default Layout
and the css file (many related answers have a css file so I tried that too):
.active{
color: #fabf49;
}
I have managed to get the scrollspy working, however I am stuck on the active part being highlighted/custom styled in the navbar.

min-height pushes the content outside of div instead of growing inside div

I have created a simple to-do app. I am creating div for every to-do being created and set min-height for the div in case if the content grows larger than div but even after setting the min-height of div content grows outside of div. Could anyone please point out what I am missing? I have attached the screenshot of the output.
App.css
body {
background-color: rgb(238, 174, 174);
}
.App {
border: 1px solid;
border-radius: 20px;
min-height: 200px;
width: 30%;
margin: auto;
display: flex;
flex-direction: column;
align-items: center;
}
Todo.css
.Todo {
border: 1px solid black;
margin: 10px;
width: 300px;
height: 50px;
min-height: 50px;
padding-left: 9px;
padding-bottom: 9px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Todo.js
import React from 'react';
import "./Todo.css"
const Todo = ({title, description}) => {
return (
<div className="Todo">
<p>{title}</p>
</div>
)
}
export default Todo
App.js
import React, {useState} from 'react';
import Todo from './Todo';
import './App.css';
function App() {
const [todos, setTodos] = useState([]) // todos => to store the value, setTodos => to update the state
const [input, setInput] = useState("")
const handleSubmit = (e) => {
e.preventDefault();
setTodos([...todos, input])
setInput("")
}
return (
<div className="App">
<h1>To-do-app</h1>
<form>
<input type="text" onChange = {(e) => setInput(e.target.value)} value={input} />
<button type="submit" onClick={handleSubmit}>Add Todo</button>
</form>
{
todos.map(todo => {
return <Todo title={todo} />
})
}
</div>
);
}
export default App;
Try this - lose the min-height change height: auto
.Todo {
border: 1px solid black;
margin: 10px;
width: 300px;
height: auto;
padding-left: 9px;
padding-bottom: 9px;
}
You need to remove the height from Todo.css(Todo class) and just keep the min-height
.Todo {
border: 1px solid black;
margin: 10px;
width: 300px;
min-height: 50px;
padding-left: 9px;
padding-bottom: 9px;
}

How to set the content of div to be visible inside parent div using css

i want the content inside the expandable_container div to be visible.
Now it moves up while adding align-items: center to the expandable div.
I have a side panel which contains list items. when the list item overflows i add a expand button. clicking that button should show the full content of list item. It works but then. when the content in list item overflows then the content in list item is half seen. like in below image
i want that content to properly placed. I tried adding padding-top to expandable class. However this will affect other list items that doesnt have expandable component. How can i fix this. Below is the code,
export default class Expandable extends React.PureComponent{
constructor(props) {
super(props);
this.expandable_ref = React.createRef();
this.state = {
expanded: false,
overflow: false,
};
}
componentDidMount () {
if (this.expandable_ref.current.offsetHeight <
this.expandable_ref.current.scrollHeight) {
this.setState({overflow: true});
}
}
on_expand = () => {
this.setState({expanded: true});
console.log("in expnad");
};
on_collapse = () => {
this.setState({expanded: false});
};
render () {
return (
<div className={(this.state.overflow ?
this.props.container_classname : '')}>
<div className={(this.state.overflow ?
this.props.classname : '')} style={{overflow: 'hidden',
display: 'flex', height: (this.state.expanded ? null :
this.props.base_height)}}
ref={this.expandable_ref}>
{this.props.children}
</div>
{this.state.overflow && this.state.expanded &&
<div className={this.props.expand}>
<button onClick={this.on_collapse}>
{this.props.arrow_up}</button>
</div>}
{this.state.overflow && !this.state.expanded &&
<div className={this.props.expand}>
<button onClick={this.on_expand}>
{this.props.arrow_down}</button>
</div>}
</div>
);
}
}
Class SidePanel extends React.purecomponent {
switch (notification.type) {
case 'new_model_uploaded':
return (
<Expandable
base_height={42}
arrow_down={<SvgAccDown className='grey' width="10"
height="10"/>}
arrow_up={<SvgAccUp className='grey' width="26"
height="26"/>}
container_classname='expandable_container'
classname='expandable'
expand='expand'>
<ListItem
icon={<SvgProject width="26" height="26"/>}
text={<Text
name={notification.initiator.name}
text=' created model '
model_name={notification.attributes.modelname}/>}
timestamp={notification.timestamp}>
<div className="additional_details">
<PreviewImage
width={70}
height={70}
model_id={filtered_model.id}
/>
</div>
</ListItem>
</Expandable>
);
case 'deleted':
return (
<ListItem
icon={<Svg width="20" height="22"/>}
text={<Text
name={notification.initiator.name}
text=' deleted model '
model_name={notification.attributes.modelname}/>}
timestamp={notification.timestamp}/>
);}
}
function ListItem(props) {
return (
<li className="notification">
<div className="details_container">
<div className="details">
{props.icon}
{props.text}
<Timestamp>{props.timestamp}</Timestamp>
</div>
{props.children}
</div>
</li>
);
}
.notification {
display: flex;
flex-direction: row;
font-size: 12px;
padding: 8px;
min-height: 49px;
flex-grow: 1;
li {
list-style: none;
}
.details_container {
display: flex;
flex-direction: column;
flex-grow: 1;
margin-right: 8px;
.details {
display: flex;
color: #333;
align-items: center;
flex-grow: 1;
svg {
margin-right: 8px;
margin-left: 7px;
flex: 0 0 auto;
align-self: center;
flex-shrink: 0;
}
span {
flex-grow: 5;
text-align: left;
}
time {
flex: 0 0 auto;
margin-left: 8px;
padding-top: 2px;
color: #CCCCCC;
}
}
.additional_details {
flex-basis: 100%;
width: 226px;
margin-left: 11%;
span {
display: block;
word-break: break-all;
margin-left: 2px;
}
}
}
}
.expandable_container {
display: flex;
margin-top: 8px;
flex-direction: column;
border-bottom: 1px solid #CCCCCC;
.expandable {
align-items: center;
padding-top: 35px;
}
}
.expand {
display: flex;
align-items: center;
position: relative;
top: 10px;
border: 1px solid #CCCCCC;
width: 150px;
height: 20px;
left: 30%;
background-color: $white;
justify-content: center;
}
Could someone help me solve this thanks.

Resources