How to customize a div's scroll bar with css modules? - javascript

I'm trying to customize a div component's scroll bar like this :
Home.js
import classes from "./Home.module.scss";
function Home() {
return (
<div className={classes.scroll}>
<p>jasbdkajsdb</p>
<p>jasbdkajsdb</p>
<p>jasbdkajsdb</p>
<p>jasbdkajsdb</p>
<p>jasbdkajsdb</p>
</div>
);
}
Home.module.scss
.scroll {
&:-webkit-scrollbar {
width: 20px;
}
&:-webkit-scrollbar-thumb {
background: red;
border-radius: 25px;
}
&::-webkit-scrollbar-track {
background-color: red;
}
}
But the css doesn't apply . How can I customize a div's scrollbar ?

You are missing a colon on two of your selectors try this:
Home.module.scss
.scroll {
&::-webkit-scrollbar {
width: 5px;
}
&::-webkit-scrollbar-thumb {
background: red;
border-radius: 25px;
}
&::-webkit-scrollbar-track {
background-color: red;
}
}
See the full list of scrollbar pseudo-element selectors

Related

Function not repeating after the first event

I've been trying to learn how to work with HTML, CSS and JavaScript with no prior experience with a any sort of programming, and I'm trying some things out as I learn.
I'm trying to get a click event where multiple divs on a list (two in this case) to either lose a specific class if they have it, and gain said class if they don't, all on the same click.
The first time it's clicked, it runs properly, but how do I get it to do this on every click?
I know there's easier ways to do this, but I really just want to experiment with this setup for now.
If anybody has an idea on why it won't switch classes again, or any tips(or insults) whatsoever, please feel free.
Here's the code:
const SignList = document.querySelectorAll('.sign')
console.log(SignList)
SignList.forEach((div) => {
div.addEventListener('click', () => {
if (div.classList.contains('active')) {
SignList.forEach((div) => {
div.classList.remove('active');
SignList.forEach((div) => {
if (!div.classList.contains('active')) {
div.classList.add('active')
}
})
})
}
})
})
html {
margin: 0px;
padding: 0px;
box-sizing: border-box;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.sign {
position: absolute;
height: 100px;
width: 100px;
border: 5px solid black;
border-radius: 20px;
}
.red {
background-color: red;
display: none;
}
.blue {
background-color: blue;
display: none;
}
.active {
display: block;
}
<div class="sign red active"></div>
<div class="sign blue"></div>
I feel like your question and code are a little confusing in terms of exactly what behavior you want from the click. Also, you probably shouldn't nest so much and reuse the same variable name [like div here] - instead, it might be better to break it down by defining a function.
If you want to toggle a certain class in each div when any div is clicked, you might change your js to something like this:
const SignList = document.querySelectorAll('.sign')
console.log(SignList)
function toggleClass(tClass) {
//incase more div.sign might be added dynamically:
const sList = document.querySelectorAll('.sign')
sList.forEach((div) => {
if (div.classList.contains(tClass)) {
div.classList.remove(tClass);
} else {
div.classList.add(tClass);
}
})
}
SignList.forEach((div) => {
div.addEventListener('click', () => { toggleClass('active') })
})
On the other hand, if you want to toggle that class only if the clicked div contain the class, you can change the above code to :
function toggleClass(clickTarget, tClass) {
if (clickTarget.classList.contains(tClass)) {
const sList = document.querySelectorAll('.sign');
sList.forEach((div) => {
if (div.classList.contains(tClass)) {
div.classList.remove(tClass);
} else {
div.classList.add(tClass);
}
})
}
}
SignList.forEach((div) => {
div.addEventListener('click', (evt) => { toggleClass(evt.target, 'active') })
})
Then, it will only toggle if an "active" element is clicked on. It won't make a difference here, because the non-"active" elements are not visible, and there are only 2 elements affected, but if the class (for example) changed border color to green, only clicking on divs with green border would do anything....
(evt.target passes the object [that the event happened to] to the function in the listener and is more reliable than passing it as div like in your code. You could pass on the evt object itself to give the function more information about the event, but it's not necessary in this case.)
Hope this helps, and best of luck with your coding journey!
You should iterate each of the .sign and toggle it. That's how the code now reflects that.
const SignList = document.querySelectorAll('.sign')
// console.log(SignList)
SignList.forEach((div) => {
div.addEventListener('click', () => {
SignList.forEach((div) => {
if (div.classList.contains('active')) {
div.classList.remove('active');
} else {
div.classList.add('active')
}
})
})
})
html {
margin: 0px;
padding: 0px;
box-sizing: border-box;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.sign {
position: absolute;
height: 100px;
width: 100px;
border: 5px solid black;
border-radius: 20px;
}
.red {
background-color: red;
display: none;
}
.blue {
background-color: blue;
display: none;
}
.active {
display: block;
}
<body>
<div class="sign red active"></div>
<div class="sign blue"></div>
</body>

Show/hide div or image when scrolling

Is there a way to show an image or a div when scrolling down a web page and hide it when not scrolling and vice versa?
So in the code below the red div would be displayed when not scrolling, and the green div would be displayed only when scrolling.
.square {
position: fixed;
width: 100px;
height: 100px;
}
.green {
background: green;
display: none;
}
.red {
background: red;
}
.container {
width: 100%;
height: 3000px;
}
<div class="container">
<div class="square green"></div>
<div class="square red"></div>
</div>
The end goal is to achieve something like this: https://mailchimp.com/annual-report/ where the character appears to be walking when the user scrolls, and stands still when the user stops. Is this easily achievable?
You just need an eventListener that listen to a scroll event. However this has the issue that it only recoginze when you scroll but not when you stop scrolling. For that you can use this answer that explains how to listen for a "scroll-stop"
To make the code shorter and easier, I removed your display: none from the green box. I added a new class d-none that contains this proeprty now instead. By default it is added to the green box.
With classList.toggle('d-none') I can toggle class within both boxes which makes it easier then to address and then add or remove the class for every box on its own.
var timer = null;
var box = document.querySelectorAll('.square');
window.addEventListener('scroll', function() {
if (timer !== null) {
clearTimeout(timer);
} else {
box.forEach(el => el.classList.toggle('d-none'));
}
timer = setTimeout(function() {
box.forEach(el => el.classList.toggle('d-none'));
}, 150);
}, false);
.d-none {
display: none;
}
.square {
position: fixed;
width: 100px;
height: 100px;
}
.green {
background: green;
/* display: none; */
/* removed */
}
.red {
background: red;
}
.container {
width: 100%;
height: 3000px;
}
<div class="container">
<div class="square green d-none"></div>
<div class="square red"></div>
</div>
You just need a setTimeout function:
(function($) {
$(function() {
$(window).scroll(function() {
$('.square.red').show()
$('.square.green').hide()
clearTimeout($.data(this));
$.data(this, setTimeout(function() {
$('.square.red').hide()
$('.square.green').show()
}, 250));
});
});
})(jQuery);
.square {
position: fixed;
width: 100px;
height: 100px;
}
.green {
background: green;
}
.red {
background: red;
display: none;
}
.container {
width: 100%;
height: 3000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="square green"></div>
<div class="square red"></div>
</div>

Style adjustments in a reactJS dropdown Menu

I'm currently building a ReactJS App, and I needed to implement a dropdown menu.
I currently have the menu built, but I need help for two elements :
The style of the menu
The position of the menu
1 - Style of the menu
The menu looks like that :
But when I hoover the menu, there is a gap between the hovering of a link and the link itselfs.
For example :
Here I hoover 'Rename', but styling come under it...
2 - Position of the menu
Simple question : How can I choose myself the position of the menu in my page ?
Neither relative to the parent element nor in a fixed page position ?
Here are my source codes :
VerticalDots.js
import React from "react";
import "./VerticalDots.css";
export default class VerticalDots extends React.Component {
state = {
status: false,
elements: [
"Rename",
"Duplicate",
"Archive",
"Delete Permanently"
]
}
buttonClick = (e, curstat) => {
e.stopPropagation();
this.setState({ status: curstat });
};
displayElements(){
if(this.state.status){
return(
<div className="show-options">
{this.state.elements.map((value, key) => {
return (
<div className="data-row">{value}</div>
);
})}
</div>
);
}
}
render() {
return (
<div className="dropdown-root">
<div className="text-box">
<div className="button" onClick={e => this.buttonClick(e, !this.state.status)}>
<img src={require("../imgs/3dots-vertical.png")} alt="NotFound"/>
</div>
{this.displayElements()}
</div>
</div>
);
}
}
VerticalDots.css
.text-box {
width: 100px;
height: 40px;
position: relative;
text-align: left;
}
.button {
text-align: right;
font-size: 13px;
}
.show-options {
height: 110px;
width: 150px;
border: 1px solid #7A7A7A;
border-radius: 4px;
position: relative;
background: #EBEBEB;
cursor: pointer;
overflow-y: scroll;
overflow-x: hidden;
z-index: 1;
}
.data-row {
height: 20px;
text-align: left;
/* margin: 0px 10px 0px 10px; */
color: #25073C;
border-radius: 4px;
}
.data-row:hover {
background-color: #1464F6;
color: white;
}
.drop-text {
margin-top: 10px;
margin-left: 5px;
position: absolute;
}
.column9:hover{
background-color: red;
}
https://codesandbox.io/s/cool-engelbart-tuz4y
I couldn't recreate your first issue, can you please clarify further on what's happening on your end? It might be that you have other styles included that are causing that issue.
Regarding issue number 2, normal css rules apply to .show-options which is a child of .text-box. I am not sure how you want to position it, but one suggestion would be to use flex, something like:
.text-box {
height: auto;
display: flex;
flex-direction: column
}
I solved the problem, a hidden line-height was linked 3 branches above.
Thank you for your time !

with javascript onclick add classname to a div

I want to achieve with javascript something like when i clink on any of thumbnail (btn-1, btn-2 and btn-3) the specific class should be add to box div dynamically.
my code: JSFiddle
document.getElementById('btn-1').onclick = function() {
document.getElementById('box').className = 'bg-1';
}
#box {
background-color: darkgray;
width: 200px;
height: 200px;
}
.thumbnail {
width: 30px;
height: 30px;
border: 1px solid;
margin: 5px;
position: relative;
float: left;
}
#btn-1 {
background-color: red;
}
#btn-2 {
background-color: green;
}
#btn-3 {
background-color: blue;
}
.bg-1 {
background-color: red;
}
.bg-2 {
background-color: blue;
}
.bg-3 {
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box"></div>
<div class="thumbnail" id="btn-1"></div>
<div class="thumbnail" id="btn-2"></div>
<div class="thumbnail" id="btn-3"></div>
You javascript is working, but your CSS isn't.
You need to add !important as follows to .bg-1, .bg-2 and .bg-3
.bg-1 {
background-color: red !important;
}
Otherwise the id styling is taking preference over the class styling
You can see the classname is being added if you right click on the grey div and choose inspect element in Chrome.
Instead of bothering with classes, use simply a data- attribute like: data-bg="#f00"
$('[data-bg]').css('background', function () {
$(this).on('click', () => $('#box').css('background', this.dataset.bg));
return this.dataset.bg;
});
#box {
background: darkgray;
width: 120px; height: 120px;
}
[data-bg] {
width: 30px; height: 30px;
margin: 5px;
float: left;
}
<div id="box"></div>
<div data-bg="red"></div>
<div data-bg="#00f"></div>
<div data-bg="rgb(255,0,180)"></div>
<div data-bg="linear-gradient(to right, #E100FF, #7F00FF)"></div>
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
You want to use jquery .addClass() function:
$('.myButton').addClass('myNewClass');
The function would probably look something like this:
$(function () {
$('.thumbnail').click(function() {
$('#box').addClass($(this).attr('id'));
});
})
You can get all the thumbnails as an array, and then iterate through the array and dynamically add an event listener to each, which will add the desired className to box when clicked:
var thumbnails = document.getElementsByClassName('thumbnail');
Array.from(thumbnails).forEach(function(thumbnail) {
var id = thumbnail.id;
thumbnail.addEventListener('click', function() {
document.getElementById('box').className = id.replace('btn', 'bg')
});
});

