How to adjust height of div based on content - css

I have designed a reusable ListItem component which I then map over in another component to create a List. The list looks good in an expanded window however when I shrink the window size the text overflows out of the div and onto subsequent items in the list. I am trying to understand how to make it so the height of the list item changes depending on the text inside.
I have searched for an answer and tried the following without success:
in #list-item set height:auto
in #list-item set height:fit-content
In displaying component apply a style of "display:block" to ListItem component during mapping.
Issue Screenshot
Result of solutions 1 and 2 above
No difference using solution 3
ListItem.js
export default function ListItem(props) {
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => setAnchorEl(event.currentTarget);
const handleClose = () => setAnchorEl(null);
return (
<div>
<div id='list-item'>
<div id="label-container">
<Typography id="type" variant="caption">{props.type}</Typography>
<p id="title">{props.title}</p>
</div>
<SvgIcon id="icon" onClick={handleClick}>
<ListIcon />
</SvgIcon>
</div>
<Divider id="divider" />
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>View / Edit</MenuItem>
<MenuItem onClick={handleClose}>Add to Community</MenuItem>
<MenuItem onClick={handleClose}>Share with...</MenuItem>
</Menu>
</div>
)
}
ListItem.css
#list-item {
display:flex;
width:70%;
min-height:54px;
align-items: center;
justify-content: center;
position: relative;
margin: 0 auto;
}
#label-container {
display:flex;
flex-direction: column;
justify-content: center;
}
#type {
position: absolute;
margin-right: 40px;
top: 5px;
left: 10px;
}
#title {
position: absolute;
margin-top: 0px;
margin-right: 40px;
top:25px;
left:10px;
}
#divider {
width:70%;
margin: 0 auto;
}
#no-margin {
margin:0;
}
#icon {
position: absolute;
fill: #70CDE5;
right: 10px;
}
#media screen and (max-width: 600px){
#list-item{
width:100%;
}
#divider {
width: 100%;
}
}
Displaying Component
...
{listData.map((item, index) => (
<ListItem key={item.title} type={item.type} title={item.title} />
))}
...
Thank you

It's probably because you have position: absolute on your Typography and p.
When set position: absolute to any element it removed it from the document flow, that's why your list height is the min-height: 54px only.
Try removing position: absolute
#type {
margin-right: 40px;
}
#title {
margin-top: 0px;
margin-right: 40px;
}

Related

CSS input form not functioning when positioned on page

When I move my input element on the page using it's parent element I can't use it anymore to type something in or hit submit. I've tried using padding using the form's 'input' class but that just stretches out the form.
I'm using a React component.
<div>
<div class='input-container'>
<form class='input' onSubmit={searchQuery}>
<input placeholder='search wikipedia' onChange={searchField} />
<input
class='search-img'
type='image'
src='https://assets.stickpng.com/images/59cfc4d2d3b1936210a5ddc7.png'
value='search'
/>
</form>
</div>
{resultInfo.map((result) => (
<a
class='page-link'
href={"http://en.wikipedia.org/?curid=" + result[1]}
>
{result[0]}
</a>
))}
</div>
My CSS:
* {
box-sizing: border-box;
}
.page-link,
.page-link:visited {
color: #000000;
display: block;
}
.logo-container {
display: flex;
justify-content: center;
}
.logo {
position: fixed;
top: 10%;
left: 27%;
height: 250px;
}
.input-container {
padding-top: 260px;
padding-left: 520px;
}
.search-img {
height: 14px;
padding-left: 5px;
}

How to display a fixed navbar in Nextjs?

