SlideToggle triggered by onScroll jQuery - javascript

I'm getting stuck on two things here that I'd appreciate the help with.
Background:
The banner displays a photo and some information. However this is not supposed to be everpresent. The banner has to, but not all the information. So there is an option to collapse it and expand it with an icon (like an accordion).
Problems
Because the panel has to be fixed, I had to position relative the content below it. Problem is, when I collapse it, the content is still respecting the position given. I'd like that content to respect the distance between each other instead so that if there is 20px between them, that would still be true on a collapsed view. (I tried margin and top) but no cigar.
And my main issue which I have no idea how to get it done is, I'd like the banner to collapse automatically on scroll. I know there is a scroll function out there, I just never used it before.
Here is my HTML:
<div id="header" class="header navbar navbar-fixed-top navbar-inverse" data-current-theme="navbar-inverse">
<p>menu & logo</p>
</div>
<div class="row">
<div class="col-xs-12">
<div class="banner clearfix">
<div class="collapser">
<i class="fa fa-chevron-up fa-fw collapse-icon"></i>
</div>
<div class="banner-info clearfix">
<div class="col-sm-12 col-md-2">
<div class="circle-container">
<img class="img-responsive" src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTGjucaoN3fabOcumnr7RKTB3ICTJFLuLClnpiQUIR9oW4a11wb" alt="offender-img">
</div>
</div>
<div class="col-sm-12 col-md-10">
<div class="col-sm-12 col-md-3">
<div class="form-group">
<label class="control-label">Full Name</label>
<span>Floyd "Money" Mayweather</span>
</div>
<div class="form-group">
<label class="control-label">Some Label</label>
<span>Something Here</span>
</div>
</div>
<div class="col-sm-12 col-md-3">
<div class="form-group">
<label class="control-label">Offender ID#</label>
<span>123569863</span>
</div>
<div class="form-group">
<label class="control-label">Longer Label Example</label>
<span>Something Here with an ellipsis</span>
</div>
</div>
<div class="col-sm-12 col-md-3">
<div class="form-group">
<label class="control-label">Institution</label>
<span>Graterford</span>
</div>
<div class="form-group">
<label class="control-label">Some Link</label>
<span>Something Here</span>
</div>
</div>
<div class="col-sm-12 col-md-3">
<div class="form-group">
<label class="control-label">Institution</label>
<span>Graterford</span>
</div>
<div class="form-group">
<label class="control-label">Some Link</label>
<span href="#"><p>Something Here</p></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container martop65">
<div class="row">
<div class="col-xs-12">
<p>Lorem ipsum dolor sit amet, et meis definitiones cum, audire iisque alterum no ius. Semper luptatum democritum has no, at sea audire inermis suscipiantur. Ei regione adipiscing ius. An est nonumy habemus, movet probatus recusabo eu eum. Hinc offendit te est, at his falli euripidis.
<br><br>
Pertinax scribentur ullamcorper in nec, sit dolor fastidii ei. Cetero pericula iudicabit no est, tale elitr ad has, eos sumo harum interesset eu. His ne fierent appareat. Vel paulo fierent eleifend id. Pri ut conceptam repudiandae theophrastus, enim periculis ius ex, te est numquam inimicus.
<br><br>
Congue deleniti deseruisse te eos, usu no brute laoreet. Nisl lorem zril eu qui. Vix tempor inimicus an, partem minimum cotidieque mel eu. Aperiam discere an mea, ea graecis scribentur mel, minim ludus saperet no vix. Has at sint sanctus. Eu docendi hendrerit liberavisse mel, ut eum viris voluptaria, eum error voluptua principes ex.
<br><br>
Vis te accumsan lucilius platonem. Possit prodesset eum in. No duo agam nullam detracto. At homero scaevola electram vel.</p>
</div>
</div>
</div>
CSS
body {
background-color: #dddddd;
}
.navbar {
border: none;
border-bottom: 2px solid #30373e;
font-size: 14px;
-webkit-box-shadow: 0 1px rgba(0,0,0,0.025);
box-shadow: 0 1px rgba(0,0,0,0.025);
z-index: 1040;
margin-bottom: 0;
height: 55px;
text-align:center;
color:#ccc;
}
.banner {
border: none;
-webkit-box-shadow: 0 2px 0 rgba(0,0,0,0.07);
box-shadow: 0 2px 0 rgba(0,0,0,0.07);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
border-radius: 5px;
margin-bottom: 20px;
position: fixed;
width: 100%;
background: #101113;
padding: 20px;
display: block;
top: 55px;
border-radius:0;
z-index: 1;
}
.banner .collapser {
position: absolute;
bottom: 10px;
color: #bbb;
}
.banner .circle-container {
position: relative;
left: 35px;
text-align: center;
width: 110px;
height: 110px;
display: flex;
overflow: hidden;
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
-ms-border-radius: 100%;
border-radius: 100%;
border: 3px solid #bbb;
}
.banner .banner-info label {
color: rgba(248,151,29,0.77);
}
.banner .banner-info span {
display: block;
color: #bbb;
white-space: nowrap;
width: 85%;
overflow: hidden;
text-overflow: ellipsis;
}
.martop65 {
/* margin-top: 240px;*/
position:relative;
top:240px;
}
JQUERY
$('.collapser').click(function() {
$collapser = $(this);
$banner = $collapser.parent().find('.banner-info .circle-container').add($collapser.parent().find(".col-md-10 > .col-md-3 > .form-group:nth-of-type(2)"));
$banner.slideToggle(500, function() {
$collapser.find('.collapse-icon').toggleClass('fa-chevron-up fa-chevron-down');
});
});
Here is a CODEPEN
Thanks!

