Have one text element track the position of another text element - javascript

I would like to have the red "Aliquam" text inside of the div with class ".absolute" track on top of the exact position of the (blue) "Aliquam" text inside ".aliquam-span", including on browser resize.
I've tried a few different ways to do this but haven't had much luck - hoping that someone here can help.
Nesting the text as a child of the span is not an option, unfortunately.
Thank you!
let aliquam = document.querySelector('.aliquam-span')
let aliquamAbsolute = document.querySelector('.red-text')
let aliquamRect = aliquam.getBoundingClientRect()
let aliquamAbsoluteRect = aliquamAbsolute.getBoundingClientRect()
let xOffset = aliquamRect.left - aliquamAbsoluteRect.left
let yOffset = aliquamRect.top - aliquamAbsoluteRect.top
console.log({xOffset})
aliquamAbsolute.style.left = `${xOffset}px`
aliquamAbsolute.style.top = `${yOffset}px`
.container {
width: 100%;
max-width: 60rem;
margin-left: auto;
margin-right: auto;
}
p {
font-size: 1.5rem;
}
.wrap {
position: relative;
}
.absolute {
position: absolute;
inset: 0;
}
.red-text {
position: relative;
color: red;
left: '200px';
}
.aliquam-span {
color: blue;
}
<div class="container">
<div class="wrap">
<p>Maecenas a finibus sapien. Duis pulvinar ligula vel arcu cursus, in euismod nunc iaculis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce facilisis quis libero nec bibendum. Donec suscipit eros sit amet ex condimentum ullamcorper. Aliquam dictum, risus id pharetra congue, nisl nisi facilisis enim, sit amet facilisis nunc diam condimentum eros. Aenean euismod turpis id enim commodo sagittis. <span class="aliquam-span">Aliquam</span> eget dolor eget nulla tempus imperdiet. Praesent gravida, nisl quis malesuada faucibus, orci purus ultrices velit, ut porttitor libero ante at nisl. Duis eget convallis risus. Nunc vitae orci non tellus ultricies vestibulum in a augue. Vestibulum hendrerit leo ac nunc rutrum imperdiet. Integer sem tellus, maximus vel interdum ut, accumsan vel orci. Mauris maximus leo vitae felis dapibus euismod. Nulla facilisi. Donec ac ullamcorper justo.</p>
<div class="absolute">
<p class="red-text">Aliquam</p>
</div>
</div>
</div>

It works for me, try it:
function changePosition () {
let aliquam = document.querySelector('.aliquam-span');
let aliquamAbsolute = document.querySelector('.red-text').parentElement;
let aliquamRect = aliquam.getBoundingClientRect();
aliquamAbsolute.style.top = aliquamRect.top + 'px';
aliquamAbsolute.style.right = aliquamRect.right + 'px';
aliquamAbsolute.style.left = aliquamRect.left + 'px';
aliquamAbsolute.style.bottom = aliquamRect.bottom + 'px';
}
window.onresize = changePosition;
window.onload = changePosition;
.container {
width: 100%;
max-width: 60rem;
margin-left: auto;
margin-right: auto;
}
p {
font-size: 1.5rem;
}
.wrap {
}
.absolute {
position: absolute;
inset: 0;
}
.red-text {
position: relative;
color: red;
left: '200px';
margin: 0;
}
.aliquam-span {
color: blue;
}
<div class="container">
<div class="wrap">
<p>Maecenas a finibus sapien. Duis pulvinar ligula vel arcu cursus, in euismod nunc iaculis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce facilisis quis libero nec bibendum. Donec suscipit eros sit amet ex condimentum ullamcorper. Aliquam dictum, risus id pharetra congue, nisl nisi facilisis enim, sit amet facilisis nunc diam condimentum eros. Aenean euismod turpis id enim commodo sagittis. <span class="aliquam-span">Aliquam</span> eget dolor eget nulla tempus imperdiet. Praesent gravida, nisl quis malesuada faucibus, orci purus ultrices velit, ut porttitor libero ante at nisl. Duis eget convallis risus. Nunc vitae orci non tellus ultricies vestibulum in a augue. Vestibulum hendrerit leo ac nunc rutrum imperdiet. Integer sem tellus, maximus vel interdum ut, accumsan vel orci. Mauris maximus leo vitae felis dapibus euismod. Nulla facilisi. Donec ac ullamcorper justo.</p>
<div class="absolute">
<p class="red-text">Aliquam</p>
</div>
</div>
</div>

You should target the div that is being set as the absolutely positioned one. So select .absolute instead of the .red-text.
let aliquam = document.querySelector('.aliquam-span')
let aliquamAbsolute = document.querySelector('.absolute')
let aliquamRect = aliquam.getBoundingClientRect()
let aliquamAbsoluteRect = aliquamAbsolute.getBoundingClientRect()
let xOffset = aliquamRect.left - aliquamAbsoluteRect.left
let yOffset = aliquamRect.top - aliquamAbsoluteRect.top
console.log({xOffset, yOffset})
aliquamAbsolute.style.left = `${xOffset}px`
aliquamAbsolute.style.top = `${yOffset}px`
.container {
width: 100%;
max-width: 60rem;
margin-left: auto;
margin-right: auto;
}
p {
font-size: 1.5rem;
}
.wrap {
position: relative;
}
.absolute {
position: absolute;
top: 0;
left: 0;
inset: 0;
}
.red-text {
color: red;
margin: 0;
}
.aliquam-span {
color: blue;
}
<div class="container">
<div class="wrap">
<p>Maecenas a finibus sapien. Duis pulvinar ligula vel arcu cursus, in euismod nunc iaculis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce facilisis quis libero nec bibendum. Donec suscipit eros sit amet ex condimentum ullamcorper. Aliquam dictum, risus id pharetra congue, nisl nisi facilisis enim, sit amet facilisis nunc diam condimentum eros. Aenean euismod turpis id enim commodo sagittis. <span class="aliquam-span">Aliquam</span> eget dolor eget nulla tempus imperdiet. Praesent gravida, nisl quis malesuada faucibus, orci purus ultrices velit, ut porttitor libero ante at nisl. Duis eget convallis risus. Nunc vitae orci non tellus ultricies vestibulum in a augue. Vestibulum hendrerit leo ac nunc rutrum imperdiet. Integer sem tellus, maximus vel interdum ut, accumsan vel orci. Mauris maximus leo vitae felis dapibus euismod. Nulla facilisi. Donec ac ullamcorper justo.</p>
<div class="absolute">
<p class="red-text">Aliquam</p>
</div>
</div>
</div>

