JSFiddle - React, Tailwind, and code Playground
HTML
<body>
<h1>SCROLL HERE<h1>
<div id="midline"></div>
<ul>
<li class="event" id="el1"></li>
<li class="event" id="el2"></li>
<li class="event" id="el3"></li>
<li class="event" id="el4"></li>
<li class="event" id="el5"></li>
<li class="event" id="el6"></li>
<li class="event" id="el7"></li>
<li class="event" id="el8"></li>
<li class="event" id="el9"></li>
<li class="event" id="el10"></li>
<li class="event" id="el11"></li>
<li class="event" id="el12"></li>
<li class="event" id="el13"></li>
<li class="event" id="el14"></li>
<li class="event" id="el15"></li>
</ul>
</body>
CSS
h1 {
font-size: 24px;
color:#ddd;
background:white;
padding:0.2em;
font-family:sans-serif;
}
.event {
display: block;
width: 30vw;
height: 6vh;
background: #DDD;
margin: 10px;
-webkit-transition: height 0.6s;
}
/* This selects the siblings before and after the middle element*/
.top, .top + li + li {
height: 20vh;
background-color: #ccc;
-webkit-transition: height 0.6s;
}
/* This selects the middle element*/
.top + li {
height: 30vh;
background-color: #bbb;
-webkit-transition: height 0.6s;
}
/* CSS4 SELECTOR, NOT SUPPORTED YET */
li:has(+ .centered) {
height: 20vh;
background-color: #Fcc;
-webkit-transition: height 0.6s;
}
/* :not() probably doesn't support complex selectors*/
li:not(.centered ~ li):last-of-type {
height: 20vh;
background-color: #Fcc;
-webkit-transition: height 0.6s;
}
#midline {
position: fixed;
height: 1px;
width: 100%;
border-top: dotted #ddd 1px;
top: 50%;
}
JavaScript
var findMiddleElement = (function (docElm) {
var viewportHeight = docElm.clientHeight,
elements = $('li');
return function (e) {
var middleElement;
if (e && e.type == 'resize') viewportHeight = docElm.clientHeight;
elements.each(function () {
var topedge = this.getBoundingClientRect().top;
var botedge = this.getBoundingClientRect().bottom;
if (topedge < viewportHeight / 2 && botedge > viewportHeight / 2) {
middleElement = this;
$(this).prev().toggleClass("top", true);
$('li').not(this).prev().toggleClass("top", false);
return false; // stop iteration
}
});
}
})(document.documentElement);
$(window).on('scroll resize', findMiddleElement)