Creating inset shadow within scrollable region but above internal divs - javascript

I have a paper-dialog-scrollable of which I would like a shadow to appear at the top when scrolling down the page.
However, if I set an inset box shadow, any internal divs simply go over the top of it even after playing with z-index.
Can anybody help me? Please see this Fiddle to play/edit.
The aim is to have no shadow when content hasn't been scrolled, then fade in when it is.

You need to make one more class boxShadow to define box-shadow on scrolling div.
.container {
width: 400px;
height: 200px;
background: #e5e5e5;
overflow: auto;
}
.content {
text-align: center;
width: 200px;
height: 300px;
background: lightblue;
margin: auto;
margin-top: 20px;
margin-bottom: 20px;
padding: 10px;
z-index:-1;
}
.boxShadow{box-shadow: inset 0 10px 10px -1px rgba(0,0,0,0.6); width:400px; height:20px; background:#e5e5e5;}
<div class="boxShadow"></div>
<div class="container">
<div class="content">
Some text
</div>
</div>

You need to add JQuery:
var header = $(".container");
$(".container").scroll(function() {
var scroll = $(this).scrollTop();
if (scroll >= 2) {
$(this).addClass("shadow");
} else {
$(this).removeClass("shadow");
}
});
.container {
width: 400px;
height: 200px;
background: #e5e5e5;
overflow: auto;
-webkit-transition: all 0.2s ease;
-moz-transition: all 0.2s ease;
-o-transition: all 0.2s ease;
transition: all 0.2s ease;
}
.container.shadow {
box-shadow: inset 0 10px 10px -1px rgba(0,0,0,0.6);
-webkit-transition: all 0.2s ease;
-moz-transition: all 0.2s ease;
-o-transition: all 0.2s ease;
transition: all 0.2s ease;
}
.content {
text-align: center;
width: 200px;
height: 300px;
background: lightblue;
margin: auto;
margin-top: 20px;
margin-bottom: 20px;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="container">
<div class="content">
Some text
</div>
</div>

Use negative z-index and position: relative on the .content to move it under the .container, and add a .wrapper with the background color, position: relative, and a positive z-index value to provide background under the .content.
var container = document.querySelector('.container');
var containerClasses = container.classList;
container.addEventListener('scroll', function(e) {
if(e.target.scrollTop > 0) {
containerClasses.contains('shadow') || containerClasses.add('shadow');
} else {
containerClasses.remove('shadow');
}
});
.wrapper {
position: relative;
z-index: 0;
display: inline-block;
background: #e5e5e5;
}
.container {
position: relative;
width: 400px;
height: 200px;
overflow: auto;
box-shadow: inset 0 10px 10px -1px rgba(0, 0, 0, 0);
transition: box-shadow 0.3s;
}
.shadow {
box-shadow: inset 0 10px 10px -1px rgba(0, 0, 0, 0.6);
}
.content {
position: relative;
z-index: -1;
text-align: center;
width: 200px;
height: 300px;
background: lightblue;
margin: auto;
margin-top: 20px;
margin-bottom: 20px;
padding: 10px;
}
<div class="wrapper">
<div class="container">
<div class="content">
Some text
</div>
</div>
</div>
If you need the .content to be clickable you can add a wrapper with a pseudo element overlay. The overlay has pointer-events: none, which means that the content under it can be clicked. The only problem is the width of the scrollbar, which is not consistent across browsers:
var wrapperClasses = document.querySelector('.wrapper').classList;
var container = document.querySelector('.container');
container.addEventListener('scroll', function(e) {
if(e.target.scrollTop > 0) {
wrapperClasses.contains('shadow') || wrapperClasses.add('shadow');
} else {
wrapperClasses.remove('shadow');
}
});
.wrapper {
position: relative;
display: inline-block;
background: #e5e5e5;
}
.wrapper::before {
position: absolute;
z-index: 1;
top: 0;
width: calc(100% - 12px); /** the width minus the scrollbar width **/
height: 100%;
box-shadow: inset 0 10px 10px -1px rgba(0, 0, 0, 0.6);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
content: "";
}
.shadow::before {
opacity: 1;
}
.container {
width: 400px;
height: 200px;
overflow: auto;
}
.content {
text-align: center;
width: 200px;
height: 300px;
background: lightblue;
margin: auto;
margin-top: 20px;
margin-bottom: 20px;
padding: 10px;
}
<div class="wrapper">
<div class="container">
<div class="content">
Some text
</div>
</div>
</div>

Related

Javascript toggle slide nav with fade

Click the flower to open menu. Then i have created the motion i want with "prosess" fading in after the menu opens up. But i want to reverse the motion when collapsing. So that "prosess" fades out before the meny toggles back. Anyone that can help me out with this?
function classOpen() {
var spinn = document.getElementById("nav");
spinn.classList.toggle('in');
spinn.classList.toggle('out');
}
const delay = ms => new Promise(res => setTimeout(res, ms));
const classFadeIn = async () => {
var element1 = document.getElementById("text1");
var element2 = document.getElementById("text2");
var element3 = document.getElementById("text3");
await delay(300);
element1.classList.toggle("show");
element2.classList.toggle("show");
element3.classList.toggle("show");
}
document.querySelector('#nav').addEventListener('click', classFadeIn);
:root{
--seconds: 5s;
--fast: 2s;
}
nav{
position: fixed;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10px;
padding-top: 20px;
width: 100%;
}
nav img{
width: 50px;
}
/* INN OUT */
#nav{
height: auto;
display: flex;
align-items: center;
justify-content: flex-start;
border-radius: 50px;
padding: 10px;
background-color: white;
margin-right: 20px;
/*drop shadow*/
-webkit-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
-moz-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
}
.in {
width: 50px;
}
.out {
width: 400px;
}
.transition{
-webkit-transition: all 0.2s ease-in-out;
-moz-transition:all 0.2s ease-in-out
-o-transition:all 0.2s ease-in-out;
transition::all 0.2s ease-in-out;
}
#navtext{
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.style{
display: flex;
background-color: white;
justify-content: center;
align-items: center;
padding: 10px 15px 10px 15px;
border-radius: 40px;
color: lightgrey;
transition: 0.1s;
}
#text{
display: none;
}
.noshow{
display: none;
}
.show{
display: flex;
}
.show:hover{
color: black;
background-color: lightgrey
}
<nav>
<div id="nav" class="in transition">
<img id="spinn" src="https://i.dlpng.com/static/png/762080_preview_preview.png" class="rotating spinn" onclick="classOpen()">
<div id="navtext">
<a id="text1" class="noshow style">Prosess</a>
<a id="text2" class="noshow style">Prosess</a>
<a id="text3" class="noshow style">Prosess</a>
</div>
</div>
</nav>
I have deleted the part for showing/hiding the items from Javascript and kept in/out toggle.
Then, depending on in/out classes I will show/hide the items by CSS:
.transition.in .noshow{
visibility: hidden;
opacity: 0;
height:0;
}
.transition.out .noshow{
visibility: visible;
opacity: 1;
height:auto;
transition: 0.7s;
}
The reason for not using display: none || flex is to keep the effect of transitoin.
Here is the full code:
function classOpen() {
var spinn = document.getElementById("nav");
spinn.classList.toggle('in');
spinn.classList.toggle('out');
}
document.querySelector('#nav').addEventListener('click', null);
:root{
--seconds: 5s;
--fast: 2s;
}
nav{
position: fixed;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10px;
padding-top: 20px;
width: 100%;
}
nav img{
width: 50px;
}
/* INN OUT */
#nav{
height: auto;
display: flex;
align-items: center;
justify-content: flex-start;
border-radius: 50px;
padding: 10px;
background-color: white;
margin-right: 20px;
/*drop shadow*/
-webkit-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
-moz-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
}
.in {
width: 50px;
}
.out {
width: 400px;
}
.transition{
-webkit-transition: all 0.2s ease-in-out;
-moz-transition:all 0.2s ease-in-out
-o-transition:all 0.2s ease-in-out;
transition::all 0.2s ease-in-out;
}
#navtext{
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.style{
display: flex;
background-color: white;
justify-content: center;
align-items: center;
padding: 10px 15px 10px 15px;
border-radius: 40px;
color: lightgrey;
transition: 0.1s;
}
#text{
display: none;
}
.transition.in .noshow{
visibility: hidden;
opacity: 0;
height:0;
}
.transition.out .noshow{
visibility: visible;
opacity: 1;
height:auto;
transition: 0.7s;
}
.noshow:hover{
color: black;
background-color: lightgrey
}
<nav>
<div id="nav" class="in transition">
<img id="spinn" src="https://i.dlpng.com/static/png/762080_preview_preview.png" class="rotating spinn" onclick="classOpen()">
<div id="navtext">
<a id="text1" class="noshow style">Prosess</a>
<a id="text2" class="noshow style">Prosess</a>
<a id="text3" class="noshow style">Prosess</a>
</div>
</div>
</nav>
Use only one "is-active" class-name on the #nav element, toggle it using JS and target descendants using CSS.
Use transition-delay CSS property to smartly inverse the transition timing login on toggle:
const nav = document.querySelector("#nav");
nav.addEventListener("click", () => nav.classList.toggle("is-active"));
nav {
position: fixed;
top: 10px;
left: 10px;
z-index: 100;
}
#navImg {
width: 50px;
cursor: pointer;
display: inline-block;
transition: transform 0.6s ease-in-out;
}
#nav {
display: flex;
padding: 10px;
border-radius: 50px;
background-color: white;
box-shadow: 0px 10px 30px 0px rgba(0, 0, 0, 0.10);
}
#navText {
display: flex;
flex-flow: row nowrap;
width: 0;
transition: 0.3s ease-in-out 0.3s;
overflow: hidden;
}
#navText a {
display: inline-flex;
align-self: center;
padding: 10px 15px 10px 15px;
margin-left: 10px;
border-radius: 40px;
color: #aaa;
text-decoration: none;
opacity: 0;
transition: opacity 0.3s ease-in-out 0s;
}
/* ACTIVE STATE */
#nav.is-active #navText {
transition-delay: 0s; /* reverse delay timing logic */
width: 270px; /* this could be calculated using JS... this is for demo only */
}
#nav.is-active #navText a {
transition-delay: 0.3s; /* reverse delay timing logic */
opacity: 1;
}
#nav.is-active #navImg {
transform: rotate(1turn);
}
<nav>
<div id="nav">
<img id="navImg" src="https://i.dlpng.com/static/png/762080_preview_preview.png">
<div id="navText">
Prosess
Prosess
Prosess
</div>
</div>
</nav>