I have a Nextjs app that displays the same navbar on each page. The navbar has a fixed position. The display is correct on the homepage (written in index.tsx). But when I click on a new page, the new page is hidden behind the navbar!
The issue disappears if I remove the fixed position property. But I can't believe Nextjs doesn't support such a basic task.
The code is very simple:
// _app.tsx
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<Navbar />
<Component {...pageProps} />
</>
);
}
export default MyApp;
// about.tsx
const About: NextPage = () => {
return (
<section>
<h1>About</h1>
</section>
);
};
export default About
// navbar.tsx
export default function Navbar() {
const router = useRouter();
return (
<nav className={styles.navbar}>
<Link href="/">
<Image
src={icon.src}
className={styles.logo}
alt="logo"
width={70}
height={70}
/>
</Link>
<ul className={styles.list}>
<li
className={
router.route === "/about" ? styles.listItemActive : styles.listItem
}
>
<Link href="/about">About</Link>
</li>
</ul>
</nav>
);
}
//navbar.module.css
.navbar {
background-color: var(--dark);
color: #fff;
height: 80px;
width: 100vw;
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
position: fixed;
z-index: 999;
}
.logo {
cursor: pointer;
}
.list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
align-items: center;
}
.listItem {
cursor: pointer;
}
.listItemActive {
cursor: pointer;
color: var(--red);
}
How to fix this?
Just add a position to your css.
top: 0px;
right: 0px;
left: 0px;
https://developer.mozilla.org/docs/Web/CSS/position
If what you want is to have a sticky navbar, you can do it with pure CSS with position: sticky like this:
header, nav, main {
padding: 1.7rem 1rem;
}
header {
background-color: #d99;
}
nav {
position: sticky;
top: 2rem;
background-color: #9d9;
}
main {
height: 100vh;
background-color: #99d;
}
--
<header>
Header
</header>
<nav>
Navbar
</nav>
<main>
Main
</main>
position: sticky;
top: 0px;
right: 0px;
left: 0px;
this worked for me!

How to fit React Modal size children?

I am trying to load a dynamic login page with React Modal. Is there a way to make React Modal resize to the size of its child elements?
//App.js
import "./styles/app.scss";
import Layout from './options/Layout'
import Login from './Components/Login'
import { useState } from "react";
import Modal from 'react-modal'
function App() {
const [OpenModal, setOpenModal] = useState(false)
return (
<div id="app" className="App">
<Layout>
<button onClick = {() => setOpenModal(true)}>open modal</button>
<Modal isOpen = {OpenModal}>
<Login/>
</Modal>
</Layout>
</div>
);
}
export default App;
//login.scss
.login {
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height: 280px;
margin: 0 auto;
background-color: #5c8fc2;
border-radius: 30px;
}
.login_top {
display: flex;
align-items: center;
justify-content: center;
margin-top: -40px;
margin-bottom: 20px;
color: whitesmoke;
}
.login_register_container {
border: none;
outline: none;
border-radius: 50%;
}
button {
margin-right: 12px;
margin-top: 30px;
border: none;
border-radius: 4px;
cursor: pointer;
}
I want to dynamically manage the size according to the child element.
I've tried several methods, but without success. How to fit modal's component to child element???
If you use the developer tools you can see that the content grows because they have applied some styles to the modal.
position: absolute;
inset:40
inset is same as
top: 40px;
left: 40px;
right: 40px;
bottom: 40px;
If you want your content to be exactly the same size as your content, you can remove the right and bottom from the styles.
<ReactModal
isOpen={true}
contentLabel="Minimal Modal Example"
className="Modal"
>
<div>
<div style={{ height: '500px' }}>Some content</div>
</div>
<button onClick={() => {}}>Close Modal</button>
</ReactModal>
CSS:
.Modal {
position: absolute;
top: 40px;
left: 40px;
background-color: papayawhip;
}
You will lose equal spacing on all sides of the modal if you do this though.
Here is an example. https://stackblitz.com/edit/react-vxe3cn

changing CSS of element on page scroll

