Search bar won't stay at top with CSS position: sticky property - css

I am trying to make a search bar stay at the top of a div with position: sticky but the property doesnt seem to work. Googling it, I see that overflow: hidden and overflow: hidden on a parent element can make it unresponsive if there is no height specified but I have a height specified so I don't think that's it. Here is the relevant CSS:
.container {
background-color: white;
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
border-radius: 1rem;
height: 85vh;
width: 60vw;
overflow-y: scroll;
overflow-x: hidden;
margin: auto;
}
.search-bar {
position: sticky;
top: 0;
margin: 1rem 1rem;
padding: 0.5rem;
font-size: 20px;
width: 100%;
display: block;
outline: 0;
border-width: 0 0 2px;
}
Note that .search-bar is a child element of .container. If needed, here is the JSX file (it's a react app):
import React, { useState, useEffect } from 'react';
import { average } from './utils/util.js';
import Card from './components/Card/Card';
import './App.css';
function App() {
const [loading, setLoading] = useState(true);
const [query, setQuery] = useState({ name: '', tag: '' });
const [users, setUsers] = useState([]);
const [filteredUsers, setFilteredUsers] = useState([]);
return (
<div className='container'>
<input
className='search-bar'
placeholder='Search by name'
onChange={(e) => {
setQuery({ ...query, name: e.target.value });
}}
/>
<input
className='search-bar'
placeholder='Search by tag'
onChange={(e) => {
setQuery({ ...query, tag: e.target.value });
}}
/>
{filteredUsers.map((user) => (
<Card
id={user.id}
pic={user.pic}
name={`${user.firstName} ${user.lastName}`}
email={user.email}
company={user.company}
skill={user.skill}
average={average(user.grades)}
grades={user.grades}
tags={user.tags}
onTagChange={tagChange}
/>
))}
</div>
);
}
export default App;

I tried to reproduce your issue here,
https://codesandbox.io/s/winter-breeze-5spod8?file=/src/styles.css
but it seems to work fine with your code. The only thing I changed was to add two .search-bar classes and height into it, because you have two input elements which you want sticky and they start to overlap on each other when we start scrolling.
.container {
background-color: white;
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
border-radius: 1rem;
height: 85vh;
width: 60vw;
overflow-y: scroll;
overflow-x: hidden;
margin: auto;
}
.search-bar1 {
position: sticky;
top: 0;
margin: 1rem 1rem;
padding: 0.5rem;
font-size: 20px;
width: 100%;
height: 3%;
display: block;
outline: 0;
border-width: 0 0 2px;
}
.search-bar2 {
position: sticky;
top: 5.8%;
margin: 1rem 1rem;
padding: 0.5rem;
font-size: 20px;
width: 100%;
height: 3%;
display: block;
outline: 0;
border-width: 0 0 2px;
}

Related

How to fill a div with dots automatically

I am building a react app and I want to know what is the best way to fill a div with dots, to be more specific how to fill a div entirely with small rounded divs, but no matter the width of the screen the div is always full with small rounded divs.
The end result should look like this :
I tried to use Array.fill().map() but when the width of my screen changes the dots became unorganized.
My code :
function About() {
const service = [
{
icon: <PhoneCallbackIcon style={{ fontSize: 32 }} />,
text: "Inbound Call Center Service",
subText: "Read more"
},
{
icon: <QuestionAnswerIcon style={{ fontSize: 32 }} />,
text: "Schriftbeschreibung",
subText: "Read more"
},
{
icon: <GTranslateIcon style={{ fontSize: 32 }} />,
text: "Übersetzung",
subText: "Read more"
}
]
const dots = 266
return (
<Container>
<OurJob>
<Title>Was machen wir?</Title>
<Line />
<p>Wir sind Experten in diesen Bereichen</p>
</OurJob>
<OurServices>
{service.map((item, index) => (
<Service key={index} >
{item.icon}
<div>
{item.text}
</div>
<p>
{item.subText}
</p>
</Service>
))}
</OurServices>
<Dots >
{Array(dots).fill().map((_, i) => (
<Dot />
))}
</Dots>
</Container>
)
}
My styled components :
const Container = styled.div`
display: flex;
width: 100%;
border-radius: 16px;
position: relative;
margin: 5% 0;
box-shadow: 9px 11px 17px -6px rgba(0,0,0,0.3);
-webkit-box-shadow: 9px 11px 17px -6px rgba(0,0,0,0.3);
-moz-box-shadow: 9px 11px 17px -6px rgba(0,0,0,0.3);
`
const Dots = styled.div`
position: absolute;
width: 33%;
display: flex;
flex-wrap: wrap;
left: -4%;
bottom: -25%;
`
const Dot = styled.div`
width: 4px;
content: "";
height: 4px;
margin: 5px 5.5px;
border-radius: 50%;
/* background: rgba(217, 217, 217, 0.5); */
background: black;
`
const OurJob = styled.div`
width: 25%;
padding: 40px;
background: rgba(122, 223, 210, 1);
overflow: hidden;
border-radius: 16px 0 0 16px;
p {
font-size: 20px;
font-weight: 400;
color: white;
}
`
const Line = styled.div`
height: 8px;
background: white;
width: 60%;
margin: 10px 0;
`
const Title = styled.div`
font-size: 50px;
font-weight: 600;
color: white;
`
const OurServices = styled.div`
display: flex;
width: 70%;
`
const Service = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 40px;
width: 25%;
text-align: center;
div {
font-size: 22px;
font-weight: 600;
height: 20%;
}
p {
color: rgba(92, 92, 92, 1);
font-size: 20px;
}
`
This can be done by setting a div with a background image and use a URL that's an encoded svg as follows:
.dots {
width: 100%;
height: 50vh;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='20' width='20'%3E%3Ccircle cx='10' cy='10' r='5' fill='%23e0e0e0' /%3E%3C/svg%3E ");
}
<div class='dots'>
</div>
You can also create it without svg image on the body or your container.
You can play with the background-size to add/remove space between the dots.
body {
background-image: radial-gradient(rgba(217, 217, 217, 0.5) 4px, transparent 0);
background-size: 30px 30px;
}

How to positioning tooltip always above the children

I am making tooltip with antd library. I wanted to change the basic styles, so I needed to override styles. Here is the code:
import * as Styled from './Tooltip.styles';
type Props = {
title: string;
children: React.ReactNode;
};
export const CustomTooltip = ({ title, children }: Props) => (
<Styled.Tooltip
visible
title={title}
getPopupContainer={(triggerNode) => triggerNode}>
{children}
</Styled.Tooltip>
);
import styled from 'styled-components';
import { Tooltip as TooltipAnt } from 'antd';
export const Tooltip = styled(TooltipAnt)`
.ant-tooltip-content {
position: relative;
overflow-x: hidden;
overflow-y: visible;
padding-bottom: 20px;
display: inline-block;
left: -35px;
top: 25px;
}
.ant-tooltip-arrow {
display: none;
}
.ant-tooltip-inner {
padding: 10px 15px;
background: white;
display: inline-block;
border-radius: 10px;
border: 3px solid #D04A02;
border-bottom-right-radius: 0;
z-index: 2;
max-width: 200px;
color: #000;
box-shadow: none;
}
.ant-tooltip-content:before {
content: '';
position: absolute;
width: 25px;
height: 25px;
background: white;
bottom: 14px;
right: -8px;
transform: rotate(25deg);
border-bottom: 3px solid #D04A02;
}
.ant-tooltip-content:after {
content: '';
width: 3px;
background: #D04A02;
height: 50%;
position: absolute;
right: -0.5px;
bottom: 12px;
}
`;
And component where I would like to call this Tooltip:
import { CustomTooltip } from 'components/Tooltip/Tooltip';
export const SomeComponent = () => {
return (
<div>
<CustomTooltip title="Home">
<p>Home</p>
</CustomTooltip>
</div>
);
};
The problem is, the tooltip is not above the children. How can I fix this?
Codesanbox: https://codesandbox.io/s/stupefied-cohen-sgxr3s?file=/src/App.tsx

How to make close effect after clicking on close in Styled-components?

I'm trying to make an in and out animation for my comment -
import {
Popup,
Overlay,
NavBarPopupHeader,
NavBarPopupContainer,
NavBarPopupImg,
NavBarPopupClose,
NavBarPopupContent,
NavBarPopupTitle,
NavBarPopupInfo,
NavBarPopupContentImg,
NavBarPopupFooter,
NavBarPopupSignOut,
} from "./styled.js";
function NavBarPopup(props) {
const { isPopupOpen } = props;
return (
<Overlay>
<Popup active={false}>
<NavBarPopupHeader>
<NavBarPopupClose
src="./popup_close.svg"
alt="close"
onClick={() => isPopupOpen(false)}
active={true}
/>
<NavBarPopupContainer>
<NavBarPopupImg />
</NavBarPopupContainer>
</NavBarPopupHeader>
<NavBarPopupContent>
<NavBarPopupTitle>You are logged as</NavBarPopupTitle>
<NavBarPopupInfo>'UserName'</NavBarPopupInfo>
<NavBarPopupInfo>'Email'</NavBarPopupInfo>
<NavBarPopupContentImg src="./popup_img.png" />
</NavBarPopupContent>
<NavBarPopupFooter>
<NavBarPopupSignOut>Sign Out...</NavBarPopupSignOut>
</NavBarPopupFooter>
</Popup>
</Overlay>
);
}
export default NavBarPopup;
I am using styled-components :
import styled, { keyframes, css } from "styled-components";
import { fadeIn, bounceInRight, bounceInLeft } from 'react-animations';
const fader = keyframes`${fadeIn}`;
const bounceIn = keyframes`${bounceInRight}`;
const bounceOut = keyframes`${bounceInLeft}`;
const Popup = styled.div`
position: fixed;
top: 0;
right: 0;
height: 100vh;
width: 400px;
background-color: #ffffff;
transition: ${(active) =>
active
? css`
${bounceIn} 0.5s linear
`
: css`${bounceOut} 0.5s`};
`;
const Overlay = styled.div`
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
animation: 0.2s ${fader};
`;
const NavBarPopupHeader = styled.div`
width: 100%;
height: 15%;
background-color: #000000;
`;
const NavBarPopupContainer = styled.p`
text-align: center;
margin: 0;
padding: 30px 0 0 0;
`;
const NavBarPopupImg = styled.img`
width: 80px;
height: 80px;
border-radius: 50px;
border: none;
background-color: white;
color: black;
font-size: 25px;
`;
const NavBarPopupClose = styled.img`
position: absolute;
top: 5px;
left: 5px;
cursor: pointer;
`;
const NavBarPopupContent = styled.div`
height: 75%;
`;
const NavBarPopupTitle = styled.h3`
margin:0;
padding: 10px 0 10px 0;
text-align: center;
font-size: 30px;
`
const NavBarPopupInfo = styled.h4`
width: 80%;
margin: 10px auto;
padding:5px;
text-align: center;
font-size: 25px;
background-color: black;
color:white;
border-radius: 15px;
`
const NavBarPopupContentImg = styled.img`
width:100%;
margin-top:90px;
`
const NavBarPopupFooter = styled.div`
width: 100%;
height: 10%;
background-color: #000000;
`;
const NavBarPopupSignOut = styled.p`
width:200px;
text-align: center;
margin: 0 auto;
padding: 15px 0 0 0;
font-weight: 700;
font-size: 32px;
color: white;
text-decoration: underline;
cursor: pointer;
`;
export {
Popup,
Overlay,
NavBarPopupHeader,
NavBarPopupContainer,
NavBarPopupImg,
NavBarPopupClose,
NavBarPopupContent,
NavBarPopupTitle,
NavBarPopupInfo,
NavBarPopupContentImg,
NavBarPopupFooter,
NavBarPopupSignOut
};
I want my popup to be animated with $bounceIn when it appears, and disappear with $bounceOut when it closes. I tried to do it by passing an attribute to styled-components but now it only works when my Popup appears. Perhaps I chose the wrong approach, in which case please guide me in the right direction.

Div with arrow up on top of div and box positioning

Hello I am trying to make a popup with dropdown login effect,
but I’m having trouble with how I could get my arrow up on the div
like this:
but i got this:
And I also have trouble positioning my invisible div correctly below my menu
I used position absolute, but is not responsive in mobiles devices etc.
I would like help with the best way to position my element in the right way
 and how I would position my arrow correctly
code:
export default function App() {
const [isHover, setisHover] = React.useState(false);
console.log(isHover);
return (
<>
<LoginColumn>
<WrapperLogin
onMouseOver={() => setisHover(true)}
onMouseOut={() => setisHover(false)}
>
<a>
<FontAwesomeIcon
className="adjust"
icon={faUserCircle}
size="2x"
fixedWidth
color="white"
/>
</a>
<div>
<a>
<h3>Olá !</h3>
<p>
Minha Conta
<span>
<FontAwesomeIcon
className="adjust"
icon={faAngleDown}
size="lg"
fixedWidth
color="white"
/>
</span>
</p>
</a>
</div>
</WrapperLogin>
<SignWrap hover={isHover}>a</SignWrap>
</LoginColumn>
</>
);
my css:
import styled from "#emotion/styled";
export const SignWrap = styled.div`
display: ${props => (props.hover ? "block" : "none")};
background: green;
position: absolute;
width: 100%;
height: 250px;
top: 100px;
:before {
content: "";
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
width: 0;
height: 0;
border-top: 15px solid #000;
transform: rotate();
border-left: 15px solid transparent;
border-right: 15px solid transparent;
}
`;
export const LoginColumn = styled.div`
position: relative;
width: 40%;
display: flex;
flex-direction: column;
background: red;
`;
export const WrapperLogin = styled.div`
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
:hover {
}
svg {
margin-right: 10px;
}
div {
display: flex;
flex-direction: column;
}
h3 {
color: white;
font-family: Roboto;
margin-bottom: 5px;
}
p {
color: white;
font-family: Roboto;
font-size: 0.8em;
}
`;
example:
https://codesandbox.io/s/ecstatic-matsumoto-mgy2q
The issue is basically 2 things. Your positioning, and which border you're using for the arrow effect. So if you change your position to top / right, and allow top to place the pseudo element outside of the box, and swap border-top for border-bottom to flip your arrow, voila. Oh and most of the rest of the properties you have in there are innocuous. Have a great weekend!
Change;
:before {
content: "";
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
width: 0;
height: 0;
border-top: 15px solid #000;
transform: rotate();
border-left: 15px solid transparent;
border-right: 15px solid transparent;
}
to;
:before {
content: "";
display: block;
position: absolute;
right: 1rem;
top: -15px;
border-bottom: 15px solid #000;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
}

Div passing full width of parent div

Hello I have a daughter div that is passing the full width of the parent div for some reason I still can't find the solution:
like this:
for some reason instead of skipping paragraph it is always horizontal I've tried everything and found no solution.
code:
<Styled.ChatBox>
<Styled.ChatLog>
<Styled.MessageWrapper user={true}>
<Styled.ChatMessage user={true}>{props.children}</Styled.ChatMessage>
</Styled.MessageWrapper>
</Styled.ChatLog>
</Styled.ChatBox>
css:
const messageBot = css`
align-self: flex-start;
background-color: #e0e0e0;
color: black;
border-radius: 8px;
padding: 10px 10px 10px 15px;
font-size: 15px;
font-family: sans-serif;
`;
const messageClient = css`
align-self: flex-end;
background-color: #1a6fe8;
color: white;
border-radius: 8px;
padding: 10px 10px 10px 15px;
font-size: 15px;
font-family: sans-serif;
`;
const ChatBox = styled.div`
display: ${props => (props.widget ? 'none' : 'flex')};
position: absolute;
position: fixed;
right: 20px;
bottom: 20px;
flex-direction: column;
max-width: 22em;
width: 100%;
height: 30em;
border-radius: 6px;
box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 10px 2px;
background: ${props => (props.widget ? 'red' : 'blue')};
`;
const ChatLog = styled.div`
display: flex;
flex-direction: column;
max-height: 400px;
width: 100%;
overflow-y: auto;
flex: 1 100%;
background: red;
padding: 10px 10px 0px 10px;
box-sizing: border-box;
`;
const MessageWrapper = styled.div`
background: yellow;
display: flex;
align-items: center;
flex-direction: row;
box-sizing: border-box;
width: 100%;
justify-content: ${props => (props.user ? 'flex-end' : 'flex-start')};
`;
const ChatMessage = styled.div`
position: relative;
margin: 1ex;
padding: 1ex;
border-radius: 2px;
:before {
content: '';
position: absolute;
top: 50%;
right: ${props => (props.user ? '-5px' : '')};
left: ${props => (props.user ? '' : '1px')};
height: 15px;
width: 15px;
background: ${props => (props.user ? '#1a6fe8' : '#e0e0e0')};
transform: rotate(45deg);
transform-origin: top right;
}
${props => (props.user ? messageClient : messageBot)}
`;
I know that my div that is passing the size is ChatMessage
I believe she is the problem
img:
example on:
https://codesandbox.io/s/cool-water-1dwqx
You need to handle the overflow of the element.
const ChatMessage = styled.div`
...
overflow: hidden;
word-break: break-all;
`;

Resources