how to hide sidebar when clicking outside of sidebar?

I have a sidebar that looks like this:
Clicking the arrow will collapse the sidebar again. However, I want to auto close the sidebar if I click outside of the sidebar. Would that be possible?
This is my script for toggling the sidebar:
<script type="text/javascript">
$(document).ready(function() {
$("#sidebar").mCustomScrollbar({
theme: "minimal"
});
$('#dismiss, .overlay').on('click', function() {
$('#sidebar').removeClass('active');
$('.overlay').removeClass('active');
});
$('#sidebarCollapse').on('click', function() {
$('#sidebar').addClass('active');
$('.overlay').addClass('active');
$('.collapse.in').toggleClass('in');
$('a[aria-expanded=true]').attr('aria-expanded', 'false');
});
});
</script>
The toggler icon (hamburger) that expands the sidebar:
<div class="col-4 my-auto text-left p-1">
<button type="button" id="sidebarCollapse" class="btn">
<i class="fa fa-bars navigation-icon"></i>
</button>
Some CSS:
#sidebar {
width: 250px;
position: fixed;
top: 0;
left: -250px;
height: 100vh;
z-index: 999;
background: #fbcc34;
color: #fff;
transition: all 0.3s;
overflow-y: scroll;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.2);
}
#sidebar.active {
left: 0;
}
#dismiss {
width: 35px;
height: 35px;
line-height: 35px;
text-align: center;
background: #000000;
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
-webkit-transition: all 0.3s;
-o-transition: all 0.3s;
transition: all 0.3s;
}
#dismiss:hover {
background: #fff;
color: #7386d5;
}
.overlay {
display: none;
position: fixed;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.7);
z-index: 998;
opacity: 0;
transition: all 0.5s ease-in-out;
}
.overlay.active {
display: block;
opacity: 1;
}
#sidebar .sidebar-header {
padding: 20px;
background: #000000;
}
So when I click anywhere outside the sidebar, it should close the sidebar automatically. Do I have to create a separate function to achieve this?
You can do this with code below:
$('body').click(function(event){
if($(event.target).attr('id') !== "sidebar" && $(event.target).attr('id') !== "sidebarCollapse") {
$('#sidebar').removeClass('active');
$('.overlay').removeClass('active');
}
});