I have a fixed header component as the two pics below illustrate. The current styling that I have is fine for when the page loads and nothing has changed. However, I want the header to have a visible border-bottom of say 1px solid black as soon as the user starts to scroll down the page. So in this case, this styling change would apply to the second pic. How can I accomplish this?
header on page load:
header on scroll:
Header.js:
const Header = props => {
return (
<header className="header-container">
<div className="logo-container">
<img className="white-logo" src={logo} alt="Food Truck TrackR logo white" />
</div>
<section className="header-section-one">
<div className="location-sub-div">
<i class="fas fa-map-marker-alt"></i>
<h3>User Location</h3>
</div>
<div className="order-sub-div">
<i class="fas fa-store"></i>
<h3>Order now</h3>
</div>
</section>
<section className="header-section-two">
<NavLink to="/dine/search" className="search-sub-div">
<i class="fas fa-search search-icon"></i>
<h3>Search</h3>
</NavLink>
<div className="acct-sub-div">
<i class="fas fa-user acct-icon"></i>
<h3>Account</h3>
</div>
</section>
</header>
)
}
Header.scss:
.header-container {
width: 100%;
height: 9vh;
display: flex;
align-items: center;
color: black;
background: white;
font-size: 0.6rem;
padding-left: 4%;
padding-right: 4%;
position: fixed;
top: 0;
// border-bottom: 1px solid black;
z-index: 99;
}
.logo-container {
width: 20%;
margin-right: 6%;
.white-logo {
width: 100%;
}
}
.header-section-one {
width: 32%;
display: flex;
margin-right: 25%;
justify-content: space-evenly;
.location-sub-div {
display: flex;
h3 {
width: 100%;
white-space: nowrap;
}
}
.order-sub-div {
display: flex;
h3 {
white-space: nowrap;
}
}
}
.header-section-two {
width: 32%;
display: flex;
justify-content: space-evenly;
.search-sub-div {
display: flex;
.search-icon {
margin-right: 1%;
}
}
.acct-sub-div {
display: flex;
.acct-icon {
margin-right: 1%;
}
}
}
i {
margin-right: 1% !important;
}
This neat CSS trick might help you with the problem:
html:not([data-scroll='0']) {
.header-container {
width: 100%;
height: 9vh;
display: flex;
align-items: center;
color: black;
background: white;
font-size: 0.6rem;
padding-left: 4%;
padding-right: 4%;
position: fixed;
top: 0;
border-bottom: 1px solid black;
z-index: 99;
}
}
Here is a, link further explaining the solution: https://css-tricks.com/styling-based-on-scroll-position/
Good luck.
You can add an event listener to the document, and when a scroll event is fired, you can check to see what the vertical scroll position (scrollTop) of the document is, and conditionally show a border based on that value.
Here's an example:
import React, { useEffect, useState } from "react";
const Header = () => {
// Store a bool that determines if the border is visible
const [isBorderVisible, setIsBorderVisible] = useState(false);
useEffect(() => {
// Define a function that is called when the scroll event fires
const handleScroll = e => {
const scrollTop = e.target.documentElement.scrollTop;
if (scrollTop > 200) {
setIsBorderVisible(true);
} else {
setIsBorderVisible(false);
}
};
// Add the event listener inside a useEffect
if (document) {
document.addEventListener("scroll", handleScroll);
}
// Remove the event listener on unmount
return () => {
if (document) {
document.removeEventListener("scroll", handleScroll);
}
};
}, [setIsBorderVisible]);
return (
<div
style={{
position: "fixed",
top: 0,
left: 0,
right: 0,
height: "100px",
background: "hotpink",
// Conditionally style the border
borderBottom: isBorderVisible ? "2px solid #000" : "0"
}}
/>
);
};
So we have a useEffect, that adds an event listener to the document, listening for the scroll event. Whenever a scroll occurs, the handleScroll function (also defined inside the useEffect) fires.
In this function, we get the scrollTop value, which is the number of pixels that have been scrolled from the top of the document.
In the example, we are setting the state value isBorderVisible to true once we have a scrollTop greater than 200 pixels, but this can be anything you want.
In the header's style, we conditionally set a border, based on the state value of isBorderVisible.

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