I'm trying to create a react css grid where the "side panel" always shows.
I'm new to react and a little confused with how to stack things.
Code:
return (
\<div\>
\<Aside /\>
\<Header /\>
\<Hero /\>
\<Middle /\>
\<End /\>
\<Footer /\>
\</div\>
);
}
CSS:
body {
margin: 0;
position: relative;
background-color: beige;
display: grid;
grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr 1fr;
justify-content: center;
align-content: center;
grid-template-areas:
"aside header header header"
"aside hero hero hero"
"aside middle-display middle-display middle-display"
"aside end-display end-display end-display"
"aside footer footer footer";
gap: 0px;
height: 100%;
width: 100%; }
I tried wrapping it into a section, different divs and more still not getting ideal result.
Here is my result:
This is what i'm going for
Thanks for the help!
This code achieves the structure that you want:
body {
margin: 0;
background-color: beige;
display: grid;
grid-template-areas:
"aside header header header header"
"aside hero hero hero hero"
"aside middle middle middle middle"
"aside end end end end"
"aside footer footer footer footer";
height: 100vh;
width: 100vw;
}
aside {
background: grey;
grid-area: aside;
}
header {
background: blue;
grid-area: header;
}
.section-one {
background: red;
grid-area: middle;
}
.section-two {
background: orange;
grid-area: end;
}
footer {
background: royalblue;
grid-area: footer;
}
<aside>Aside</aside>
<header>Header</header>
<section class="section-one">Section1</section>
<section class="section-two">Section2</section>
<footer>Footer</footer>
Related
I realize this is a lot of code to look through, and i'm sure you can ignore 90% of it. Been pulling my hair out about this issue. None of my other code has this problem except for the footer and the grid. (I wrapped the grid with .staff-box) Had to take out a chunk of css to make it less of a headache to read.
Thanks!
.main-flex-box {
position: relative;
margin-left: auto;
margin-right: auto;
width: 80%;
text-align: center;
background-color: white;
border-radius: 20px;
margin-top: -40px;
line-height: 30px;
}
.main-text-flex {
position: relative;
display: flex;
flex-direction: column;
max-width: 750px;
justify-content: center;
margin-left: auto;
margin-right: auto;
}
.staff-box {
margin-top: 40px;
flex-direction: column;
border-radius: 20px;
position: relative;
display: flex;
min-height: 90vh;
width: 100%;
background-color: #f2f2f2;
margin-left: auto;
margin-right: auto;
}
.grid-container {
display: grid;
position: relative;
position: relative;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
min-height: 400px;
text-align: center;
margin-top:50px;
grid-column-gap: -40px;
grid-row-gap: 100px;
}
.grid-item {
height: 2px;
background-color: black;
display: block;
width: 80%;
font-weight: normal;
position: relative;
font-size: 1rem;
font-size: 2vh;
margin-left: auto;
margin-right: auto;
}
#media all and (max-width: 1025px) {
.main-flex-box {
width: 100%;
height: auto;
}
.home-text {
font-size: 1.1rem;
}
.socials {
display: none;
}
img {
max-width: 325px;
}
}
#media all and (max-width: 994px) {
.grid-container {
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
width: 100%;
grid-row-gap: 175px;
}
.staff-box {
height: 90vh;
width: 100%;
}
}
#media all and (max-width: 580px) {
.grid-container {
grid-template-columns: 1fr;
}
}
#media all and (max-width: 414px) {
.grid-container {
margin-top: -50px;
}
.grid-item {
margin-top: 90px;
}
}
#media all and (max-width: 645px) {
.staff-flex-box{
margin-top: 150px;
}
}
<div class="main-text-flex">
<h1>Massachusetts</h1>
<p class="toggle-item">
A New Way Photo Gallery
</p>
<img src="img/stock2.png" class="image-1">
<div class="image-flex-container">
</div>
<div class="staff-box">
<h1>Meet The Staff</h1>
<h3>Here are our four most experienced members</h3>
<div class="grid-container">
<div class="grid-item">
<h3>Marcus Johnson</h3>
<p class="grid-item-text">With years of experience under his belt, he is a great addition to our team. He is the assistant manager of relations.</p>
</div>
<div class="grid-item">
<h3>Bill LaPointe</h3>
<p class="grid-item-text">With years of experience under his belt, he is a great addition to our team. He is the assistant manager of relations.</p>
</div>
<div class="grid-item">
<h3>Bill Formal</h3>
<p class="grid-item-text">With years of experience under his belt, he is a great addition to our team. He is the assistant manager of relations.</p>
</div>
<div class="grid-item">
<h3>Scott Wesley</h3>
<p class="grid-item-text">With years of experience under his belt, he is a great addition to our team. He is the assistant manager of relations.</p>
</div>
<div class="grid-item">
<h3>Scott Wesley</h3>
<p class="grid-item-text">With years of experience under his belt, he is a great addition to our team. He is the assistant manager of relations.</p>
</div>
<div class="grid-item">
<h3>Scott Wesley</h3>
<p class="grid-item-text">With years of experience under his belt, he is a great addition to our team. He is the assistant manager of relations.</p>
</div>
</div>
</div>
<footer class="div">
<p>footer test</p>
</footer>
Not quite sure what you want to accomplish, but when I encounter this sort of issue, I create a minimal example that still has the problem. That means remove everything except the elements that still show the issue. That's what I did here:
.staff-box {
margin-top: 40px;
border-radius: 20px;
position: relative;
min-height: 90vh;
width: 100%;
background-color: red
}
#media all and (max-width: 994px) {
.staff-box {
height: 90vh;
width: 100%;
}
}
<div class="staff-box">
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>a<br>
</div>
<footer class="div">
<p>footer test</p>
</footer>
From here, it's easy to change the css to get the (I think) expected result.
The problem, if I understood it correctly, is with "height: 90vh;" in the media query. It makes the div 90% of the viewport, and since the content is larger than that, it overflows the div. Remove that rule from the media query and the footer will appear under the staff-box div
Never ran into this problem before. Basically I added a class list toggle on my header via Javascript, and it normally works fine, but when I add media queries that have nothing to do with the header, it stops working. If you need any more info let me know. Any ideas? I'm lost
EDIT: Added additional HTML Code
Here's all my code
window.addEventListener('scroll', () => {
let header = document.querySelector('.page-header');
header.classList.toggle('sticky', window.scrollY > 30);
})
.page-header {
width: 100%;
height: 60px;
background-color: var(--main-bg-color);
display: flex;
flex-direction: row;
align-items: center;
color: white;
font-weight: bold;
overflow: hidden;
position: fixed;
transition: .7s;
z-index: 1;
}
.page-header.sticky {
background-color: white;
color: black;
position: fixed;
z-index: 1;
transition: .7s;
box-shadow: 5px 5px 3px lightgray;
}
.portfolio-images {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 20px;
margin-top: 50px;
}
.portfolio-images img {
margin-right: auto;
margin-left: auto;
}
.portfolio-images img:hover {
filter: brightness(.4);
transition: .4s;
cursor: pointer;
}
/* media queries */
#media all and (max-width: 1275px) {
.portfolio-images {
grid-template-columns: 1fr 1fr;
}
.portfolio-images img {
width: 40vw;
height: auto;
}
#media all and (max-width: 500px) {
.portfolio-images {
grid-template-columns: 1fr;
}
.portfolio-images img {
width: 90vw;
height: auto;
}
}
<div class="page-header">
<h1 id="logo">ParallaxStudios</h1>
<div class="navigation-container">
<ul>
<li><a class="navigation-item">Portfolio</a></li>
<li><a class="navigation-item">Socials</a></li>
<li><a class="navigation-item">Staff</a></li>
</ul>
</div>
<div class="rightside-navigation">
<h3 id="contact">Contact</h3>
</div>
</div>
<div class="portfolio-container">
<h1>Current Projects</h1>
<div class="portfolio-images">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
<img src="https://via.placeholder.com/420">
</div>
</div>
You literally have one missing } in the end the of one of the Media Queries here:
#media all and (max-width: 1275px) {
.portfolio-images {
grid-template-columns: 1fr 1fr;
}
.portfolio-images img {
width: 40vw;
height: auto;
}
} //this one was missing.
#media all and (max-width: 500px) {
.portfolio-images {
grid-template-columns: 1fr;
}
.portfolio-images img {
width: 90vw;
height: auto;
}
}
I am having some issues with CSS Grid "blow out" which is causing my text property text-overflow: ellipsis to not work.
I have seen many posts on this, and tried many things, but just don't understand what I have wrong. I can reproduce in a simple example.
In my case, I am using a third part component, where I want to put my UI inside one of it's elements.
For example, below the element third-party-container is the third part component, and my UI is contained in my-containerm where I wish to completely fill the third-party-container
HTML
<div id='third-party-container'>
<div id='my-container'>
<div id='s1'>S1</div>
<div id='s2'>S2</div>
<div id='s3'>aaaaaaaabbbbbbbbbbbccccccccccccccccccccccccccddddddddddddddd</div>
</div>
</div>
CSS
#third-party-container {
height: 40px;
width: 140px;
background: orange;
}
#my-container {
background: yellow;
height: 100%;
width: 100%;
display:grid;
align-items: center;
justify-items: left;
grid-template-columns: min-content 13px minmax(0, 1fr);
grid-template-rows: 1fr;
column-gap: 2px;
white-space: nowrap;
}
#s1 {
background: red;
grid-row: 1;
justify-items: left;
grid-column: 1;
align-items: stretch;
}
#s2{
background: green;
grid-row: 1;
overflow: hidden;
grid-column: 2;
}
#s3 {
background: pink;
grid-row: 1;
justify-items: left;
display: grid;
align-items: center;
grid-column: 3;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Also available at this Plunkr
So in my-container I have a single row, and 3 columns. The first two columns have quite small widths. The first columns may vary slightly, but will always be quite small. The 2nd is just fixed.
The third column s3 (coloured pink) is the one that may sometimes have longer text than can fit in the containers. However, this is what I see in the above example...
When I look at this in dev tools, I can see the s3 is "blowing out", ie not being contained within its container.
I had got around this before by using the minmax(0, 1fr) but it is not working here.
The outer container has a fixed width, and my-container is 100% of this.
What am I doing wrong and how I can get this to work?
The issue is the use of display:grid on #s3. Remove it and also add width:100%
#third-party-container {
height: 40px;
width: 140px;
background: orange;
}
#my-container {
background: yellow;
height: 100%;
display: grid;
align-items: center;
justify-items: left;
grid-template-columns: min-content 13px minmax(0, 1fr);
grid-template-rows: 1fr;
column-gap: 2px;
white-space: nowrap;
}
#s1 {
background: red;
}
#s2 {
background: green;
overflow: hidden;
}
#s3 {
background: pink;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
width:100%;
}
<div id='third-party-container'>
<div id='my-container'>
<div id='s1'>S1</div>
<div id='s2'>S2</div>
<div id='s3'>aaaaaaaabbbbbbbbbbbccccccccccccccccccccccccccddddddddddddddd</div>
</div>
</div>
Note: I'm looking for vanilla JS preferably, since jQuery isn't something I can use in this project
I have a somewhat complex grid structure:
body {
margin: 0;
height: 100vh;
text-align: center;
}
.grid-container {
height: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas: "tl tr" "bl br";
}
.tl {
background: #fdfdfd;
color: #2f2f2f;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: ". . . ." ". . text-tl ." ". . . button-tl";
grid-area: tl;
}
.button-tl {
grid-area: button-tl;
background: #2f2f2f;
color: #fdfdfd;
}
.text-tl {
grid-area: text-tl;
}
.tr {
background: #2f2f2f;
color: #fdfdfd;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: ". . . ." ". text-tr . ." "button-tr . . .";
grid-area: tr;
}
.button-tr {
grid-area: button-tr;
background: #fdfdfd;
color: #2f2f2f;
}
.text-tr { grid-area: text-tr; }
.br {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: "button-br . . ." ". text-br . ." ". . . .";
grid-area: br;
}
.button-br {
grid-area: button-br;
background: #2f2f2f;
color: #fdfdfd;
}
.text-br { grid-area: text-br; }
.bl {
background: #2f2f2f;
color: #fdfdfd;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: ". . . button-bl" ". . text-bl ." ". . . .";
grid-area: bl;
}
.button-bl {
grid-area: button-bl;
background: #fdfdfd;
color: #2f2f2f;
}
.text-bl { grid-area: text-bl; }
<div class="grid-container">
<div class="tl">
<div class="button-tl">button A</div>
<div class="text-tl">word A</div>
</div>
<div class="tr">
<div class="button-tr">button B</div>
<div class="text-tr">word B</div>
</div>
<div class="br">
<div class="button-br">button C</div>
<div class="text-br">word C</div>
</div>
<div class="bl">
<div class="button-bl">button D</div>
<div class="text-bl">word D</div>
</div>
</div>
I want to fire an animation when a user clicks one of those button elements using Anime.js, basically what amounts to a window blind or something similar to a window blind going from the top of the screen to the bottom.
This is the code, I'm sorry because I genuinely could not get this to work on sites like CodePen. The only thing you need here in your package.json is "dependencies": { "animejs":"^3.1.0"} if you want to see the animation I'm talking about.
import anime from '/node_modules/animejs/lib/anime.es.js';
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
anime({
targets: '.animationBox',
keyframes: [{
height: "10%"
},
{
height: "20%"
},
{
height: "30%"
},
{
height: "40%"
},
{
height: "50%"
},
{
height: "60%"
},
{
height: "70%"
},
{
height: "80%"
},
{
height: "90%"
},
{
height: "100%"
}
],
duration: 2000,
easing: 'linear'
});
}, 500);
});
body {
margin: 0;
background: #241B2F;
height: 100vh;
}
#App {
display: flex;
justify-content: flex-end;
align-items: center;
height: 100%;
width: 100%;
}
#hiddenBox {
height: 100%;
width: 100%;
}
.animationBox {
background: white;
height: 0%;
width: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="index.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<title>Anime.js</title>
</head>
<body>
<div id="App">
<div id="hiddenBox">
<div class="animationBox"></div>
</div>
</div>
</body>
<script type="module" src="index.js"></script>
</html>
I want to have that white 'window blind' scroll down on top of the all the other elements on the page, but I don't know how to structure my HTML/CSS to avoid breaking the entire layout. I've tried:
z-index, which didn't seem to accomplish anything, presumably because z-index requires position:relative or position:absolute, which also breaks the grid
display: none and other variations like visibility: hidden, but these didn't work either and still caused the structure to get messed up
putting the animated white div off the screen and placing it using a function that gets triggered onClick()
I guess a TL;DR is: How do I overlay a div on top of a grid without breaking anything in the grid layout? Basically, this image:
You can add a div to the end of your site's HTML, just before the closing tag with the following CSS.
<div id="divname" style="
background-color:white;
position: fixed;
top: 0px;
right: 0px;
height: 0;
width: 100vw;">
</div>
That should create an overlay div that you can QuerySelect in JS to animate.
Please take a look at the below example. I'm learning css grids. The whole purpose is to keep things simple and to not need to specify distinct layout details on the child elements unnecessarily, so solutions should conform to this pattern.
Given the following:
function toggle(t) {
document.querySelectorAll('div').forEach(el =>
el.classList[0] === t.classList[0] ?
el.classList.toggle('selected') :
el.classList.remove('selected'))
}
:root,
html,
body,
main {
margin: 0;
padding: 0;
font-family: sans-serif;
height: 100%;
}
main {
border: solid 3pt white;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
}
div {
grid-area: span 2 / span 2;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
font-size: 5em;
font-weight: bold;
color: white;
background: grey;
}
.one {
background: red
}
.two {
background: green
}
.three {
background: blue
}
.selected {
width: 150%;
height: 150%;
z-index: 2;
}
<main>
<div class=one onclick="toggle(event.target)">one</div>
<div class=two onclick="toggle(event.target)">two</div>
<div class=three onclick="toggle(event.target)">three</div>
<div class=four onclick="toggle(event.target)">four</div>
</main>
https://jsfiddle.net/robbie_at_harvard/a3ouq711/1/
Please adjust to cause the areas two, three and four to expand towards the middle instead of always from the top-left corner? Again, preferably with generic rules rather than ones specific to the div.class specifications.
Second question, if I wanted instead a 4x4 layout of 2x2 child elements, where clicking on one element expanded it to 3x3 and contracted the others to 1x2, 2x1, and 1x1 in the opposite corner, what is necessary to produce this solution?
You could use transform:scale(1.5) and position it with transform-origin.
It would require specific CSS rules depending on the grid (i use :nth-child to target each element)
For 2x2 use
main div:nth-child(1){transform-origin: top left;}
main div:nth-child(2){transform-origin: top right;}
main div:nth-child(3){transform-origin: bottom left;}
main div:nth-child(4){transform-origin: bottom right;}
.selected {
transform:scale(1.5);
z-index: 2;
}
function toggle(t) {
document.querySelectorAll('div').forEach(el =>
el.classList[0] === t.classList[0] ?
el.classList.toggle('selected') :
el.classList.remove('selected'))
}
:root,
html,
body,
main {
margin: 0;
padding: 0;
font-family: sans-serif;
height: 100%;
}
main {
border: solid 3pt white;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
}
div {
grid-area: span 2 / span 2;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
font-size: 5em;
font-weight: bold;
color: white;
background: grey;
}
.one {
background: red
}
.two {
background: green
}
.three {
background: blue
}
main div:nth-child(1) {
transform-origin: top left;
}
main div:nth-child(2) {
transform-origin: top right;
}
main div:nth-child(3) {
transform-origin: bottom left;
}
main div:nth-child(4) {
transform-origin: bottom right;
}
.selected {
transform: scale(1.5);
z-index: 2;
}
<main>
<div class=one onclick="toggle(event.target)">one</div>
<div class=two onclick="toggle(event.target)">two</div>
<div class=three onclick="toggle(event.target)">three</div>
<div class=four onclick="toggle(event.target)">four</div>
</main>
I think it's difficult to have a general solution since the 4 blocks need to move in different ways. By the way here a solution that involve few CSS changes.
I know you want a generic one but i think in all the cases you will have some specificities (like the color and the content)
function toggle(t) {
document.querySelectorAll('div').forEach(el =>
el.classList[0] === t.classList[0] ?
el.classList.toggle('selected') :
el.classList.remove('selected'))
}
:root,
html,
body,
main {
margin: 0;
padding: 0;
font-family: sans-serif;
height: 100%;
}
main {
position:relative;
border: solid 3pt white;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
}
div {
grid-area: span 2 / span 2;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
font-size: 5em;
font-weight: bold;
color: white;
background: grey;
transition:0.5s;
}
.one {
background: red;
}
.two {
background: green;
right:25%;
}
.three {
background: blue;
bottom:25%;
}
.four {
bottom:25%;
right:25%;
}
.selected {
position:relative;
width:150%;
height:150%;
}
<main>
<div class=one onclick="toggle(event.target)">one</div>
<div class=two onclick="toggle(event.target)">two</div>
<div class=three onclick="toggle(event.target)">three</div>
<div class=four onclick="toggle(event.target)">four</div>
</main>