How to use toggleClass with the same classed divs but without affecting the other ones

I am currently looking for a solution which aims at creating several of these boxes with this hover effect.
The easiest solution would be to duplicate the code each time and change the id. Now I am looking for a better and more lean solution to achieve several duplications of the example shown in the snippet.
Any hints are highly appreciated.
Thanks!
$(".rsausschreibung").hover(function() {
$(".lsausschreibung").toggleClass("small large");
$(".rsausschreibung").toggleClass("small large");
});
.annonce {
margin-left: 30px;
width: auto;
}
.lsausschreibung {
float: left;
position: relative;
margin-right: -10px;
background-color: white;
transition: all 0.5s ease-in-out;
}
.large {
height: 320px;
width: 280px;
z-index: 10;
box-shadow: 5px 2px 14px rgba(0, 0, 0, 0.6);
}
.small {
height: 290px;
width: 230px;
z-index: 1;
margin-top: 15px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
}
.rsausschreibung {
float: left;
position: relative;
z-index: 1;
background-color: white;
transition: all 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="annonce">
<div class="lsausschreibung large">
</div>
<div class="rsausschreibung small">
</div>
</div>
Instead of using a class selector inside the hover function, use a reference to the targetted element with $(this):
$(".rsausschreibung").hover(function() {
$(this).prev().toggleClass("small large");
$(this).toggleClass("small large");
});
That way you are always targetting the element on which the mouseover is happening, regardless of whether other elements are targetted overall by the hover method.
$(".rsausschreibung").hover(function() {
$(this).prev().toggleClass("small large");
$(this).toggleClass("small large");
});
.annonce {
margin-left: 30px;
width: auto;
clear: both;
margin-bottom: 50px;
}
.lsausschreibung {
float: left;
position: relative;
margin-right: -10px;
background-color: white;
transition: all 0.5s ease-in-out;
}
.large {
height: 320px;
width: 280px;
z-index: 10;
box-shadow: 5px 2px 14px rgba(0, 0, 0, 0.6);
}
.small {
height: 290px;
width: 230px;
z-index: 1;
margin-top: 15px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
}
.rsausschreibung {
float: left;
position: relative;
z-index: 1;
background-color: white;
transition: all 0.5s ease-in-out;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="annonce">
<div class="lsausschreibung large" id="el1">
</div>
<div class="rsausschreibung small" id="el2">
</div>
</div>
<div class="annonce">
<div class="lsausschreibung large" id="el3">
</div>
<div class="rsausschreibung small" id="el4">
</div>
</div>
Some adjustments to the stylesheet were necessary for proper display, check the snippet.

Modal Window with scroll bar

So, I have a modal window in a website that I'm devloping.
The modal is made out of pure CSS, to open it and close it I have javascript functions wich change the css elements to make the modal show/hide.
CSS of the modal:
<style>
.modalDialog {
position: fixed;
font-family: Arial, Helvetica, sans-serif;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
z-index: 99999;
opacity:0;
-webkit-transition: opacity 400ms ease-in;
-moz-transition: opacity 400ms ease-in;
transition: opacity 400ms ease-in;
pointer-events: none;
}
.modalDialog > div {
position: relative;
margin: 10% auto;
padding: 5px 20px 13px 20px;
border-radius: 10px;
background:white;
display: table;
}
.close {
background: #606061;
color: #FFFFFF;
line-height: 25px;
position: absolute;
right: -12px;
text-align: center;
top: -10px;
width: 24px;
text-decoration: none;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
}
.close:hover {
background: #00d9ff;
}
.btnEncomendarProduto {
background-color:#D60E12;
color:white;
border-radius:5px;
font-size: 12px;
white-space:normal;
cursor:pointer;
text-transform: initial;
border:1px solid #D60E12;
margin-top:3px;
}
</style>
So the problem is when I have a something that displays too much information on the modal, this happens:
So I think I need a scroll bar on the div inside the modal. How can I do that?
Thank you.
If you have an inner div that expands with the content of the actual modal, you can set the max-height of that div to be something--like 75vh--and add overflow-y: auto to that container, and it will automatically add a scrollbar when the content gets longer than that set max-height.
HTML
<div class="Content">
<p>
This is the page contents.
</p>
</div>
<div class="Modal" id="modal">
<div class="Contents">
<h1>Modal</h1>
<p id="text-area">
[large amounts of content]
</p>
</div>
</div>
CSS
body
{
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
.Content
{
position: relative;
width: 100%;
}
.Modal
{
position: fixed;
display: none;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3); // light grey background
}
.Modal.Open
{
display: block;
}
.Modal .Contents
{
overflow-y: auto;
display: block;
position: relative;
width: 90%;
margin: 5% auto 0;
max-height: 90vh;
padding: 5px;
background: #fff;
}
Note the .Modal .Contents selector and how it works.
JSFiddle Example: https://jsfiddle.net/nj6r0sjw/

Positions of buttons change after being clicked

Hi, I made a leftmenu that hides on a button click and shows on another button's click. When I click the ".smaller" button, the leftmenu's width changes to 0px and the ".bigger" button appears. But when I click this button somehow the position of the ".smaller" button is changed to another location.
HTML:
<html>
<body>
<div id="container">
<div id="header">
</div>
<div id="leftmenu">
<ul>
<li>Home</li>
<li>About</li>
<li>Ideas</li>
<li>Video</li>
<li>Contact</li>
</ul>
<div class="smaller"></div>
<div class="bigger"></div>
</div><!--leftmenu end-->
<div id="content">
</div>
</div><!--container end-->
</body>
</html>
CSS:
body{
margin: 0;
padding: 0;
background-color: #c8c8c8;
}
html{
background-color: #c8c8c8;
}
li{
list-style: none;
}
a{
text-decoration: none;
}
#container{
width: 100%;
height: 2000px;
}
#leftmenu{
position: fixed;
width: 200px;
height: 100%;
background: #b99d84;
transition: .5s ease-out;
-webkit-transition: .5s ease-out;
margin: 0;
padding: 0;
}
#leftmenu:hover{
transition: .5s ease-in;
-webkit-transition: .5s ease-in;
background: #a2805e;
}
#leftmenu ul{
width: 100%;
height: 100%;
padding: 0;
text-align: center;
margin-top: 50px;
}
#leftmenu ul li{
width: 100%;
height: 50px;
margin-bottom: 50px;
vertical-align: middle;
}
#leftmenu ul li a{
color: white;
font-size: 25px;
}
#leftmenu ul li a:hover{
transition: 0.1s ease-in;
text-shadow: 0 0 12px white;
}
.smaller{
position: fixed;
top: 22%;
left: 0;
width: 0;
height: 0;
border-top: 120px solid transparent;
border-right: 30px solid white;
opacity: .75;
border-bottom: 120px solid transparent;
transition: .5s ease-out;
-webkit-transition: .5s ease-out;
}
.bigger{
position: fixed;
top: 22%;
left: 0;
border-top: 120px solid transparent;
border-left: 30px solid white;
border-bottom: 120px solid transparent;
display: none;
}
#content{
width: 60%;
height: 100%;
background: #d7d7d7;
margin: 0 20%;
border-left: 1px solid gray;
border-right: 1px solid gray;
}
JQUERY:
$(document).ready(function(){
$(".smaller").click(function(){
$("#leftmenu").css("width", "0px");
$("#leftmenu ul").fadeOut();
$(".smaller").hide();
$(".bigger").show();
//content widths and margins
$("#content").css("width", "80%");
$(this).css("width", "80%");
$("#content").css("margin", "0 auto");
$(this).css("margin", "0 auto");
});//smaller.click end
$(".bigger").click(function(){
$(".bigger").hide();
$(".smaller").show();
$("#leftmenu").css("width", "200px");
$("#leftmenu ul").fadeIn();
});//bigger.click end
$("#content").css("width", "60%");
$(this).css("width", "60%");
$("#content").css("margin", "0 20%");
$(this).css("margin", "0 20%");
});
Thanks a lot, if anybody could find the answer, I've been stuck on this for a long time..
Line 12 in your javascript change $(this).css("width", "80%"); to $(this).css("width", "0%");.

Categories

Resources