Related

Fade out one section and fade in the next section as you scroll on webpage

I have a site and I want each section to take up the screen and as you scroll down the page the sections fade out as the next section comes into view. I'm struggling on how this math needs to work.
For one section it's easy which is basically the height of the element and it's distance from the top to get the opacity percentage. However, I just can't quite figure out the math for other sections. I need section 2 to start fading in as section 1 is fading out.
I do not want to scrolljack. I just want a scrolling effect. Rather than override default scrolling behavior I just want to animate in/out as you scroll where a certain Y scroll value = a certain CSS value rather than a sort of "breakpoint" where it animates to a new "slide".
For the proper effect, for example, my math divides the height of the row by 2 so that it's 50% faded out as the next section should be fading in 50%. But, as of now, the math just doesn't work for the other sections.
This site is using vanilla JS as it's supposed to be a simple one pager.
Example below:
(function () {
window.addEventListener('scroll', () => {
const rows = document.querySelectorAll('.row');
rows.forEach(function (row, index) {
const distanceToTop = window.pageYOffset;
const elementHeight = row.offsetHeight * (index + 1) / 2;
row.style.opacity = ((elementHeight - distanceToTop) / elementHeight * 100) / 100;
});
});
})();
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0 0 0 0;
font-family: sans-serif;
font-family: 'Manrope', helvetiva, sans-serif;
transition: background-color 1s;
color:#fff;
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
}
header {
position: fixed;
top: 0;
width: 100%;
background: #fff;
z-index: 999;
}
header h1 {
font-family: 'Lack';
font-size: 4em;
text-align: center;
padding: 10px;
color: #100521;
}
.row-container .row:first-child {
opacity: 1;
}
.row {
opacity: 0;
height: 100vh;
display: flex;
flex-direction:column;
}
.row-inner {
display: grid;
grid-template-columns: 1fr 1fr;
position: sticky;
top: 0;
/* border: 1px solid yellow; */
padding: 0;
height: 100vh;
}
.column {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
flex: 50%;
padding: 10px;
}
.left-column {
background-color: transparent;
}
.right-column {
background-color: transparent;
}
h1 {
font-family: 'Unbounded', helvetica, sans-serif;
}
h1 {
margin: 0;
font-size: 36px;
}
h2 {
margin: 0;
font-size: 24px;
}
p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
img {
width: 100%;
height: auto;
}
<!DOCTYPE html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Manrope&family=Unbounded&family=Lack&display=swap" rel="stylesheet">
</head>
<body>
<header>
<h1>My App</h1>
</header>
<!-- First row -->
<div class="row-container">
<div class="row section-1">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 1</h1>
<h2>Subhead 1</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
<!-- Second row -->
<div class="row section-2">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 2</h1>
<h2>Subhead 2</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 2">
</div>
</div>
</div>
</div>
<!-- Third row -->
<div class="row section-3">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 3</h1>
<h2>Subhead 3</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 3">
</div>
</div>
</div>
</div>
<!-- Fourth row -->
<div class="row section-4">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 4</h1>
<h2>Subhead 4</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-4.jpg" alt="Image 4">
</div>
</div>
</div>
</div>
</div>
</body>
</html>
As suggested in one of the comments to your question, it's more effective to use IntersectionObserver rather than the 'scroll' event listener.
If I'm correct, this snippet should help you achieve what you're looking for:
window.addEventListener("load", (event) => {
let options = {
rootMargin: "0px",
threshold: 0.8
};
const intersectionHandler = function(entries, observer) {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.intersectionRatio > 0.8) {
entry.target.classList.remove("fadeOut");
entry.target.classList.add("fadeIn");
} else {
entry.target.classList.remove("fadeIn");
entry.target.classList.add("fadeOut");
}
});
};
let observer = new IntersectionObserver(intersectionHandler, options);
document.querySelectorAll(".section").forEach((row, index) => {
observer.observe(row);
});
});
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0 0 0 0;
font-family: sans-serif;
font-family: "Manrope", helvetiva, sans-serif;
transition: background-color 1s;
color: #fff;
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
}
header {
position: fixed;
top: 0;
width: 100%;
background: #fff;
z-index: 999;
}
header h1 {
font-family: "Lack";
font-size: 4em;
text-align: center;
padding: 10px;
color: #100521;
}
.row-container .row:first-child {
opacity: 1;
}
.row {
opacity: 0;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.row-inner {
display: grid;
grid-template-columns: 1fr 1fr;
position: sticky;
top: 0;
/* border: 1px solid yellow; */
padding: 0;
height: 100vh;
}
.column {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
flex: 50%;
padding: 10px;
height: 100vh;
box-sizing: border-box;
}
.left-column {
background-color: transparent;
}
.right-column {
background-color: transparent;
}
h1 {
font-family: "Unbounded", helvetica, sans-serif;
}
h1 {
margin: 0;
font-size: 36px;
}
h2 {
margin: 0;
font-size: 24px;
}
p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
img {
width: 100%;
height: auto;
}
.fadeIn {
animation-name: fadeIn;
animation-duration: 1s;
animation-fill-mode: forwards;
}
.fadeOut {
animation-name: fadeOut;
animation-duration: .5s;
animation-fill-mode: forwards;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<!-- First row -->
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 1</h1>
<h2>Subhead 1</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
<!-- Second row -->
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 2</h1>
<h2>Subhead 2</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 2">
</div>
</div>
</div>
</div>
<!-- Third row -->
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 3</h1>
<h2>Subhead 3</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 3">
</div>
</div>
</div>
</div>
<!-- Fourth row -->
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline 4</h1>
<h2>Subhead 4</h2>
<p>Lorem Ipsum dolar Gamet</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-4.jpg" alt="Image 4">
</div>
</div>
</div>
</div>
</div>
You'll notice I've made some minor modifications to your HTML and CSS, but the magic happens in the Javascript.
I've also used the window "load" event listener to create the observer options, object and callback function when the page is loaded.
You can check the IntersectionObserver API docs for more details on how it works and how to tweak the options or the callback to suit your needs.
Let me know if you have any questions for modifying my code. (I've also had to change your css a bit - the content of the row element was higher than the row element itself what led to some weird issues.)
I have rewritten most of it and it should now work for large row heights. The math for it is just a quadratic formula (Opacity of offset from center of the screen) with it's roots at the height of the row and a maximum at 0 offset with a value of 1.
/** #format */
const calculateOpacity = () => {
const ROW_CONTAINER = document.querySelector(".row-container");
const rows = ROW_CONTAINER.children;
const rowContainerBBox = ROW_CONTAINER.getBoundingClientRect();
console.log("calc")
for (const row of rows) {
const rowBBox = row.getBoundingClientRect();
const top = rowBBox.top - rowContainerBBox.top;
const bottom = rowBBox.bottom - rowContainerBBox.bottom;
if (rowBBox.height > rowContainerBBox.height) {
const opacityOfOffset = (offset) => {
const a = -1 / Math.pow(rowBBox.height, 2);
return Math.max(0, a * Math.pow(offset, 2) + 1);
};
row.style.opacity = opacityOfOffset(top + bottom);
continue;
}
const unvisibleHeightTop = -Math.min(0, top);
const unvisibleHeightBottom = Math.max(0, bottom);
const visibleHeight = rowBBox.height - unvisibleHeightTop - unvisibleHeightBottom;
row.style.opacity = visibleHeight / rowBBox.height;
}
};
document.querySelector(".row-container").addEventListener("scroll", calculateOpacity);
/** #format */
body {
height: 100%;
margin: 0;
padding: 0;
font-family: sans-serif;
font-family: "Manrope", helvetiva, sans-serif;
color: #fff;
}
header {
height: max(70px, 10vh);
position: fixed;
background-color: black;
width: 100%;
display: flex;
align-items: center;
}
header h1 {
margin: 0;
}
main {
padding-top: max(70px, 10vh);
height: 100%;
box-sizing: border-box;
}
.row-container {
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
height: calc(100vh - max(70px, 10vh));
overflow-y: auto;
}
.row {
height: 150vh;
display: flex;
align-items: center;
padding: 10vh 0;
}
.row .row-inner {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 1fr 1fr;
}
.row .row-inner .col {
margin-inline: 10px;
display: flex;
align-items: center;
height: 100%;
}
.row img {
width: 100%;
height: auto;
}
.row h2 {
margin: 0;
font-family: "Unbounded", helvetica, sans-serif;
font-size: 36px;
}
.row h3 {
margin: 0;
font-size: 24px;
}
.row p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
<!-- #format -->
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Manrope&family=Unbounded&family=Lack&display=swap" rel="stylesheet" />
</head>
<body>
<header>
<h1>My App</h1>
</header>
<main>
<div class="row-container">
<div class="row row-1">
<div class="row-inner">
<div class="col left">
<div class="col-inner">
<h2>Headline 1</h2>
<h3>Subhead 1</h3>
<p>Lorem ipsum dolor sit</p>
</div>
</div>
<div class="col right">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1" />
</div>
</div>
</div>
<div class="row row-1">
<div class="row-inner">
<div class="col left">
<div class="col-inner">
<h2>Headline 1</h2>
<h3>Subhead 1</h3>
<p>Lorem ipsum dolor sit</p>
</div>
</div>
<div class="col right">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1" />
</div>
</div>
</div>
<div class="row row-1">
<div class="row-inner">
<div class="col left">
<div class="col-inner">
<h2>Headline 1</h2>
<h3>Subhead 1</h3>
<p>Lorem ipsum dolor sit</p>
</div>
</div>
<div class="col right">
<img src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1" />
</div>
</div>
</div>
</div>
</main>
</body>
</html>
You didn't really ask for a web component, I just got carried away. This is a fun challenge! Anyway, here's a version that is NOT a web component. I also realized that I missed all the css that you provided. So I added that as well. I'm not sure if tweaking the css a little is verbotten ... but I did it. I also added a single [section] tag, which wraps everything but the app header, to make it more bullet proof ... Please let me know if I need to use your code exactly as you posted it.
I had a lot of trouble finding settings that provide a dramatic enough effect on both large screens and phones without some ugly hacks, so I opted for a compromise. You can optimize for either large or small by changing the rootMargin option for the IntersectionObserver. Smaller values make the fade effect more dramatic, but values that are too small cause the content to look washed out on smaller devices. As I'm posting this, rootMargin is set to "-25px". Apparantly you can use negative values, but as far as I can tell, you can only use "px" as the measurement. Other measurements don't seem to work.
Sooooo...
I used IntersectionObserver
const observer = new IntersectionObserver(fadeInOut, options);
One of the options IntersectionObserver takes is something called "threshold". I don't totally understand it, but MDN suggested that if you want to poll the viewport to determine element visibility, you should set the value of "threshold" as an array with many numbers ranging from 0 to 1. The example provided a function that generates 20 of them, so that's what I used.
function buildThresholds() {
const steps = 20;
const thresholds = [];
for (let i = 0; i <= steps; i++) {
let ratio = i/steps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
Then I grabbed the collection of elements to watch using querySelectorAll(".row-container").
Then I looped through the elements and added each one to the observer's watch list.
observer.observe(elem);
Then, in the callback you provide when you create a new instance of IntersectionObserver, I set each element's opacity to the the intersectionRatio, which is a property provided by the instance of the IntersectionObserverEntry which is passed to the callback.
function fadeInOut(items, observer) {
items.forEach( (item) => {
item.target.style.opacity = item.intersectionRatio;
});
}
function buildThresholds() {
const steps = 20;
const thresholds = [];
for (let i = 0; i <= steps; i++) {
let ratio = i/steps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
function fadeInOut(items, observer) {
items.forEach( (item) => {
item.target.style.opacity = item.intersectionRatio;
});
}
function scrollFade() {
const elems = document.querySelectorAll('.row-container');
const options = {
root: null,
rootMargin: "-25px",
threshold: buildThresholds()
};
const observer = new IntersectionObserver(fadeInOut, options);
for (let elem of elems) {
observer.observe(elem);
}
}
document.addEventListener('DOMContentLoaded', scrollFade);
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0 0 0 0;
font-family: sans-serif;
font-family: 'Manrope', helvetiva, sans-serif;
transition: background-color 1s;
color:#fff;
background: linear-gradient(0deg, #100521 0%, #50357c 50%, #878290 100%);
}
header {
position: fixed;
top: 0;
width: 100%;
background: #fff;
z-index: 999;
}
header h1 {
font-family: 'Lack';
font-size: 4em;
text-align: center;
padding: 10px;
color: #100521;
}
section {
margin-top: 6em;
}
h1 {
font-family: 'Unbounded', helvetica, sans-serif;
}
h1 {
margin: 0;
font-size: 36px;
}
h2 {
margin: 0;
font-size: 24px;
}
p {
margin: 10px 0;
font-size: 18px;
line-height: 1.5;
}
img {
width: 100%;
height: auto;
}
.row-container {
background-color: rgb(16, 5, 33);
min-height: 50vh;
}
.row-inner {
align-content: center;
align-items: center;
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
padding: 10px;
gap: 10px;
}
.left-column {
flex: 1 1 70vw;
}
.right-column {
flex: 1 1 100px;
text-align: center;
}
<header>
<h1>My App</h1>
</header>
<section>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline One</h1>
<h2>Subhead One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Two</h1>
<h2>Subhead Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Three</h1>
<h2>Subhead Three</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Four</h1>
<h2>Subhead Four</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-4.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Five</h1>
<h2>Subhead Five</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-5.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<h1>Headline Six</h1>
<h2>Subhead Six</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-6.jpg" alt="Image 1">
</div>
</div>
</div>
</div>
</div>
</section>
Will this work? I used IntersectionObserver and set the opacity of the sections based on the intersection ratio of each section with the viewport. I pretty much took the idea straight from MDN.
MDN Intersection Observer API
class ScrollFade extends HTMLElement {
template;
shadow;
static observer = false;
constructor() {
super();
this.shadow = this.attachShadow({mode: 'open'});
if (!ScrollFade.observer) {
const buildThresholds = function() {
const steps = 20;
const thresholds = [];
for (let i = 0; i <= steps; i++) {
let ratio = i/steps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
const options = {
root: null,
rootMargin: "0px",
threshold: buildThresholds()
};
ScrollFade.observer = new IntersectionObserver(ScrollFade.fadeInOut, options);
}
}
connectedCallback() {
const tmpl = document.querySelector('#scroll-fade-template').cloneNode(true);
const template = tmpl.content;
ScrollFade.observer.observe(this.shadow.host);
this.shadow.append(template);
}
disconnectedCallback() {
ScrollFade.observer.unobserve(this.shadow.host);
}
static fadeInOut(items, observer) {
items.forEach( (item) => {
item.target.style.opacity = item.intersectionRatio;
});
}
}
document.addEventListener('DOMContentLoaded', customElements.define('scroll-fade', ScrollFade));
body { margin: 0 }
img { width: 100%; }
<scroll-fade>
<h1 slot="headline">Headline One</h1>
<h2 slot="subhead">Subhead One</h2>
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-1.jpg" alt="Image 1">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip </p>
</div>
</scroll-fade>
<scroll-fade>
<h1 slot="headline">Headline Two</h1>
<h2 slot="subhead">Subhead Two</h2>
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-2.jpg" alt="Image 2">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip </p>
</div>
</scroll-fade>
<scroll-fade>
<h1 slot="headline">Headline Three</h1>
<h2 slot="subhead">Subhead Three</h2>
<img slot="avatar" src="https://avatars.dicebear.com/api/adventurer/team-member-3.jpg" alt="Image 1">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip </p>
</div>
</scroll-fade>
<template id="scroll-fade-template">
<style>
.row-container {
background-color: seagreen;
height: 100vh;
overflow: auto;
}
.row-inner {
align-content: center;
display: flex;
flex-direction: row;
flex-wrap: wrap-reverse;
padding: 10px;
gap: 10px;
}
.left-column {
flex: 1 1 70vw;
}
.right-column {
flex: 1 1 100px;
text-align: center;
}
</style>
<div class="row-container">
<div class="row section">
<div class="row-inner">
<div class="column left-column">
<div class="column-inner">
<slot name="headline">Need Headline</slot>
<slot name="subhead">Need Subhead</slot>
<slot>Need Content</slot>
</div>
</div>
<div class="column right-column">
<div class="column-inner">
<slot name="avatar">Need Avatar</slot>
</div>
</div>
</div>
</div>
</div>
</template>

Why are the <div> borders bleeding through the <ul>?

I've recently gotten back into coding, and continuing off where I left, trying to create a mobile-first site for a hypothetical apartment website.
With that being said, I've noticed that bottom border of a different , with the class ".description_section", is visible through the one containing the element.
The is within the tag with the id "sidebar". Not the most aesthecally-pleasing side nav (as fonts is my weak point).
Picture
HTML:
<div class="container">
<div id="sidebar">
<ul>
<li>Home</li>
<li>Amenities</li>
<li>Floor Plans</li>
<li>About Us</li>
</ul>
</div><!--close #sidebar-->
<div class="row" id="big_picture">
<div class="row" id="social_media">
<div class="col-4" id="facebook">
<img src="images/fb.svg">
</div><!-- close .social_media_icon-->
<div class="col-4" id="twitter">
<img src="images/twitter.svg">
</div><!-- close .social_media_icon-->
<div class="col-4" id="google_plus">
<img src="images/google_plus.svg">
</div><!-- close .social_media_icon-->
</div><!--close #social_media-->
</div><!--close #big_picture-->
<div class="row description_section">
<hr>
<h2>Directions</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consectetur tristique tortor feugiat dictum. Duis placerat orci vel massa interdum dapibus eu id risus. Curabitur tempor placerat congue. Curabitur ut augue sit amet arcu volutpat rutrum ut sit amet turpis.</p>
<div class="desc_image" id="one"></div><!--close .desc_image-->
</div><!--.description_section-->
CSS:
#sidebar {
left: 0px;
width: 50%;
border-top-right-radius: 1.5em;
border-bottom-right-radius: 1.5em;
background-color: black;
color: white;
/*border: 1px solid white;*/
text-align: center;
position: absolute;
display: none;
}
#big_picture {
height: 13.4em;
background: url("../images/apt_lobby.jpg");
background-size: cover;
background-repeat: no-repeat;
}
.description_section {
background-color: #1d2f5c;
color: white;
}
.description_section h2 {
padding-top: 0;
padding-bottom: 2%;
text-align: center;
font-style: bold;
}
.description_section p {
font-size: 0.8em;
padding: 1% 5% 5% 5%;
}
jQuery:
$("#hamburger_menu").click(function() {
$("#sidebar").toggle(1000);
});
If people would like more code snippets, including the one with id of the whose borders is bleeding through, please let me know!
My guess is that it's because of the
position: absolute
Try playing around with this and also height of the sidebar.
try to make the ul higher z-index
ul {
position: absolute;
z-index:9;
}

Fill HTML elements with JSON

I am trying to figure out the best way to JSONify a set of repeated HTML that I have with me.
I have the following piece of code that gets repeated for "n" number of times.
<article class="style2">
<div class="row">
<div class="col-md-6 col-sm-6">
<a href="http://www.google.com">
<div class="article-thumb">
<img src="https://place-hold.it/370x231/5" class="img-responsive" alt=""/>
</div>
</a>
</div>
<div class="col-md-6 col-sm-6">
<div class="post-excerpt">
<h3>This is my first article</h3>
<div class="meta">
<span>by Benjamin K.</span>
<span>on Sep 23, 2016</span>
<span class="comment"><i class="fa fa-comment-o"></i> 1</span>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco</p>
Read More
</div>
</div>
</div>
</article>
I want to create a template, something like this (suggestions welcome)
<article class="style2">
<div class="row">
<div class="col-md-6 col-sm-6">
<a href="">
<div class="article-thumb">
<img src="" class="img-responsive" alt=""/>
</div>
</a>
</div>
<div class="col-md-6 col-sm-6">
<div class="post-excerpt">
<h3></h3>
<div class="meta">
<span>by </span>
<span></span>
<span class="comment"><i class="fa fa-comment-o"></i> </span>
</div>
<p></p>
Read More
</div>
</div>
</div>
</article>
and then dynamically generate this element based on a JSON file. The contents of the JSON will be similar to the following:
url = http://www.google.com
image = https://place-hold.it/370x231/5
title = This is my first article
author = Benjamin K.
date = Sep 23, 2016
abstract = Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
comments = 1
CodePen https://codepen.io/iwant2learn/pen/PEmBMN
Thanks in advance for any help!
If your "template" really is fixed (no variants) and quite simple as what you posted... The .clone() method may be an interest for you.
Yes... As mentionned in comments, there is templating libs that exist. You should also look. But a simple way to do it by yourself, using just one jQuery method, is to give each of your template "field" a class.
Then populate a clone of your template with the jsons you have and append it to the document.
Notice the ".template" class I added in your CSS to hide the template.
var myJSONarray = [
{
url : "http://www.google.com",
image : "https://place-hold.it/370x231/5",
title : "This is my first article",
author : "Benjamin K.",
date : "Sep 23, 2016",
abstract : "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco",
comments : 1
},{
url : "https://learn.jquery.com/",
image : "http://www.desartlab.com/wp-content/uploads/2015/10/jquery_logo.gif",
title : "This is my first script!!!",
author : "J. Q. Harry",
date : "Dec 31, 2017",
abstract : "You can do what you want, if you are a bit creative, my friend.",
comments : 172
}
];
$(document).ready(function(){
for(i=0;i<myJSONarray.length;i++){
var clone = $(".template").clone();
clone.find(".template-url").attr("href",myJSONarray[i].url);
clone.find(".template-title").find("a").html(myJSONarray[i].title);
clone.find(".template-image").attr("src",myJSONarray[i].image);
clone.find(".template-author").html(myJSONarray[i].author);
clone.find(".template-date").html(myJSONarray[i].date);
clone.find(".template-abstract").html(myJSONarray[i].abstract);
clone.find(".template-comment").html('<i class="fa fa-comment-o"></i> '+myJSONarray[i].comments);
clone.removeClass("template");
$(".template-spot").append(clone);
}
});
.template{
display:none;
}
.wrapper {
position: relative;
width: 100%;
overflow: hidden;
}
.inner-content {
padding: 50px 0 57px;
}
.container {
max-width: 700px;
width: 100%;
margin: 0 auto;
}
.section-head {
margin-bottom: 22px;
}
.section-head h2 {
font-weight: 300;
}
article.style2 {
padding-bottom: 30px;
margin-bottom: 30px;
}
article {
border-bottom: 1px solid #eeeeee;
padding-bottom: 15px;
margin-bottom: 30px;
}
article .article-thumb {
position: relative;
overflow: hidden;
background: #fff;
}
article:hover .article-thumb {
background: #000;
}
article .article-thumb img {
width: 100%;
}
article .article-thumb img {
}
article .article-thumb:hover img {
}
article .post-excerpt {
padding: 9px 0;
}
article .meta {
margin-top: 2px;
}
.meta span {
font-size: 14px;
color: #787878;
}
a.link:hover, a {
color: #333;
}
a.link, a:hover {
color: #33ccff;
}
.small-title {
font-size: 10px;
letter-spacing: 0.10em;
font-weight: bold;
line-height: 18px;
color: #333333;
margin-bottom: 5px;
text-transform: uppercase;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="inner-content">
<div class="container">
<div class="section-head">
<h2>Latest Bits</h2>
</div>
<div class="row">
<div class="col-md-8 template-spot">
<article class="style2 template">
<div class="row">
<div class="col-md-6 col-sm-6">
<a href="http://www.google.com" class="template-url">
<div class="article-thumb">
<img src="https://place-hold.it/370x231/5" class="img-responsive template-image" alt=""/>
</div>
</a>
</div>
<div class="col-md-6 col-sm-6">
<div class="post-excerpt">
<h3 class="template-title">This is my first article</h3>
<div class="meta">
<span>by Benjamin K.</span>
<span class="template-date">on Sep 23, 2016</span>
<span class="comment template-comment"><i class="fa fa-comment-o"></i> 1</span>
</div>
<p class="template-abstract">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco</p>
Read More
</div>
</div>
</div>
</article>
</div>
</div>
</div>
</div>
</div>
CodePen (Updated with an infinite scroll)
var myJSONArray = [{
url: "http://www.google.com",
image: "https://place-hold.it/370x231/5",
title: "This is my first article",
author: "Benjamin K.",
date: "Sep 23, 2016",
abstract: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco",
comments: 1
}, {
url: "https://learn.jquery.com/",
image: "http://www.desartlab.com/wp-content/uploads/2015/10/jquery_logo.gif",
title: "This is my first script!!!",
author: "J. Q. Harry",
date: "Dec 31, 2017",
abstract: "You can do what you want, if you are a bit creative, my friend.",
comments: 172
}];
$(document).ready(function() {
for (const val of myJSONArray) {
var clone = $(".template").clone();
clone.find(".template-url").attr("href", val.url);
clone.find(".template-title").find("a").html(val.title);
clone.find(".template-image").attr("src", val.image);
clone.find(".template-author").html(val.author);
clone.find(".template-date").html(val.date);
clone.find(".template-abstract").html(val.abstract);
clone.find(".template-comment").html(`<i class="fa fa-comment-o"></i> ${val.comments}`);
clone.removeClass("template");
$(".template-spot").append(clone);
}
});
.template {
display: none;
}
.wrapper {
position: relative;
width: 100%;
overflow: hidden;
}
.inner-content {
padding: 50px 0 57px;
}
.container {
max-width: 700px;
width: 100%;
margin: 0 auto;
}
.section-head {
margin-bottom: 22px;
}
.section-head h2 {
font-weight: 300;
}
article.style2 {
padding-bottom: 30px;
margin-bottom: 30px;
}
article {
border-bottom: 1px solid #eeeeee;
padding-bottom: 15px;
margin-bottom: 30px;
}
article .article-thumb {
position: relative;
overflow: hidden;
background: #fff;
}
article:hover .article-thumb {
background: #000;
}
article .article-thumb img {
width: 100%;
}
article .article-thumb img {}
article .article-thumb:hover img {}
article .post-excerpt {
padding: 9px 0;
}
article .meta {
margin-top: 2px;
}
.meta span {
font-size: 14px;
color: #787878;
}
a.link:hover,
a {
color: #333;
}
a.link,
a:hover {
color: #33ccff;
}
.small-title {
font-size: 10px;
letter-spacing: 0.10em;
font-weight: bold;
line-height: 18px;
color: #333333;
margin-bottom: 5px;
text-transform: uppercase;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="inner-content">
<div class="container">
<div class="section-head">
<h2>Latest Bits</h2>
</div>
<div class="row">
<div class="col-md-8 template-spot">
<article class="style2 template">
<div class="row">
<div class="col-md-6 col-sm-6">
<a href="http://www.google.com" class="template-url">
<div class="article-thumb">
<img src="https://place-hold.it/370x231/5" class="img-responsive template-image" alt="" />
</div>
</a>
</div>
<div class="col-md-6 col-sm-6">
<div class="post-excerpt">
<h3 class="template-title">This is my first article</h3>
<div class="meta">
<span>by Benjamin K.</span>
<span class="template-date">on Sep 23, 2016</span>
<span class="comment template-comment"><i class="fa fa-comment-o"></i> 1</span>
</div>
<p class="template-abstract">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco</p>
Read More
</div>
</div>
</div>
</article>
</div>
</div>
Same as what Louys did but used for..of loop as it's cleaner.

Make it possible for a jQuery appended label to toggle a checkbox

I have a list with the following markup:
<div class="container">
<div class="element">
<input type="checkbox" id="checkbox1" class="toggler">
<label for="checkbox1">Toggle +</label>
<div class="more-info">
<p>...</p>
</div>
</div>
<div class="element">
...
</div>
</div>
The purpuse is to use pure CSS to make the toggle function, so I use this to hide/show the <div class="more-info">...</div>:
.more-info {
max-height: 0;
opacity: 0;
overflow: hidden;
transition: all .3s ease;
}
.toggler:checked ~ .more-info {
max-height: 200px;
opacity: 0;
overflow: hidden;
}
Under the container, I have a button that will get (in this case it is static) element and append to the container. And this is where I have my problem, the label in the new element won't toggle the checkbox. If I make the checkbox visible and check it directly it works.
I have also made a codepen to illustrate my problem.
Thanks in advance :)
You have two issues in your code. Firstly there's a $a() which should be just $(). You're also setting the class of the appended checkbox to chekcbox instead of checkbox. Try this:
$(document).ready(function() {
var i = 1;
$('#more').click(function(e) {
e.preventDefault();
var element, checkbox, label, moreInfo, dummyText;
i++
dummyText = $('<p />').text('Similique dis egestas aptent exercitationem sequi urna, nonummy laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil. Similique dis egestas aptent exercitationem sequi urna, nonummy laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil.');
checkbox = $('<input />', {
id: 'checkbox' + i,
class: 'toggler',
type: 'checkbox'
});
label = $('<label />', {
for: 'checkbox' + i,
text: 'Toggle +'
});
moreInfo = $('<div />', {
class: 'more-info',
html: dummyText
});
element = $('<div />', {
class: 'element'
}).append(checkbox, label, moreInfo);
$('.container').append(element);
})
});
body {
margin: 0;
font-family: sans-serif;
font-size: 18px;
}
.container {
display: block;
margin: 50px auto;
width: 500px;
padding: 30px;
background-color: #ededed;
}
label {
display: block;
margin-bottom: 5px;
font-size: 24px;
font-weight: 700;
cursor: pointer;
}
.toggler {
display: none;
}
.more-info {
margin-bottom: 20px;
padding-bottom: 20px;
width: 100%;
max-height: 0;
overflow: hidden;
opacity: 0;
border-bottom: solid 1px #ababab;
transition: all .3s ease;
}
.more-info>p {
margin: 0;
}
.toggler:checked~.more-info {
max-height: 200px;
opacity: 1;
}
#more {
display: block;
margin: 30px auto 0;
padding: 10px 0;
width: 120px;
text-align: center;
color: #3498db;
border: solid 2px #3498db;
border-radius: 22px;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="container">
<div class="element">
<input id="checkbox1" class="toggler" type="checkbox">
<label for="checkbox1">Toggle +</label>
<div class="more-info">
<p>Similique dis egestas aptent exercitationem sequi urna, nonummy laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil. Similique dis egestas aptent exercitationem sequi urna, nonummy
laudantium, cillum pulvinar sociis assumenda? Minus nostra atque minima duis expedita ab irure sequi lectus natoque? Nihil.</p>
</div>
</div>
</div>
Get more

How to make top and bottom of div transparent

I am making a div with a content longer than what I want to view in height, so I used a height of 20em, and made overflow:scroll. This work great, but I want to add some effect to it.
How can I do so the top and bottom 50px have a opacity of 0.7? so it gets a effect when the content is scrolled "away".
Thanks!
<div>
<ul>
<li>long list here</li>
<li>long list here</li>
<li>long list here</li>
<li>long list here</li>
</ul>
Style:
height:25em;
overflow:scroll;
DEMO
DEMO:
#wrapper {
position: relative;
}
#wrapper:before, #wrapper:after {
content: '';
position: absolute;
left: 0;
right: 0;
height: 30px; /* Height of the effect */
}
#wrapper:before {
top: 0;
/* Use your background color, assuming white: */
background-image: linear-gradient(to bottom, rgba(255,255,255,1), rgba(255,255,255,0));
}
#wrapper:after {
bottom: 0;
/* Use your background color, assuming white: */
background-image: linear-gradient(to top, rgba(255,255,255,1), rgba(255,255,255,0));
}
#mydiv {
background: red;
height: 20em;
overflow: auto;
border: 0 solid transparent;
border-width: 10px 0; /* 10px to be able to read first and last lines */
}
<div id="wrapper">
<div id="mydiv">
Your content
</div>
</div>
You can add two layers at top and bottom, note it will cover your content so I suggest it takes no more than 20px. Here is an example with transparent covers, but you can use nice PNG gradient instead:
.fixed_height {
position: relative;
}
.fixed_height_content {
padding: 20px 0;
height: 100px;
overflow-y: scroll;
}
.cover_top {
position: absolute;
left: 0;
top: 0;
right: 0;
height: 20px;
background: red;
opacity: .3;
}
.cover_bottom {
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 20px;
background: red;
opacity: .3;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Opacity</title>
<style type="text/css">
</style>
</head>
<body>
<div class="fixed_height">
<div class="fixed_height_content">
<p>Some content<br />more<br />more<br />more<br />more</p>
<p>Some content<br />more<br />more<br />more<br />more</p>
<p>Some content<br />more<br />more<br />more<br />more</p>
<p>Some content<br />more<br />more<br />more<br />more</p>
</div>
<div class="cover_top"></div>
<div class="cover_bottom"></div>
</div>
</body>
</html>
I think you may like this. Try this one.
<style>
#boxBorder {
height: 3em;
overflow: hidden;
}
#boxBorder:hover {
height: 5em;
overflow: hidden;
}
#boxBorder:after {
content: '';
position: absolute;
left: 0;
right: 0;
height: 100px;
bottom: 0;
background-image: linear-gradient(to top, rgba(255,255,255,1), rgba(256,256,256,0));
}
</style>
and my div is like
<div id="boxBorder">
Vis meis ipsum cu, est ad modus facilis, ut est modus alienum consulatu. Mel ut primis dissentias. Doming omittam necessitatibus eam ei, simul vocibus complectitur at eam. Aliquid dolorem laboramus pri et. Porro utroque facilis ex has, pro eripuit ullamcorper te, an audiam civibus voluptaria mei.
Consul iuvaret te eam. Eu usu modus nonumy nostrud, his ne facilis maiestatis. Nec clita nonumes ea, solet noluisse vix cu. Te vel altera verterem sapientem, quo corrumpit theophrastus ne.
Quo iusto exerci assentior cu, ius erat velit timeam ea. Te modo offendit consectetuer has, id ius utamur quaerendum. Ut choro neglegentur nec, ea iusto feugait est. Feugait reprimique mel id, mel ad indoctum definitionem, nostrum apeirian ad pro.
an discere delenit.

Categories

Resources