Using .show/.hide with .next causing issues

I am wanting to display the service-specificBar-tab of serviceBarId1 on page load and hide the other tabs, which is working. However, the part that isn't working like I want is when I click on that tab, I want the rest of the other three tabs to show in the order in which the HTML is and then when I click on the first tab again, for tabs 2, 3 and 4 to close. The method I am using now is acting very buggy. When you click on serviceBarId1 to open the tabs, all of the tabs open, but then one disappears - this didn't happen until I added:
$("#serviceBarId1").click(function() {
$("#serviceBarId2").hide(1000);
$("#serviceBarId3").hide(1000);
$("#serviceBarId4").hide(1000);
});
When I try to close the tabs, nothing happens.
What am I doing wrong?
$("#serviceBarId1").addClass("active");
$("#serviceBarId2").hide();
$("#serviceBarId3").hide();
$("#serviceBarId4").hide();
$("#serviceBarId1").click(function() {
$(".service-specificBar-tab").first().show("fast", function showNext() {
$(this).next(".service-specificBar-tab").show("fast", showNext);
});
});
$("#serviceBarId1").click(function() {
$("#serviceBarId2").hide(1000);
$("#serviceBarId3").hide(1000);
$("#serviceBarId4").hide(1000);
});
#gray {
background: #f9f9f9;
width: 100%;
height: 700px;
position: relative;
}
#service-specificBar-container {
position: relative;
top: 50px;
width: 100%;
padding: 25px 0;
}
#service-specificBar {
width: 100%;
height: 100px;
position: relevant;
}
.service-specificBar-tab {
width: 25%;
height: 100%;
display: inline-block;
margin: 0;
padding: 0px;
text-align: center;
font-size: 1.6em;
}
.service-specificBar-tab:nth-child(odd) {
background: #dbdbdb;
transition: ease-in-out .3s;
cursor: pointer;
}
.service-specificBar-tab:nth-child(even) {
background: #FFF;
transition: ease-in-out .3s;
cursor: pointer;
}
#serviceBarId1:hover,
#serviceBarId2:hover,
#serviceBarId3:hover,
#serviceBarId4:hover {
transition: ease-in-out .3s;
color: #FFF;
}
#serviceBarId2:hover {
background: #0085A1;
}
#serviceBarId3:hover {
background: #a11c00;
}
#serviceBarId4:hover {
background: #00a16d;
}
/*----Test for page swithces ----*/
#serviceBarId1.active {
background: #a10085;
color: #FFF;
}
#serviceBarId2.active {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="gray">
<div id="service-specificBar-container">
<div id="service-specificBar">
<div class="service-specificBar-tab" id="serviceBarId1">A</div>
<div class="service-specificBar-tab" id="serviceBarId2">B</div>
<div class="service-specificBar-tab" id="serviceBarId3">C</div>
<div class="service-specificBar-tab" id="serviceBarId4">D</div>
</div>
</div>
</div>
On the click event you could check the number of visible items. If the length of the visible divs is 1, show the siblings, otherwise, hide them:
$("#serviceBarId1").click(function() {
if ($('#service-specificBar').find(':visible').length == 1) {
$(".service-specificBar-tab").first().show("fast", function showNext() {
$(this).next(".service-specificBar-tab").show("fast", showNext);
});
} else {
$(".service-specificBar-tab").next().hide("fast", function hideNext() {
$(this).next(".service-specificBar-tab").hide("fast", hideNext);
});
}
});
Fiddle Demo

Categories

Resources