The folks at GSAP helped me out on this one!
Three different answers here:
https://greensock.com/forums/topic/35705-tracking-position-of-a-text-span-with-javascript/

Related

Is it possible to align child items based on parents border-radius

I am creating a custom scrollbar with absolute positioned divs at the right(for vertical) and bottom(for horizontal).
When there is a border radius on parent, both scrollbars edge gets hidden.
Is there a way we can align the child elements based on border-radius of parent?
Like this:
Below is my html:
<div class=“content-container”>
<div class=“content”>SOME OVERFLOW CONTENT</div>
<div class=“scrollbar-y”>
<div class=“scrollbar-track”>
<div class=“scrollbar-thumb”></div>
</div>
</div>
</div>
Below is my css:
.content-container {
position: relative;
height: 400px;
width: 600px;
}
.content {
height: 100%;
width: 100%;
overflow: auto;
}
.scrollbar-y {
position: absolute;
top: 0;
right: 0;
height: 100%;
}
.scrollbar-track {
width: 16px;
height: 100%;
border: 4px;
background: transparent;
position: relative;
}
.scrollbar-thumb {
top: 0; // calculated based on scroll event
width: 8px;
background: grey;
height: 42px; // calculated based on clientHeight and scrollHeight
}
Here. You have to set height of "scrollbar-button".
.container {
overflow-y: auto;
max-height: 170px;
border: 1px solid #b9b9b9;
border-radius: 20px;
padding: 10px;
}
.container::-webkit-scrollbar {
width: 6px;
}
.container::-webkit-scrollbar-track {
background: #7070705e 0% 0% no-repeat padding-box;
border-radius: 100px;
}
.container::-webkit-scrollbar-button {
height: 14px;
}
.container::-webkit-scrollbar-thumb {
background: #707070 0% 0% no-repeat padding-box;
border-radius: 100px;
}
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu tellus elit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut at erat in purus fermentum sodales. Nulla vel nunc vel metus interdum venenatis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Fusce tincidunt porttitor massa, in aliquam mauris vehicula id. In non volutpat velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nunc nisi dolor, viverra et efficitur ornare, lobortis vel velit. Integer volutpat, justo eleifend cursus pellentesque, lectus turpis fringilla elit, sit amet ultrices est magna ac leo. Sed dolor ipsum, bibendum ac viverra vel, vehicula ac quam. Sed eu justo vitae turpis vehicula interdum.
Cras ultricies leo eu aliquet ullamcorper. Pellentesque eu placerat velit. Sed sit amet gravida metus, nec auctor lectus. Donec blandit purus id est vehicula gravida. Aenean viverra enim id leo pretium, rhoncus mollis magna fringilla. Ut ullamcorper tempus urna id efficitur. Integer sit amet mattis nibh, ac sagittis diam. Morbi feugiat lacinia tortor nec dapibus. Pellentesque lobortis nec risus ac lacinia. Maecenas iaculis nisl nec lacus vehicula vulputate. Sed nec tortor id dui condimentum pulvinar. Donec nulla nisi, convallis at consectetur gravida, suscipit eu ante. In bibendum congue nisi, eget ullamcorper lectus bibendum in. Integer semper tortor elementum dui vestibulum tincidunt. Suspendisse potenti. Mauris vel velit vel felis fringilla dignissim.
Sed mauris nunc, auctor ac velit at, tempor sagittis diam. Nullam volutpat rutrum faucibus. Mauris ultrices tempor tempor. Mauris varius mauris sed viverra sollicitudin. Praesent nec eros sed enim consequat commodo. Donec id dui at nisi elementum condimentum. Nulla luctus lacus eu aliquam condimentum. Morbi vel dapibus massa. In nibh lectus, commodo vel elit in, sagittis varius elit. Donec in ex lorem. Vivamus id mattis dolor, nec finibus augue. Curabitur ut justo eu velit congue maximus. Maecenas non augue erat. Nam euismod leo ut enim dignissim, vitae semper dolor rhoncus.
</div>

Grid footer covers site content

