I have a popup where I show notifications. The user can delete notifications at any time. The day the notification arrives and the delete button will appear one after the other. No matter what I did, I couldn't.
How can I show these two divs under each other, as can be seen in the marked area in the picture?
<div className="notificationlist__container only-desktop">
{props.notification.notificationList.map((e) => {
return (
<div className="notificationlist__item">
<div className="notificationlist__info">
<div className="notificationlist__content">
Lorem, ipsum.
</div>
<div className="notificationlist__detail">
<Link to="/profil">
<div>Profile</div>
<AS.KeyboardArrowRightIcon />
</Link>
</div>
</div>
<div className="notificationlist__time">Today
<div className="delete__button">
<AS.IconButton >
<AS.DeleteIcon />
</AS.IconButton>
</div>
</div>
</div>
);
})}
</div>
.notificationlist__container.only-desktop {
font-size: 1.2rem;
// padding-right: 2em;
max-height: 400px;
overflow: auto;
.notificationlist__item {
padding: 0.5em 0;
border-bottom: 1px solid #d1d1d1;
&:last-of-type {
border-bottom: none;
}
display: flex;
justify-content: space-between;
align-items: flex-start;
.notificationlist__info {
margin-right: 1em;
max-width: 400px;
.notificationlist__content {
color: gray;
}
.notificationlist__detail {
margin-top: 1em;
color: var(--palette-blue-300);
display: flex;
align-items: center;
font-size: 1.1rem;
font-weight: 600;
svg {
font-size: 1.5rem !important;
}
a {
display: contents;
}
}
}
.notificationlist__time{
display: flex;
.delete__button {
float: left;
}
}
}
}
display: flex is putting divs next to each other. You can delete display: flex or just add flex-direction: column; to put them under each other. To center them horizontally add align-items: center;
You should move delete button out of notificationlist_time content, then it would be easy to manipulate it
<div className="notificationlist__right">
<div className="notificationlist__time">today</div>
<div className="delete__button">
<AS.IconButton >
<AS.DeleteIcon />
</AS.IconButton>
</div>
</div>
So since it would be two different blocks, you would have an ability to position them like you want.
Related
I have tried looking around for this but can't seem to find a question to match my current problem. I am trying to build a mock ecommerce website to practice using React. I have a header component. I want this component to be 100% of the screen width, so that the elements inside this component shrink whenever the page shrinks. I have some global css that sets the height and width of the html and body to 100%:
html, body{
background-color: rgb(167, 72, 72);
height: 100%;
min-width: 100%;
}
I am currently facing two problems, neither of which I understand very well the causes of. When I set my header component (the outermost component) to have a width of 100%, the page shrinks correctly. But when I open up developer tools to check the responsiveness, something goes wrong so that the right side of my header is shrinking faster than the page header_shrink
I am able to fix this by setting the width of my header to "fit-content" instead of "100%". Here is what the header looks like when I shrink the page using developer tools.header_fixed But when I do it this way, the components inside of my header don't shrink correctly. For example, my search bar is supposed to decrease in width as I shrink the page, but when I use "fit-content", it just stays set to whatever size it is. search-bar-constant. When I have the width set to 100% instead of fit content, it looks the way it's supposed to search-bar-fixed.
Sorry for the long explanation, but this is the bulk of my problem. "Width: 100%" allows the items in my header component to shrink correctly, but not the component itself. And "width: fit-content" allows the outer header component to shrink correctly, but not the items inside of it.
Here is the JSX I have for reference:
import React from 'react'
import './Header.css'
import { BiSearchAlt2 as SearchIcon} from "react-icons/bi";
import {RiArrowDropDownLine as DropDownIcon} from "react-icons/ri";
import { CgProfile as Profile } from "react-icons/cg";
import { CgShoppingCart as Cart } from "react-icons/cg";
const Header = () => {
const texts = [
'ORDERS OF $5K SHIP FREE',
'FREE SHIPPING ON SELECT ITEMS: SHOP NOW',
'BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE'
];
let currentTextIndex = 0;
setInterval(() => {
const shippingDealsText = document.querySelector('.shipping-deals-text');
shippingDealsText.classList.add('out');
setTimeout(() => {
shippingDealsText.textContent = texts[currentTextIndex];
shippingDealsText.classList.remove('out');
currentTextIndex = (currentTextIndex + 1) % texts.length;
}, 1000);
}, 5000);
return (
<div className="header">
<div className="header-top">
<div className="top-logo">
<h5 className='small-logo'>LEVIATHAN</h5>
</div>
<div className="space"></div>
<div className="link-container">
<div className="link-wrap">
Gift Cards
</div>
<div className="link-wrap">
Contact Us
</div>
<div className="link-wrap">
Order Status
</div>
<div className="link-wrap">
Live Chat
</div>
</div>
</div>
<div className="header-middle">
<div className="middle-logo">
<h5 className='big-logo'>LEVIATHAN</h5>
</div>
<div className="search-container">
<div className="search-wrapper">
<input
type="text"
id="search-bar"
placeholder="Search"
className='search'
/>
<div className="search-icon-wrapper">
<SearchIcon className='search-icon'/>
</div>
</div>
</div>
<div className="shipping-deals-container">
<div className="button-container">
<div className="shipping-deals-button">
<span className="deals-text">DAILY SHIPPING DEALS </span>
</div>
</div>
<div className="text-container">
<div className="text-slideshow">
<p className="shipping-deals-text">BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE</p>
</div>
</div>
</div>
<div className="icons-right">
<Profile className='login-pic'/>
<span>Log In</span>
<Cart className='shopping-cart'/>
</div>
</div>
<div className="header-bottom">
<div className="nav-bar">
<ul className='navigation'>
<li className='menu-items'>
<a href="/" className='button drop-down red'>Shop <DropDownIcon className='drop-icon'/></a>
<a href="/" className='button'>Equipment for Crossfit</a>
<a href="/" className='button'>New Gear</a>
<a href="/" className='button'>Barbells</a>
<a href="/" className='button'>Plates</a>
<a href="/" className='button'>Rigs and Racks</a>
<a href="/" className='button'>Shoes</a>
<a href="/" className='button'>Apparel</a>
<a href="/" className='button'>3 Ships Free</a>
<a href="/" className='button'>Zeus</a>
<a href="/" className='button drop-down'>The Index</a>
</li>
</ul>
</div>
</div>
</div>
)
}
export default Header
Here is the styling I am currently applying:
.header {
min-width: 100%;
margin: 0;
padding: 0;
}
.header-top {
background-color: white;
display: flex;
height: 2.5rem;
width: 100%;
}
.top-logo {
position: relative;
margin-left: 3rem;
}
.space {
flex-grow: 1;
}
.small-logo {
padding-top: 0.5em;
position: relative;
font-size: larger;
color: rgb(133, 133, 133)
}
.link-container {
display: flex;
/*border: 1px solid red;*/
margin-right: 3rem;
}
.link-wrap {
/*border: 1px solid green;*/
font-size: 14px;
padding-left: 1rem;
padding-top: 0.75rem;
}
.link-wrap a {
text-decoration: none;
color:#666666;
cursor: pointer;
}
/* Large section of header, black background */
.header-middle {
background-color: black;
height: 7rem;
display: flex;
}
/* Big LEVIATHAN text */
.middle-logo {
/*border: 1px solid red;*/
position: relative;
margin-left: 3rem;
display: flex;
justify-content: center;
align-items: center;
cursor: co;
}
.big-logo {
font-size: 48px;
/*padding-top: 2rem;*/
position: relative;
color: white;
}
.big-logo:hover {
color: rgb(210, 0, 0);
}
.search-container {
position: relative;
width: 40%;
display: flex;
flex-basis: 60%;
margin-left: 3rem;
align-items: center;
justify-content: center;
}
/*This is what has the appearance of the search bar*/
.search-wrapper {
min-width:100%;
height: 35%;
position: relative;
background-color: white;
display: flex;
flex-basis: 50%;
}
.search-icon-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
}
.search-icon {
color: black;
font-size: 20px;
}
/*This is the actual search bar tucked inside*/
.search {
width: 100%;
height: 100%;
border: none;
outline: none;
margin-left: 1em;
font-size: 17px;
}
.search::placeholder {
color:rgb(94, 94, 94);
}
/* This holds onto both our daily shipping deals button */
/* and our text slideshow */
.shipping-deals-container{
width: 18em;
margin-left: 2.5em;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
/*border: 2px solid rgb(136, 77, 255);*/
}
.shipping-deals-button {
width: 65%;
height: 44%;
background-color: rgb(234, 2, 2);
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-top: 1.5em;
}
.button-container {
width: 100%;
height: 50%;
/*border: 2px solid magenta;*/
}
.deals-text {
color: white;
font-size: 12px;
position: relative;
text-align: center;
align-items: stretch;
width: 100%;
}
.text-container {
/*border: 2px solid rgb(20, 182, 11);*/
width: 100%;
height: 50%;
}
.text-slideshow {
color: white;
width: 100%;
height: 50%;
font-size: 12px;
}
.shipping-deals-text {
transition: opacity 1s;
opacity: 1;
font-size: 13px;
}
.out {
opacity: 0;
transition: opacity 1s;
}
.shipping-deals-text-red{
color: red;
}
.navigation {
display: flex;
align-items:flex-start;
height: 3rem;
}
.menu-items {
height: 100%;
margin-left: 1.5rem;
padding-right: 1.5rem;
display: flex;
align-items: flex-start;
flex: 1;
}
ul {
list-style-type: none;
background-color: #333333;
}
.button {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
text-decoration: none;
color: white;
text-transform: uppercase;
white-space: nowrap;
padding: 1em;
font-weight: bold;
}
.button:hover {
color:rgb(210, 0, 0)
}
.red {
background-color: rgb(210, 0, 0);
}
.red:hover {
color: white;
}
.drop-icon {
font-size: 25px;
}
.icons-right {
height: 50%;
margin-top: 2em;
min-width: 10%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 1rem;
}
.login-pic {
color: white;
font-size: 20px;
}
.shopping-cart {
color: white;
font-size: 20px;
margin-left: 1rem;
}
.icons-right span {
color: white;
margin-left: 0.5em;
}
#media (max-width: 1025px) {
.shipping-deals-container {
display: none;
}
.header-top {
display: none;
}
.header-middle {
height: 50%;
}
.search-wrapper {
border: 2px solid white;
height: 2rem;
}
.icons-right {
margin-bottom: 2rem;
}
}
I have tried altering the width of my body, and html, but nothing seems to be giving me the solution I am looking for
With width: 100% on .header it shrinks the header the way you want it. That seems to be correct actually.
The element that prevents shrinking is <li class="menu-items"></li> because of display: flex;. Flexbox is by default not wrapping (flex-wrap: nowrap;).
Add flex-wrap. wrap; and you'll see everything will shrink with fit-content or width: 100%;
Hope this helps.
On another note: You shouldn't use <li> (List-Element) as the list. Thats what <ul> (Unsorted list) is for.
It should look more like this ->
<ul>
<li>
Shop
</li>
<li>
Equipment for Crossfit
</li>
<li>
New Gear
</li>
<!-- ... -->
</ul>
In Angular application I am making Filters and Header row element sticky. I am using HostListener and windowscroll to achieve this functionality. The problem I am facing is Header and filter content is overlapped with the results when user scroll down.
I need help to fix this overlap.
Link to demo - https://screenrec.com/share/XKtIZji2lY
FILTERS Code
html
<div class="filters-data" [ngClass]="{'mat-elevation-z5' : true, 'sticky' : isSticky}">
<div class="im-results">
<div>
<strong>{{ Amazon Data }} </strong> match
</div>
</div>
<div class="filters-data-result">
<app-filters-data-result *ngFor="let item of filters; let i = index" [item]="item" (onRemoved)="remove(item)">
</app-filters-data-result>
</div>
</div>
.css
.mat-elevation-z5 {
position: relative;
}
.sticky {
position: fixed;
top: 100px;
}
div.filters-data {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-around;
align-items: center;
align-content: flex-start;
padding: 20px 0;
.im-results {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: center;
align-items: center;
align-content: center;
font-size: 18px;
}
.filters-data-result {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
align-content: center;
margin-right: 8px;
}
}
.ts
isSticky: boolean = false;
#HostListener('window:scroll', ['$event'])
checkScroll() {
this.isSticky = window.pageYOffset >= 10;
}
HEADER CODE
html
<div class="header-top bottom-border mb-10" [ngClass]="{'mat-elevation-z5' : true, 'sticky' : isSticky }">
<div class="am-ctnr rows-header">
<div class="im-header-product">
<div> Products</div>
</div>
<div class="im-number">
<div> Number</div>
</div>
<div class="shippment-number">
<div>Shippment Number</div>
</div>
<div class="origin">
<div>
Origin
</div>
</div>
<div class="size">
<div>
Size
</div>
</div>
</div>
</div>
.css
.header-top{
.im-error-notification-div{
overflow:hidden;
.im-error-notification-inner{
float:right;
}
}
&.bottom-border {
border-bottom: 1px solid am-colors.$ash-grey;
}
.mb-10 {
margin-bottom: 10px;
}
.am-ctnr {
display: flex;
padding: 5px 16px 10px;
align-items: baseline;
flex-wrap: wrap;
#media #{am-responsive-breakpoints.$screen-xs-sm-md}{
display: none;
}
&.rows-header {
font-family: am-fonts.$am-font-family-bold;
font-size: 11px;
font-weight: bold;
justify-content: space-between;
.im-header-product{
padding: 5px;
width: 30%;
}
.im-header-catalog{
padding: 5px;
width: 10%;
}
.im-header-lot-number{
padding: 5px;
width: 10%;
}
.im-header-origin{
padding: 5px;
width: 10%;
}
.im-header-unit-size{
padding: 5px;
width: 5%;
min-width: 60px;
}
.im-header-item-price{
padding: 5px;
width: 10%;
}
}
}
}
I'm a newbie of front-end development. I'm currently working on a project trying to make my header style change while scrolling using intersectionObserver. I'm also using fullpage.js to create a full page transition effect. However, I encounter the problem that when I scroll, browser considers section 1 and section2 are the same section, which the header style will only change when I scroll to the section3.
Would anyone tell me what happened? Maybe I missed something.
The code I used is here:
<div class="header">
<a href="#">
<h1>logo<h1>
</a>
<nav>
<ul class="nav-link">
<li>projects</li>
<li>about</li>
</ul>
</nav>
</div>
<div id="fullpage">
<div class="section s1">
</div>
<div class="section s2">
</div>
<div class="section s3">
</div>
<div class="section s4">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/3.0.9/fullpage.min.js"></script>```
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #070520;
}
.header {
--text: #fff;
--background: transparent;
position: fixed;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
width: 100%;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
z-index: 999;
padding: 1rem 6.5rem 0 1.5rem;
background-color: var(--background);
}
.header a {
font-size: 0.8rem;
text-decoration: none;
color: var(--text);
font-family: "Helvetica", sans-serif;
font-weight: 100;
letter-spacing: 0;
}
.header .nav-link {
list-style: none;
}
.header .nav-link li {
display: inline-block;
bottom: 0;
padding: 0px 10px;
}
.header-scrolled {
--text: #070520;
}
.s2 {
background-color: grey;
}
.s3 {
background-color: green;
}
.s4 {
background-color: blue;
}
new fullpage("#fullpage", {
scrollingSpeed: 1000,
});
const header = document.querySelector('.header');
const sectionOne = document.querySelector('.s1');
const sectionOneOptions = {};
const sectionOneObserver = new IntersectionObserver(function(entries,sectionOneObserver){
entries.forEach(entry=>{
if(!entry.isIntersecting){
header.classList.add('header-scrolled')
}else{
header.classList.remove('header-scrolled')
}
})
},sectionOneOptions);
sectionOneObserver.observe(sectionOne);
https://codepen.io/Austin020304/pen/WNwjqaO
Thank you!
Consider using fullPage.js state classes or callbacks for that.
Also, do not forget to check the callbacks examples:
https://github.com/alvarotrigo/fullPage.js/tree/master/examples
You might also want to check this video tutorial I did making use of the state classes to create animations.
here is what my services page currently looks like:
So when you choose one of the blue radio buttons, it loads the green radio buttons which are sub options, clicking on a green sub option will show the information for that specific product/service.
As you can see when you select a categeory and then a service, it all works correct but I need to add an "active-radio-button" class to the ones that are currently selected.
Similar to a nav bar showing which page is currently active.
I've tried giving each radio button a $ref and then I loop through all the refs to see if they are checked, however it doesnt work, I can't even figure out how to print each ref to the console (although I can see them in the Vue developer console).
Here is the service page:
<template>
<div class="services">
<div class="header services__header">
<h1 :class="$mq">Services</h1>
</div>
<div class="services__services-container">
<div class="select-wrapper">
<div
class="services__services-container__category-selection"
:key="`category-${index}`"
v-for="(item, index) in this.JSON"
>
<!-- GENERATE CATEGORIES -->
<input
v-model="currentCategory"
#change="UncheckRadio"
type="radio"
class="services__services-container__category-selection__category"
:class="$mq"
:value="item"
:ref="item.name"
/>
<label :for="item">{{ item.name }}</label>
</div>
</div>
<!-- GENERATE SERVICES -->
<div class="services__services-container__service-selection" v-if="currentCategory != null">
<div class="select-wrapper">
<div
class="services__services-container__service-selection__service"
:key="`option-${index}`"
:class="$mq"
v-for="(option, index) in currentCategory.options"
>
<input
type="radio"
class="services__services-container__service-selection__service__wrapper"
:class="$mq"
:value="option"
v-model="currentService"
:ref="option.optionName"
/>
<label :for="option">{{ option.optionName }}</label>
</div>
</div>
</div>
<!-- GENERATE DESCRIPTIONS -->
<div class="services__services-container__product-description" v-if="currentService != ''">
<div class="services__services-container__product-description__description" :class="$mq">
<div :class="$mq">
<img :src="currentService.images" alt />
<p>{{ currentService.description }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import services from "#/JSON/services.json";
export default {
name: "Services",
data: function() {
return {
JSON: [],
currentCategory: "",
currentService: ""
};
},
created: function() {
//TO TEST
this.JSON = services.services;
},
methods: {
UncheckRadio: function() {
this.currentService = "";
console.log("kek");
for (const ref in this.refs) {
console.log(ref.key);
}
}
}
};
</script>
<style lang="scss">
#import "#/scss/variables.scss";
#import "#/scss/button.scss";
#import "#/scss/header.scss";
#import "#/scss/input.scss";
.services {
width: 100%;
height: auto;
display: grid;
grid-template-rows: 15vh auto auto auto;
&__services-container {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
padding: 2rem;
&__category-selection {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
position: relative;
padding: 1rem;
cursor: pointer;
& input {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 100;
opacity: 0;
}
& label {
cursor: pointer;
color: $colour-blue;
}
}
&__service-selection {
&__service {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: wrap;
//
position: relative;
padding: 1rem;
cursor: pointer;
& input {
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
z-index: 100;
opacity: 0;
}
& label {
cursor: pointer;
color: $colour-green;
}
}
}
/* For IE10 */
select::-ms-expand {
display: none;
}
&__product-description {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
#include green-gradient;
padding: 2rem;
border-radius: 1.5rem;
&__description {
& img {
margin-bottom: 1rem;
height: 10rem;
width: 10rem;
object-fit: cover;
}
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
}
}
}
}
.select-wrapper {
//FLEX
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
//
border-radius: 1.5rem;
position: relative;
width: auto;
height: auto;
margin-bottom: 1rem;
}
.select-icon {
font-size: 1rem;
color: $white;
position: absolute;
right: 0.5rem;
pointer-events: none;
}
.transition {
transition: all 0.25s linear;
}
.active-radio-button {
border-bottom: 0.1rem solid black;
}
</style>
I have a flex container in which I have two boxes which are side by side (and collapse in one column when the screen is too small).
Now, when boxes are side by side, I've set that they have the same height, like in the following image.
Now, what I want to achieve is to put the EDIT button of both boxes at the bottom (this means that only the EDIT button of the box with less content will need to move).
I've searched, but the solution are to use position absolute, because one of the two boxes won't need it, and if I put position absolute on both EDIT button, the box on the right will have less height because it won't count the EDIT button anymore.
I tried to play with flex, but I rather not set the boxes as display flex.
There may be some solution with Jquery, I've read something about it, but it was just something like "You could achieve that with Jquery!" but.. I honestly don't know how.
#parent {
flex-flow: row wrap;
display: flex;
align-items: stretch;
}
.box {
margin: 10px;
padding: 15px;
flex: 0 1 calc(50% - 50px);
}
.box:last-of-type {
background-color: green;
}
.box:first-of-type {
background-color: red;
}
.cool-form {
display: flex;
flex-direction: column;
}
.button-container {
display: block;
margin-left: 5px;
margin-top: auto;
align-self: center;
}
.button {
background-color: white;
display: inline-block;
width: 120px;
height: 48px;
line-height: 48px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
<div id="parent">
<div class="box">
<form class="cool-form">
<h1>Box on left</h1>
<p>This is a shorter box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</form>
</div>
<div class="box">
<form class="cool-form">
<h1>Box on right</h1>
<p>This is</p>
<p>a</p>
<p>bigger</p>
<p>waaay bigger</p>
<p>Box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</form>
</div>
</div>
Adding flexbox to these divs (using flex-direction:column) seems minimally invasive (which was, perhaps a concern).
.box {
display: flex;
flex-direction: column;
}
Then you can give the button container margin-top:auto and it's auomatically pushed to the bottom.
Then it's just a matter of aligning it horizontally/centrally
.button-container {
margin-top: auto;
align-self: center;
}
#parent {
flex-flow: row wrap;
display: flex;
align-items: stretch;
}
.box {
margin: 10px;
padding: 15px;
flex: 0 1 calc(50% - 50px);
display: flex;
flex-direction: column;
}
.box:last-of-type {
background-color: green;
}
.box:first-of-type {
background-color: red;
}
.button-container {
display: block;
margin-left: 5px;
margin-top: auto;
align-self: center;
}
.button {
background-color: white;
display: inline-block;
width: 120px;
height: 48px;
line-height: 48px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
<div id="parent">
<div class="box">
<h1>Box on left</h1>
<p>This is a shorter box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</div>
<div class="box">
<h1>Box on right</h1>
<p>This is</p>
<p>a</p>
<p>bigger</p>
<p>waaay bigger</p>
<p>Box</p>
<span class="button-container">
<span class="button">EDIT</span>
</span>
</div>
</div>