I have the following code which contains a modification of CSS code suggested by another user in one of my posted questions.
The code implements a grid which is used as a responsive footer menu, which also contains a copyright reference for the site.
The problem is that the footer covers the content of the website. Is there a way to avoid covering any of the 3 tags of the website with the tag that implements the grid?
function myFunction() {
var x = document.getElementById("myNavbar");
if (x.className === "navbar") {
x.className += " responsive";
} else {
x.className = "navbar";
}
}
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
#content {
max-width: 720px;
margin: 100px auto 0;
}
#divleft {
position: fixed;
top: 50%;
transform: translate(-50%, -50%);
left: calc((100% - 720px)/4);
width: 200px;
height: 400px;
border: solid;
border-color: red;
}
#divright {
position: fixed;
top: 50%;
transform: translate(50%, -50%);
right: calc((100% - 720px)/4);
width: 200px;
height: 400px;
border: solid;
border-color: red;
}
/*
The Navigation Container/Block
*/
.navbar {
background-color: #333;
position: fixed;
bottom: 0%;
right: 0%;
width: 100%;
}
/*
Grid Container
*/
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/*
Item 1
*/
.item-1 {
text-align: end;
}
/*
Item 2
*/
.item-2 {
color: white;
display: flex;
align-items: center;
justify-content: center;
}
/*
Item 3
*/
.item-3 {
text-align: end;
display: flex;
align-items: center;
justify-content: flex-end;
}
.item-3 a {
color: #f2f2f2;
text-align: center;
padding: 15px 16px;
text-decoration: none;
}
.item-3 a:hover {
background-color: #ddd;
color: black;
}
.item-3 a.active {
background-color: #04aa6d;
color: white;
}
/*
Toggle Icon For Menu
*/
.navbar .icon {
display: none;
}
/*
This Will Display In Media Queries
*/
.copyright-bottom {
display: none;
}
/*
Media Queries
*/
#media screen and (max-width: 970px) {
.item-3 a {
display: none;
}
.navbar a.icon {
display: block;
}
.navbar.responsive .icon {
position: absolute;
right: 0;
bottom: 0;
}
.navbar.responsive a {
display: block;
text-align: left;
}
.navbar.responsive .copyright-bottom {
display: block;
text-align: center;
color: white;
}
.navbar.responsive .copyright {
display: none;
}
.navbar.responsive .item-3 {
grid-column: span 3;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<section id="divleft"></section>
<section id="content">
<h2>Responsive Bottom Navbar Example</h2>
<p>Resize the browser window to see how it works.</p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque et viverra justo. Suspendisse quis ligula ac nibh ultricies ultrices. Etiam vel sagittis nunc. Praesent mi justo, ultrices sit amet lectus id, tincidunt volutpat nulla. Vivamus neque dolor,
elementum sit amet enim in, fringilla faucibus neque. Fusce a lectus enim. Pellentesque risus orci, efficitur et facilisis et, egestas eu eros. Sed commodo lacinia dolor eget suscipit. Ut facilisis orci lorem, et vehicula risus sollicitudin eu. Donec
aliquam urna at mi consectetur, sed condimentum velit vehicula. Nam et urna fringilla, vulputate risus ac, posuere ante. Morbi at ex et libero lobortis viverra. Donec nibh massa, faucibus a hendrerit ac, faucibus ac diam. Nunc vel gravida dui, euismod
viverra ex. Praesent elementum egestas venenatis. Duis quis nulla mi. Aliquam efficitur enim ipsum, sed venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod et vel turpis. Quisque vel tincidunt purus. Aliquam a mauris tortor. Vestibulum fringilla augue sit amet egestas tempus. Pellentesque pellentesque erat id porta
interdum. Vestibulum eros nibh, sagittis sit amet velit ut, auctor tincidunt tortor. Cras blandit condimentum enim ac sagittis. Nunc pretium, metus id pulvinar efficitur, nunc nunc sagittis sem, eget efficitur elit dui quis nisi. Mauris eros ex, elementum
sit amet neque at, elementum bibendum quam. Quisque ornare in lacus non maximus. Nullam volutpat, nisi vel consectetur mattis, magna ligula condimentum mauris, sed accumsan nibh augue quis dolor. Aenean id dignissim purus. Donec venenatis condimentum
nisl, quis placerat lorem suscipit nec. Vestibulum ante massa, euismod et pellentesque ut, eleifend volutpat arcu. Mauris porttitor nec orci vitae hendrerit. Suspendisse cursus urna id ullamcorper placerat. Nullam varius diam ut nibh molestie, a sodales
leo ultricies. Ut eget felis malesuada, imperdiet lectus finibus, aliquam quam. Pellentesque ac leo aliquam, viverra lorem in, dignissim nisl. Cras ligula mauris, bibendum vel ex ac, sodales ullamcorper magna. Etiam ac libero ut mi semper dignissim.
Proin eu enim at nunc porttitor mattis. Duis nec nisi vel est lacinia tincidunt. Sed interdum turpis sed ante maximus tristique. Etiam non urna placerat, ornare diam at, dictum massa. Praesent et imperdiet sem, quis varius mauris. Proin nunc elit,
vehicula non posuere sed, rhoncus vitae nunc. Duis ornare condimentum felis ut tempor. Donec tempor est nec diam gravida fermentum. Sed sit amet libero non tortor ultricies lacinia eu cursus metus. Morbi porta blandit libero sit amet laoreet. Vivamus
auctor dui sit amet turpis rutrum dapibus. Quisque tortor ipsum, interdum id sodales in, cursus at turpis. Duis dui sapien, finibus vel venenatis a, gravida nec sapien. Aenean tortor lorem, venenatis eu quam ac, ullamcorper pulvinar erat. In hac habitasse
platea dictumst. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus eleifend interdum mattis. Praesent et mi nec lacus mattis dictum quis et augue. Donec aliquam rutrum felis ac vestibulum. Sed vehicula
luctus enim. Vivamus pharetra neque nec ante tincidunt, quis lobortis quam rutrum. Nulla non consequat mauris, vel posuere nisi. Fusce varius imperdiet libero sit amet mattis. Vivamus ut efficitur velit, quis dapibus nisi. Pellentesque tempus turpis
nec tortor mollis, in euismod lectus porttitor. Proin dignissim accumsan nisi a sollicitudin. Pellentesque scelerisque ipsum eu risus mollis dapibus. Cras eget ornare odio, ac ultricies urna. Aliquam porttitor nunc leo, eleifend pretium magna congue
ac. In ut odio et ante tincidunt malesuada vel ac velit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aenean vestibulum tempus velit, nec maximus quam. Proin pellentesque risus vel enim dictum tincidunt. Curabitur purus turpis, efficitur
eu velit in, efficitur tincidunt neque. Proin dignissim efficitur nisl sit amet efficitur. Sed dictum tellus eu turpis porta porta. Vestibulum in ipsum urna. Donec finibus sed lacus sed mattis. Fusce lacinia mauris vitae mauris lobortis, ut auctor
neque posuere. Donec scelerisque mauris in justo cursus varius. Aliquam varius sodales diam vel iaculis. In et malesuada velit, nec pulvinar lacus. Quisque eu auctor tortor. Ut iaculis placerat lacus, quis tempor erat lacinia in. Vivamus tempor purus
velit, vel mollis enim pellentesque sed. Aenean euismod lobortis ultrices. In volutpat sem vitae iaculis dignissim. Sed auctor, leo lobortis aliquam sodales, tellus tortor mattis dolor, sed iaculis elit purus eu nisi. Donec viverra laoreet ipsum eget
pulvinar. Sed nisl ipsum, congue id ornare eu, vulputate vitae turpis. Suspendisse feugiat dui at elit placerat eleifend. Morbi quam ligula, eleifend nec elit vel, lacinia vehicula nibh. Maecenas in orci ut odio aliquam sodales a vitae urna. Maecenas
eget interdum dolor. Integer vel magna mi. Suspendisse at consectetur lectus, sed accumsan erat. Aliquam erat volutpat. Mauris non mauris auctor, fringilla arcu vitae, bibendum justo. Sed pulvinar et magna eget cursus. Etiam quis risus vitae ipsum
pharetra vulputate. Vestibulum commodo ac nisl sit amet porta. Ut ultrices tristique ipsum et commodo. Integer urna ipsum, vehicula convallis metus suscipit, euismod rhoncus lectus. Mauris elementum odio ut odio aliquam, ut fringilla tellus facilisis.
In vitae arcu ut orci pellentesque consequat. Maecenas sit amet sem a sem varius porta ut a risus. Phasellus ac lacus aliquam, mollis felis vel, finibus arcu. Ut sodales nulla odio, sit amet sodales nibh bibendum ac. Sed purus dolor, iaculis et nunc
sit amet, viverra maximus nisl.
</section>
<section id="divright"></section>
<footer class="navbar" id="myNavbar">
<div class="grid-container">
<div class="item-1"></div>
<div class="item-2">
<p class="copyright">© domain.com</p>
</div>
<div class="item-3">
About
Contact
News
Home
<a href="javascript:void(0);" style="font-size: 15px" class="icon" onclick="myFunction()">☰</a
>
</div>
</div>
<p class="copyright-bottom">© domain.com</p>
</footer>
</body>
</html>
You Can Use This:
you can change the value with the one you want!
#content
{
margin-bottom:70px;
}
You can update your footer like this, so the footer doesn't cover your text.
Your two ad bars have a fixed height and width, so your footer will cover those on different screen sizes.
.navbar {
background-color: #333;
position: sticky;
bottom: 0;
right: 0;
width: 100%;
}
And then introduce flexbox to stretch your content. Your code looks then something like this:
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
display: flex;
flex-direction: column;
min-height: 100vh;
}
#content {
max-width: 720px;
margin: 100px auto 0;
flex: 1;
}
#divleft {
position: fixed;
top: 50%;
transform: translate(-50%, -50%);
left: calc((100% - 720px)/4);
width: 200px;
height: 400px;
border: solid;
border-color: red;
}
#divright {
position: fixed;
top: 50%;
transform: translate(50%, -50%);
right: calc((100% - 720px)/4);
width: 200px;
height: 400px;
border: solid;
border-color: red;
}
/*
The Navigation Container/Block
*/
.navbar {
background-color: #333;
position: sticky;
bottom: 0%;
right: 0%;
width: 100%;
}
/*
Grid Container
*/
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/*
Item 1
*/
.item-1 {
text-align: end;
}
/*
Item 2
*/
.item-2 {
color: white;
display: flex;
align-items: center;
justify-content: center;
}
/*
Item 3
*/
.item-3 {
text-align: end;
display: flex;
align-items: center;
justify-content: flex-end;
}
.item-3 a {
color: #f2f2f2;
text-align: center;
padding: 15px 16px;
text-decoration: none;
}
.item-3 a:hover {
background-color: #ddd;
color: black;
}
.item-3 a.active {
background-color: #04aa6d;
color: white;
}
/*
Toggle Icon For Menu
*/
.navbar .icon {
display: none;
}
/*
This Will Display In Media Queries
*/
.copyright-bottom {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<section id="divleft"></section>
<section id="content">
<h2>Responsive Bottom Navbar Example</h2>
<p>Resize the browser window to see how it works.</p>
viverra ex. Praesent elementum egestas venenatis. Duis quis nulla mi. Aliquam efficitur enim ipsum, sed venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod et vel turpis. Quisque vel tincidunt purus. Aliquam a mauris tortor. Vestibulum fringilla augue sit amet egestas tempus. Pellentesque pellentesque erat id portaviverra ex. Praesent elementum egestas venenatis. Duis quis nulla mi. Aliquam efficitur enim ipsum, sed venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod et vel turpis. Quisque vel tincidunt purus. Aliquam a mauris tortor. Vestibulum fringilla augue sit amet egestas tempus. Pellentesque pellentesque erat id portaviverra ex. Praesent elementum egestas venenatis. Duis quis nulla mi. Aliquam efficitur enim ipsum, sed venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod et vel turpis. Quisque vel tincidunt purus. Aliquam a mauris tortor. Vestibulum fringilla augue sit amet egestas tempus. Pellentesque pellentesque erat id portaviverra ex. Praesent elementum egestas venenatis. Duis quis nulla mi. Aliquam efficitur enim ipsum, sed venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod et vel turpis. Quisque vel tincidunt purus. Aliquam a mauris tortor. Vestibulum fringilla augue sit amet egestas tempus. Pellentesque pellentesque erat id portaviverra ex. Praesent elementum egestas venenatis. Duis quis nulla mi. Aliquam efficitur enim ipsum, sed venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod et vel turpis. Quisque vel tincidunt purus. Aliquam a mauris tortor. Vestibulum fringilla augue sit amet egestas tempus. Pellentesque pellentesque erat id portaviverra ex. Praesent elementum egestas venenatis. Duis quis nulla mi. Aliquam efficitur enim ipsum, sed venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod et vel turpis. Quisque vel tincidunt purus. Aliquam a mauris tortor. Vestibulum fringilla augue sit amet egestas tempus. Pellentesque pellentesque erat id porta
interdum. Vestibulum eros nibh, sagittis sit amet velit ut, auctor tincidunt tortor. Cras blandit condimentum enim ac sagittis. Nunc pretium, metus id pulvinar efficitur, nunc nunc sagittis sem, eget efficitur elit dui quis nisi. Mauris eros ex, elementum
sit amet neque at, elementum bibendum quam. Quisque ornare in lacus non maximus. Nullam volutpat, nisi vel consectetur mattis, magna ligula condimentum mauris, sed accumsan nibh augue quis dolor. Aenean id dignissim purus. Donec venenatis condimentum
nisl, quis placerat lorem suscipit nec. Vestibulum ante massa, euismod et pellentesque ut, eleifend volutpat arcu. Mauris porttitor nec orci vitae hendrerit. Suspendisse cursus urna id ullamcorper placerat. Nullam varius diam ut nibh molestie, a sodales
leo ultricies. Ut eget felis malesuada, imperdiet lectus finibus, aliquam quam. Pellentesque ac leo aliquam, viverra lorem in, dignissim nisl. Cras ligula mauris, bibendum vel ex ac, sodales ullamcorper magna. Etiam ac libero ut mi semper dignissim.
Proin eu enim at nunc porttitor mattis. Duis nec nisi vel est lacinia tincidunt. Sed iut fringilla tellus facil
</section>
<section id="divright"></section>
<footer class="navbar" id="myNavbar">
<div class="grid-container">
<div class="item-1"></div>
<div class="item-2">
<p class="copyright">© domain.com</p>
</div>
<div class="item-3">
About
Contact
News
Home
<a href="javascript:void(0);" style="font-size: 15px" class="icon" onclick="myFunction()">☰</a
>
</div>
</div>
<p class="copyright-bottom">© domain.com</p>
</footer>
</body>
</html>
It will work with less content also fine.
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
display: flex;
flex-direction: column;
min-height: 100vh;
}
#content {
max-width: 720px;
margin: 100px auto 0;
flex: 1;
}
#divleft {
position: fixed;
top: 50%;
transform: translate(-50%, -50%);
left: calc((100% - 720px)/4);
width: 200px;
height: 400px;
border: solid;
border-color: red;
}
#divright {
position: fixed;
top: 50%;
transform: translate(50%, -50%);
right: calc((100% - 720px)/4);
width: 200px;
height: 400px;
border: solid;
border-color: red;
}
/*
The Navigation Container/Block
*/
.navbar {
background-color: #333;
position: sticky;
bottom: 0%;
right: 0%;
width: 100%;
}
/*
Grid Container
*/
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/*
Item 1
*/
.item-1 {
text-align: end;
}
/*
Item 2
*/
.item-2 {
color: white;
display: flex;
align-items: center;
justify-content: center;
}
/*
Item 3
*/
.item-3 {
text-align: end;
display: flex;
align-items: center;
justify-content: flex-end;
}
.item-3 a {
color: #f2f2f2;
text-align: center;
padding: 15px 16px;
text-decoration: none;
}
.item-3 a:hover {
background-color: #ddd;
color: black;
}
.item-3 a.active {
background-color: #04aa6d;
color: white;
}
/*
Toggle Icon For Menu
*/
.navbar .icon {
display: none;
}
/*
This Will Display In Media Queries
*/
.copyright-bottom {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<section id="divleft"></section>
<section id="content">
<h2>Responsive Bottom Navbar Example</h2>
<p>Resize the browser window to see how it works.</p>
venenatis tortor tempor eu. Maecenas maximus diam nec ante pellentesque, a efficitur ipsum semper. Donec sagittis enim quis nisl efficitur sodales.
Etiam porttitor tristique urna ut auctor. Mauris eget urna quis diam interdum euismod
</section>
<section id="divright"></section>
<footer class="navbar" id="myNavbar">
<div class="grid-container">
<div class="item-1"></div>
<div class="item-2">
<p class="copyright">© domain.com</p>
</div>
<div class="item-3">
About
Contact
News
Home
<a href="javascript:void(0);" style="font-size: 15px" class="icon" onclick="myFunction()">☰</a
>
</div>
</div>
<p class="copyright-bottom">© domain.com</p>
</footer>
</body>
</html>

Grow Canvas to fit following div

I have a canvas which I want to be 100% screen width and at least 100% screen height, but more if the following div goes beyond the bottom of the screen.
I am filling the canvas using Trianglify.
var pattern = Trianglify({
cell_size: 25,
x_colors: 'Greens'
});
pattern.canvas(document.getElementById('container1'));
setInterval(function() {
// method to be executed;
var pattern = Trianglify({
cell_size: 25,
x_colors: 'Greens'
});
pattern.canvas(document.getElementById('container1'));
}, 1000);
canvas#container1 {
position: absolute;
width: 100vw;
min-height: 100vh;
}
.screen-container {
min-height: 100vh;
position: relative
}
.trianglify-container {
background-color: transparent;
color: #fff;
text-align: center;
padding-top: 20vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/trianglify/1.0.1/trianglify.min.js"></script>
<canvas id="container1"></canvas>
<div class="screen-container trianglify-container">
<div class="container">
...
</div>
</div>
EDIT
The important thing for me is that the div immediately following the canvas needs to have the canvas covering all of it's background and cover at least 1 screen. It there is a different way to achieve this I'm happy to adapt my approach.
Is this result what you want?
-- Long content --
var pattern = Trianglify({
cell_size: 25,
x_colors: 'Greens'
});
pattern.canvas(document.getElementById('container1'));
setInterval(function() {
// method to be executed;
var pattern = Trianglify({
cell_size: 25,
x_colors: 'Greens'
});
pattern.canvas(document.getElementById('container1'));
}, 1000);
.outer-wrapper{
min-height: 100vh;
position: relative;
}
canvas#container1 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.screen-container {
/*min-height: 100vh;*/
position: relative;
}
.trianglify-container {
background-color: transparent;
color: #fff;
text-align: center;
/*padding-top: 20vh;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/trianglify/1.0.1/trianglify.min.js"></script>
<div class="outer-wrapper">
<canvas id="container1"></canvas>
<div class="screen-container trianglify-container">
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ullamcorper lacinia semper. Pellentesque dignissim tempus nisi sit amet porttitor. Sed laoreet, nisi eu auctor cursus, tellus turpis porta diam, ac fermentum enim odio auctor dolor. Duis in nunc rhoncus, vestibulum est at, fermentum ligula. Suspendisse dui dui, luctus id lacus eu, tempor venenatis sem. Ut pellentesque sodales turpis quis efficitur. Donec vulputate placerat orci, vitae porttitor nunc. Etiam risus nibh, porta porta libero in, tempor auctor dolor. Quisque id augue at dui egestas vulputate.
Praesent tristique eu urna non faucibus. Nunc leo urna, euismod in neque vitae, elementum consequat libero. Integer in dignissim nunc, id scelerisque metus. Etiam ut ipsum iaculis, ullamcorper eros nec, elementum odio. Donec ornare lorem a semper porttitor. Suspendisse tincidunt mauris nec dui rhoncus, in semper augue blandit. Integer laoreet, velit sed molestie malesuada, enim quam mollis sapien, ullamcorper sollicitudin mi mi non urna. Mauris eu dignissim lectus.
Aliquam lacus tortor, dictum quis pulvinar volutpat, tincidunt id leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce fermentum aliquam neque vitae bibendum. Nulla volutpat luctus urna et faucibus. Fusce convallis nulla tortor, vel ornare ante scelerisque in. Vivamus justo odio, porta nec vulputate ut, volutpat quis ipsum. Praesent id volutpat justo, sit amet euismod dui. In eget erat massa. Aliquam ultrices egestas ipsum, ac tincidunt diam gravida ac. Nullam tortor dui, viverra scelerisque vehicula varius, luctus in ipsum. Nulla dolor est, mattis in pellentesque at, interdum ac nibh.
Ut bibendum tellus varius orci aliquet luctus. Duis tortor nisl, suscipit at ornare ut, scelerisque nec dolor. Ut efficitur facilisis nulla a rutrum. Donec ut sodales odio, sed venenatis leo. Ut scelerisque eros in gravida fringilla. Aliquam fringilla vitae orci sed tincidunt. Aenean efficitur nibh elit, id sollicitudin enim mattis ut.
Praesent hendrerit ex eget quam ultrices, eget iaculis nunc pellentesque. In in orci interdum sapien bibendum sagittis. Mauris at massa quis nisi commodo facilisis at vel ligula. Vestibulum vitae aliquet lorem, vel faucibus lacus. Integer tortor nulla, rutrum dictum elit a, iaculis scelerisque nulla. Suspendisse massa eros, cursus quis enim a, volutpat aliquam quam. Fusce tristique tortor id laoreet blandit. Donec laoreet enim felis, consequat faucibus ante auctor vitae. Duis sollicitudin euismod dolor, in accumsan ipsum. Mauris tempus ligula nec nisl ornare dictum. Quisque luctus dolor magna. Maecenas et neque eu mi pellentesque maximus eu sit amet purus. Fusce eu porta tellus.
</div>
</div>
</div>
-- Same code, this time with a shorter content --
var pattern = Trianglify({
cell_size: 25,
x_colors: 'Greens'
});
pattern.canvas(document.getElementById('container1'));
setInterval(function() {
// method to be executed;
var pattern = Trianglify({
cell_size: 25,
x_colors: 'Greens'
});
pattern.canvas(document.getElementById('container1'));
}, 1000);
I just wraped them both inside a wrapper div that has `min-height: 100%`. The wrapper div will expand with the content if it get longers, while the canvas always fill the wrapper div.
.outer-wrapper{
min-height: 100vh;
position: relative;
}
canvas#container1 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.screen-container {
/*min-height: 100vh;*/
position: relative;
}
.trianglify-container {
background-color: transparent;
color: #fff;
text-align: center;
/*padding-top: 20vh;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/trianglify/1.0.1/trianglify.min.js"></script>
<div class="outer-wrapper">
<canvas id="container1"></canvas>
<div class="screen-container trianglify-container">
<div class="container">
Short content
</div>
</div>
</div>
https://jsfiddle.net/hbe5j4m9/4/
Like this?
I Updated the .screen-container to contain the height of the canvas
.screen-container {
min-height: 100%;
position: relative
}

div like fixed but with position:absolute

I need something like this, but with position:absolute not fixed.
Is it possible with JavaScript to change top when user scrolling page?
var elementPosition = $('#div2').offset();
var div1 = $('#div1');
var main=$('#main');
var spacer = $('#spacer');
$(window).scroll(function(){
if($(window).scrollTop() > elementPosition.top){
var left = Math.ceil(div1.offset().left + div1.outerWidth()) + 'px';
console.log(main.width(), div1.width())
var width = main.width() - div1.outerWidth() + 'px';
$('#div2').css({
position: 'fixed',
left: left,
width: width
});
} else {
$('#div2').css({
'position':'static',
width: 'auto'
});
}
});
body{
margin: 0;
width: 100%;
}
* { box-sizing: border-box;}
#main{
width:80%;
margin:0 auto;
}
#div1{
width: 10%;
border: solid 1px #000000;
background-color: #0066CC;
float: left;
}
#div2{
height: 30px;
border: solid 1px #000000;
background-color: #66CC00;
}
#spacer {
width: 90%;
min-height:30px;
float:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="main">
<div id="div1">Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu, luctus et interdum adipiscing wisi. Aliquam erat ac ipsum. Integer aliquam purus. Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non, consectetuer lobortis quis, varius in, purus. Integer ultrices posuere cubilia Curae, Nulla ipsum dolor lacus, suscipit adipiscing. Cum sociis natoque penatibus et ultrices volutpat. Nullam wisi ultricies a, gravida vitae, dapibus risus ante sodales lectus blandit eu, tempor diam pede cursus vitae, ultricies eu, faucibus quis, porttitor eros cursus lectus, pellentesque eget, bibendum a, gravida ullamcorper quam. Nullam viverra consectetuer. Quisque cursus et, porttitor risus. Aliquam sem. In hendrerit nulla quam nunc, accumsan congue. Lorem ipsum primis in nibh vel risus. Sed vel lectus. Ut sagittis, ipsum dolor quam.</div>
<div id="spacer">
<div id="div2">div2</div>
</div>
</div>
</body>
Change to this:
$('#div2').css({
position: 'absolute',
top: $(window).scrollTop(),
left: left,
width: width
});
Instead of (previous):
$('#div2').css({
position: 'fixed',
left: left,
width: width
});

Scroll one sticky div over another

I have a div that sticks once scrolled to top of the container - similar to this fiddle I found and have hacked (I appreciate the code is not great but is for the purposes of showing my issue).
I would like the next div to scroll over the previous div, and also stick once it hits the same position. At the minute, I can only get the div to continue scrolling behind, or 'jump', like what it is doing now.
I wish to achieve a scrolling set of divs that each fix at the top of the container, one after the other, on top of one another, rather than continuing to scroll beyond - this is the only option I can come up with so far.
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#sticky-anchor').offset().top;
if (window_top > div_top) {
$('#sticky').addClass('stick');
$('#sticky-anchor').height($('#sticky').outerHeight());
} else {
$('#sticky').removeClass('stick');
$('#sticky-anchor').height(0);
}
}
$(function() {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#sticky-anchor').offset().top;
if (window_top > div_top) {
$('#sticky1').addClass('stick');
$('#sticky-anchor').height($('#sticky1').outerHeight());
} else {
$('#sticky1').removeClass('stick');
$('#sticky-anchor').height(0);
}
}
$(function() {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
#sticky,
#sticky1 {
padding: 0.5ex;
width: 400px;
background-color: #333;
color: #fff;
font-size: 2em;
border-radius: 0.5ex;
}
#sticky.stick {
margin-top: 0 !important;
position: fixed;
top: 0;
z-index: 1;
border-radius: 0 0 0.5em 0.5em;
}
#sticky1.stick {
margin-top: 0 !important;
position: fixed;
top: 0;
z-index: 2;
border-radius: 0 0 0.5em 0.5em;
}
body {
margin: 1em;
}
p {
margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sticky-anchor"></div>
<div id="sticky">This will stay at top of page</div>
<p>...</p>
<div id="sticky-anchor"></div>
<div id="sticky1">This should continue to scroll and stick on top
</div>
<p>...</p>
How about this? Should be at least a start.
https://jsfiddle.net/mqf7h5dz/
HTML:
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top;
$('.sticky').each(function() {
//$(this).find(".scrolling").width( width * imgLength * 1.2 );
div_top = $(this).offset().top;
console.log("Top for this div: ", div_top);
if (window_top > div_top) {
$(this).removeClass('sticky');
$(this).addClass('sticked');
//$(this).height($('.sticky').outerHeight());
$(this).clone().appendTo($('#sticky_container'));
}
});
}
$(function() {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
.sticky {
padding: 0.5ex;
width: 400px;
background-color: #333;
color: #fff;
font-size: 2em;
border-radius: 0.5ex;
}
.sticky-header {
padding: 0.5ex;
width: 400px;
background-color: #333;
color: #fff;
font-size: 2em;
border-radius: 0.5ex;
}
#sticky_container {
position: fixed;
top: 0;
}
.sticky.stick {
margin-top: 0 !important;
position: fixed;
top: 0;
z-index: 1;
border-radius: 0 0 0.5em 0.5em;
background: red;
}
body {
margin: 1em;
}
p {
margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sticky_container"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse scelerisque, lectus in pharetra blandit, augue mauris pulvinar erat, ut euismod nibh lectus sed diam. Nulla fringilla ultrices ligula. Aliquam vitae felis metus. Maecenas lacinia bibendum
accumsan. Curabitur lobortis convallis purus non imperdiet. Morbi ut vulputate mauris. Curabitur lacinia faucibus volutpat. Nulla elit tortor, rhoncus ut luctus eget, blandit in risus. Integer accumsan ullamcorper lorem id porttitor. Aliquam vitae
</p>
<div class="sticky-anchor"></div>
<div class="sticky sticky-header">This will stay at top of page</div>
<p>Nunc eu sapien turpis. Proin non arcu orci, eget volutpat tellus. Maecenas tempor mattis risus, quis pellentesque eros imperdiet nec. Vestibulum porttitor, justo at ornare bibendum, magna lectus cursus felis, tristique consectetur arcu justo at augue.
Mauris ultrices mollis sem eget elementum. Sed ipsum orci, tempus vel porttitor vel, tristique eu erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis aliquam pulvinar nisl, vitae congue velit ultricies
eget.
</p>
<p>Nunc eu sapien turpis. Proin non arcu orci, eget volutpat tellus. Maecenas tempor mattis risus, quis pellentesque eros imperdiet nec. Vestibulum porttitor, justo at ornare bibendum, magna lectus cursus felis, tristique consectetur arcu justo at augue.
Mauris ultrices mollis sem eget elementum. Sed ipsum orci, tempus vel porttitor vel, tristique eu erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis aliquam pulvinar nisl, vitae congue velit ultricies
eget.
</p>
<div class="sticky-anchor"></div>
<div class="sticky sticky-header">This should continue to scroll and stick on top
</div>
<p>
Phasellus malesuada euismod lectus nec bibendum. Ut adipiscing dapibus ipsum nec iaculis. Donec quis dignissim tortor. Suspendisse molestie rhoncus enim hendrerit ultricies. Proin semper purus posuere urna porttitor suscipit.</p>
<p>Curabitur odio dui, imperdiet sed sodales nec, aliquet id nisl. Mauris nec sapien nibh. Maecenas vel sem at felis posuere rutrum non non mauris. Maecenas at lectus ut ipsum iaculis lobortis. Vivamus ut porta nisi. Phasellus tempor accumsan urna eu faucibus.
Duis sed ligula neque, pulvinar euismod velit. Donec tristique eros at dolor ornare sagittis. Vestibulum sodales imperdiet ante et tincidunt. Suspendisse malesuada tempor nisi ac accumsan. Pellentesque accumsan pulvinar odio, id adipiscing diam mollis
eu. Nulla id mi rutrum elit rutrum ultrices. Maecenas viverra, est ut pellentesque ultricies, ligula nisi auctor tellus, vitae bibendum mi nunc non libero. Mauris in facilisis enim. Proin facilisis, risus et tempus accumsan, orci enim egestas arcu,
sit amet sodales risus leo quis nisi.</p>
<p>
Phasellus malesuada euismod lectus nec bibendum. Ut adipiscing dapibus ipsum nec iaculis. Donec quis dignissim tortor. Suspendisse molestie rhoncus enim hendrerit ultricies. Proin semper purus posuere urna porttitor suscipit.</p>
<p>Curabitur odio dui, imperdiet sed sodales nec, aliquet id nisl. Mauris nec sapien nibh. Maecenas vel sem at felis posuere rutrum non non mauris. Maecenas at lectus ut ipsum iaculis lobortis. Vivamus ut porta nisi. Phasellus tempor accumsan urna eu faucibus.
Duis sed ligula neque, pulvinar euismod velit. Donec tristique eros at dolor ornare sagittis. Vestibulum sodales imperdiet ante et tincidunt. Suspendisse malesuada tempor nisi ac accumsan. Pellentesque accumsan pulvinar odio, id adipiscing diam mollis
eu. Nulla id mi rutrum elit rutrum ultrices. Maecenas viverra, est ut pellentesque ultricies, ligula nisi auctor tellus, vitae bibendum mi nunc non libero. Mauris in facilisis enim. Proin facilisis, risus et tempus accumsan, orci enim egestas arcu,
sit amet sodales risus leo quis nisi.</p>
<p>
Phasellus malesuada euismod lectus nec bibendum. Ut adipiscing dapibus ipsum nec iaculis. Donec quis dignissim tortor. Suspendisse molestie rhoncus enim hendrerit ultricies. Proin semper purus posuere urna porttitor suscipit.</p>
<p>Curabitur odio dui, imperdiet sed sodales nec, aliquet id nisl. Mauris nec sapien nibh. Maecenas vel sem at felis posuere rutrum non non mauris. Maecenas at lectus ut ipsum iaculis lobortis. Vivamus ut porta nisi. Phasellus tempor accumsan urna eu faucibus.
Duis sed ligula neque, pulvinar euismod velit. Donec tristique eros at dolor ornare sagittis. Vestibulum sodales imperdiet ante et tincidunt. Suspendisse malesuada tempor nisi ac accumsan. Pellentesque accumsan pulvinar odio, id adipiscing diam mollis
eu. Nulla id mi rutrum elit rutrum ultrices. Maecenas viverra, est ut pellentesque ultricies, ligula nisi auctor tellus, vitae bibendum mi nunc non libero. Mauris in facilisis enim. Proin facilisis, risus et tempus accumsan, orci enim egestas arcu,
sit amet sodales risus leo quis nisi.</p>

Categories

Resources