im trying to show a text "copied" after an image has been clicked, with :active class but testing with hover and i cant figure it out. Like a :hover on a navbar to see a drop down menu
.copy {
display: flex;
&__text {
display: none;
}
&__img {
max-width: 1.2rem;
height: 1.2rem;
margin-left: 0.3rem;
cursor: pointer;
&:active {
filter: opacity(0.5) drop-shadow(0 0 0 rgb(133, 177, 0));
}
}
}
.copy__img:active .copy__text {
display: block;
background-color: red;
}
<div className="copy">
<img
className="copy__img"
src={CopyIcon}
onClick={copyText}
alt="copy icon"
/>
<p className={"copy__text"}>copied</p>
</div>
The :active pseudo-class is used to select and style the active link or any other element. It is activated by user.
An element becomes active when the user clicks on the link or the element and presses down the mouse button.
More details on documentation
:active pseudo-class work with user click not with hovering the element.
If you are working with React.js, you can use this methods :-
jsx:
import "./App.scss";
import { useState } from "react";
export default function App() {
const [mouse, setMouse] = useState(false);
return (
<div className="App">
{/* :active && mouseEventListner*/}
<h4>:active && mouseEventListner</h4>
<div className="div">
<img
className="div__img"
src="https://picsum.photos/200/200"
alt="random"
onMouseDown={() => setMouse(true)}
onMouseUp={() => setMouse(false)}
/>
{mouse && <p className="div__text">copied</p>}
</div>
{/* :active && :hover */}
<h4>:active && :hover</h4>
<div className="parentDiv">
<img
className="parentDiv__childDiv1"
src="https://picsum.photos/200/200"
alt="random"
/>
<div className="parentDiv__childDiv2">copied</div>
</div>
</div>
);
}
scss:
.div{
display: flex;
&__img{
width: 5rem;
cursor: pointer;
&:active{
filter: opacity(0.5) drop-shadow(0 0 0 rgb(133, 177, 0));
}
}
&__text{
background-color: red;
}
}
.parentDiv{
width: 6rem;
background-color: teal;
cursor: pointer;
display: flex;
flex-direction: column;
padding: 1rem;
&:hover > &__childDiv2 {
display: block;
}
&__childDiv1, &__childDiv2{
width: 6rem;
height: 6rem;
}
&__childDiv1{
background-color: white;
&:active{
filter: opacity(0.5) drop-shadow(0 0 0 rgb(133, 177, 0));
}
}
&__childDiv2{
display: none;
background-color: red;
}
}
:active pseudo class only works when clicking.
Related
I'm trying to create a collapsible sidebar on the left.
I want to set it up real simple: 2 columns which contains of 2 flex boxes, and when a button is pushed: the left flex box increases in width and the tight flexbox just moves with. When the button is clicked again, the flexbox on the left decreases again in side, back to the first state where the menu cannot be seen.
My problem is that I don't know how a click event of a button can control the width size of the flexbox.
What I have now is this:
html
<div>
<button
onClick={handleViewMenu}??
style={{ height: "30px", width: "30px" }}>
</button>
</div>
<div className='container'>
<div className='container-left'>
Left
</div>
<div className='container-right'>
right
</div>
</div>
scss
.container { width: 100vw;
height: 100vh;
display: flex;
&-left {
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
// flex: 0.3 0 auto;
// background-color: aqua;
} &-right {
flex: 1 0 auto;
}
}
I just don't know how to deal with the onClick event (where I put the ??. I work in React so I found different things like:
const [sideMenuOpen, setMenuOpen] = useState(false);
const handleViewMenu = () => {
setMenuOpen(!sideMenuOpen);
};
But it should be pretty easy to handle this I think, but I can't find a solution..
Here's a solution that doesn't need javascript by using the :has() pseudo class. Just set the width of the side bar when the checkbox is clicked and if you're using normal flexbox the right hand one will automatically shift to suit. See below. Any questions drop me a comment.
/* essential to add this as there's a default 8px margin */
body {
margin: 0;
}
/* this is also essential to avoid a world of width-based pain */
* {
box-sizing: border-box;
}
/* Just making things pretty here */
nav {
display: flex;
width: 100%;
gap: 1rem;
padding: 0.5rem 1rem;
background-color: purple;
color: white;
}
/*the menu button is basically a hidden check box, we use label to style it as a button */
.menubutton>input {
display: none;
}
/*these toggles the display of the menu button, it works because the label after the input element */
.menubutton>input:checked+label .not-active {
display: none;
}
.menubutton>input:not(:checked)+label .active {
display: none;
}
.container {
display: flex;
width: 100%;
}
.container-left {
background-color: plum;
height: 50vh;
padding: 0.5rem 0.5rem;
border: 1px solid transparent;
width: 3rem;
transition: width 300ms;
}
/* this is the bit that styles the width of the sidebar when the checkbox is checked. */
body:has(.menubutton > input:checked) .container-left {
width: 10rem;
}
/* just style the right box for visibility */
.container-right {
border: 1px solid lightgray;
height: 50vh;
flex-grow: 1;
padding: 0.5rem 0.5rem;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<nav>
<div class='menubutton'><input type='checkbox' id='menubuttoninput'><label for='menubuttoninput'><i class="fa-solid fa-bars not-active"></i><i class="fa-solid fa-xmark active"></i></label></div>
This is a navbar!
</nav>
</div>
<div class='container'>
<div class='container-left'>
Left
</div>
<div class='container-right'>
right
</div>
</div>
If you do need a javascript solution then attach a listener to the checkbox input element and toggle the sidebar class to change the width as below:
window.onload = () => {
document.querySelector('.menubutton input').addEventListener('change', (e) => {
const sidebar = document.querySelector('.container-left');
if (e.target.checked) {
sidebar.classList.add('sidebar-active');
} else {
sidebar.classList.remove('sidebar-active');
}
});
}
/* essential to add this as there's a default 8px margin */
body {
margin: 0;
}
/* this is also essential to avoid a world of width-based pain */
* {
box-sizing: border-box;
}
/* Just making things pretty here */
nav {
display: flex;
width: 100%;
gap: 1rem;
padding: 0.5rem 1rem;
background-color: cornflowerblue;
color: white;
}
/*the menu button is basically a hidden check box, we use label to style it as a button */
.menubutton>input {
display: none;
}
/*these toggles the display of the menu button, it works because the label after the input element */
.menubutton>input:checked+label .not-active {
display: none;
}
.menubutton>input:not(:checked)+label .active {
display: none;
}
.container {
display: flex;
width: 100%;
}
.container-left {
background-color: lightblue;
height: 50vh;
padding: 0.5rem 0.5rem;
border: 1px solid transparent;
width: 3rem;
transition: width 300ms;
}
/* this is the bit that styles the width of the sidebar when the checkbox is checked. We just add this using javascript*/
.sidebar-active {
width: 10rem;
}
/* just style the right box for visibility */
.container-right {
border: 1px solid lightgray;
height: 50vh;
flex-grow: 1;
padding: 0.5rem 0.5rem;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<nav>
<div class='menubutton'><input type='checkbox' id='menubuttoninput'><label for='menubuttoninput'><i class="fa-solid fa-bars not-active"></i><i class="fa-solid fa-xmark active"></i></label></div>
This is a navbar!
</nav>
</div>
<div class='container'>
<div class='container-left'>
Left
</div>
<div class='container-right'>
right
</div>
</div>
I have multiple list items. I want active blue border on clicked or selected item. I am creating a image card layouts. It will active while selecting. It will be a single item selection.
Here is the below code
template code
<div class="container">
<div
v-for="(obj, index) in layoutDatas"
:key="index"
class="item"
#click="getLayoutDetails(obj)"
>
<cmp-image-viewer
ref="index"
:style="'width: 250px; height:150px;'"
/>
<div class="column">
<div class="text1">
{{ obj.layoutId }}
</div>
<div class="row">
<div class="col-xs-9 text2 noBorder">
{{ obj.layoutTitle }}
</div>
</div>
</div>
</div>
</div>
style css code
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: auto;
height: 450px;
border-radius: 3px;
margin-top: 50px;
padding: 10px;
}
.item {
width: 250px;
height: 220px;
border: 0.3px solid #eaeaea;
align-self: center;
padding: 5px;
border-radius: 3px;
margin: 10px 10px;
transition: all .15s ease-in-out;
}
.item:hover {
border: 0.3px solid #0071c5;
transform: scale(1.1);
}
.itemClick {
border: 1px solid #0071c5;
}
.text1 {
font-weight: bold;
padding-left: 10px;
font-size: 16px;
}
.text2 {
color: #959595;
}
How to do the active border on selected item or clicked item using css and vue?
If I understand you correctly, you will only have a single card that is displaying a blue border when clicked. You can track which card is clicked by assigning it to a data property. For instance, the function #getLayoutDetails might include a method to set this.selectedObject = obj, the object you've passed in.
Then, you can use that data value to set a CSS class on the selected object. That would look something like:
<div
v-for="(obj, index) in layoutDatas"
:key="index"
class="item"
:class="obj.id === selected.id ? 'active' : 'not-active'"
#click="getLayoutDetails(obj)"
>
And use the active tag in your css:
.active {
border: 1px solid #0071c5;
}
I have a HTML section of Top Bar which is fixed to view port. And another section of slider. These two 2 section are not totally related to each other as they are the same level in DOM tree. But when I edit the default padding of div.col of Slider, it affect the TopBar. It seems top bar is pulled to bottom and right side when padding of Section edited. I have tried my ways but no way help. Could you please advise any suggestion? Thank you so much. You can view live demo at: https://vanminhquangtri.github.io/football-fashion/
The Top Slide:
import React from 'react';
import {NavLink} from "react-router-dom";
import TinySlider from "tiny-slider-react"
const settings = {
items: 1,
nav: false,
autoplay: true
}
const TopSlide = () => {
return (
<section className="top-slide">
<div className="container-fluid">
<div className="row">
<div className="col">
<div className="wrap">
<TinySlider settings={settings}>
<div className="slide-item item-1">
<div className="background-image"></div>
<div className="slide-caption">
<h5 className="title">Always update the latest</h5>
<NavLink
to="/best-sales"
className="link"
>
Discover Now
</NavLink>
</div>
</div>
<div className="slide-item item-2">
<div className="background-image"></div>
<div className="slide-caption">
<h5 className="title">Bring you the champion's fashion</h5>
<NavLink
to="/champion"
className="link"
>
Discover Now
</NavLink>
</div>
</div>
<div className="slide-item item-3">
<div className="background-image"></div>
<div className="slide-caption">
<h5 className="title">Top-five leagues in the world</h5>
<NavLink
to="/all-fashion"
className="link"
>
Discover Now
</NavLink>
</div>
</div>
</TinySlider>
</div>
</div>
</div>
</div>
</section>
);
};
export default TopSlide;
The TopBar:
// top bar of web page
import React from 'react';
import {NavLink} from "react-router-dom";
import Logo from "../../Assets/images/section-top-bar/ball.png";
import Leagues from "../../Assets/images/section-top-bar/leagues.jpg";
import HotDeal from "../../Assets/images/section-top-bar/hotdeal.png";
const TopBar = () => {
return (
<section className="top-bar">
<div className="container-fluid">
<div className="row">
{/* ball icon */}
<div className="col-3 ball-icon">
<div className="wrap">
<NavLink
to="/"
exact={true}
>
<img
src={Logo}
alt="ball-icon"
/>
</NavLink>
</div>
</div>
{/* icons of top-5 leagues */}
<div className="col-6 leagues-icon">
<div className="wrap">
<NavLink
to="/most-concerned"
exact={true}
>
<img
src={Leagues}
alt="leagues-icon"
/>
</NavLink>
</div>
</div>
{/* hot deals icon */}
<div className="col-3 top-bar-hot-deals">
<div className="wrap">
<NavLink
to="/hot-deal"
exact={true}
>
<img
src={HotDeal}
alt="leagues-icon"
/>
</NavLink>
</div>
</div>
</div>
</div>
</section>
);
};
export default TopBar;
CSS:
/*--- top bar ---*/
.top-bar {
z-index: 2000;
position: fixed;
left: 0;
bottom: 0;
right: 0;
width: 100%;
border-top: 1px solid rgb(235, 235, 235);
background: white;
.container-fluid {
.row {
.wrap {
width: 100%;
a {
display: block;
width: 100%;
}
img {
height: 30px;
}
}
.col-3.ball-icon {
display: flex;
align-items: center;
justify-content: flex-start;
padding-left: 5px;
img {
width: 30px;
}
}
.col-6.leagues-icon {
text-align: center;
img {
height: 35px;
}
}
.col-3.top-bar-hot-deals {
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 5px;
img {
width: 100%;
}
}
}
}
}
/*--- end top bar ---*/
Slider:
/*--- top slide ---*/
.top-slide {
margin-top: 10px;
.container-fluid {
.row {
.col {
padding: 0; PROBLEM HERE, IF REMOVE THIS TOP BAR WILL BE NOT AFFECTED, BUT I NEED TO KEEP THIS SO THAT IT LOOKS BETTER IN MOBILE
.wrap {
.tns-outer {
> button {
display: none;
}
position: relative;
/* next and back button of slide */
.tns-controls {
z-index: 100;
position: absolute;
top: 40%;
width: 100%;
padding: 0 5px;
display: flex;
justify-content: space-between;
button {
border: none;
outline: none;
background: transparent;
color: transparent;
width: 20px;
height: 20px;
background : {
size: cover;
position: center;
repeat: no-repeat;
}
}
button[data-controls=prev] {
background-image: url("../src/Assets/images/section-top-slide/previous-3.png")
}
button[data-controls=next] {
background-image: url("../src/Assets/images/section-top-slide/next-3.png")
}
}
.tns-ovh {
.tns-inner {
.tns-slider {
/* each item of slider is a div named slide-item */
.slide-item {
.background-image {
height: 150px;
background: {
position: center 0;
repeat: no-repeat;
size: cover;
}
}
.slide-caption {
text-align: center;
.title {
font-weight: bold;
font-size: 16px;
margin-bottom: 0;
}
.link {
color: white;
background: $color-red;
display: inline-block;
padding: 2px 5px;
border-radius: 3px;
font-size: 14px;
font-weight: bold;
}
}
}
.slide-item.item-1 {
.background-image {
background-image: url("../src/Assets/images/section-top-slide/tot.webp")
}
}
.slide-item.item-2 {
.background-image {
background-image: url("../src/Assets/images/section-top-slide/arsenal.jpg")
}
.title {
text-shadow: 1px 1px 3px $color-red;
}
}
.slide-item.item-3 {
.background-image {
background-image: url("../src/Assets/images/section-top-slide/mc.jpg")
}
.title {
text-shadow: 1px 1px 3px #5fa5e3;
}
}
}
}
}
}
}
}
}
}
}
/*--- end top slide ---*/
When I click on a thumbnail, I'd like it to display in color and the other thumbnails as grey.
So When you click on a thumbnail is active and to illustrate I want to have the thumbnail in color, and the other thumbnails in grey because they are inactive.
This is what I'd like to achieve:
Vue.component('carousel', {
template: `
<div class="card-carousel" >
<div class="thumbnails">
<div
v-for="(image, index) in images"
:key="image.id"
:class="['thumbnail-image', (activeImage == index) ? 'active' : '']"
#click="activateImage(index)">
<img :src="image.thumb"/>
</div>
</div>
<div class="containe-carousel">
<span> {{currentImage.text}}</span>
<div class="photoshop-screenshot">
<img :src="currentImage.big" alt="">
</div>
<div class="card-img">
<img :src="currentImage2.big2" alt="">
</div>
</div>
</div>
`,
computed: {
currentImage() {
return this.images[this.activeImage];
},
currentImage2() {
return this.images[this.activeImage];
}
},
data() {
return {
activeImage: 0,
}
},
methods: {
activateImage(imageIndex) {
this.activeImage = imageIndex;
},
},
props: ['images']
});
.section{
background-color: black;
}
.card-carousel {
user-select: none;
position: relative;
}
.containe-carousel {
padding-top: 5%;
}
.thumbnails {
display: flex;
justify-content: space-evenly;
flex-direction: row;
}
.thumbnail-image {
display: fixed;
align-items: center;
cursor: pointer;
padding: 2px;
}
.thumbnail-image > img {
width: 100%;
height: auto;
transition: all 250ms;
filter: grayscale(100%);
}
.thumbnail-image:selected> img {
box-shadow: 2px 2px 6px 1px rgba(0,0,0, 0.5);
visibility: hidden;
filter: none;
}
.card-img {
position: relative;
}
.card-img > img {
margin: 0 auto;
padding-top: 7%;
z-index: 2;
}
.photoshop-screenshot {
position:absolute;
z-index: 1;
width: 70%;
right:-80px;
bottom:-130px;
}
.containe-carousel span {
color: white;
font-weight: bold;
box-shadow: -0.3125em 0.3125em 0 0 rgba(0, 0, 0, 0.15);
}
<section class="section" id="app">
<div class="container">
<div class="text-center" style="margin:0px 50px">
<div class="heading-underscore">
<h2 class="dk-5q-color">
<?php say("X50Q-dashboard-title"); ?>
</h2>
</div>
</div>
<div class="columns">
<div class="column ">
<div class="card-content">
<carousel
:starting-image="0"
:show-progress-bar="true"
:images="images"
></carousel>
</div>
</div>
</div>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.13/dist/vue.js"></script>
<script src ="/x/x50q-rgb-mechanical-keyboard/x50q-cloud-js.js"></script>
<script>
var app = new Vue({
el: '#app',
data() {
return {
images: [
{
text : 'Photoshop',
id: '1',
big: '/images/das-keyboard-x50q/photoshop-profile.PNG',
big2: '/images/das-keyboard-x50q/photoshop-screenshot.png',
thumb: '/images/das-keyboard-x50q/photoshop-logo.jpg'
},
{
text : 'Aurocad',
id: '2',
big: '/images/das-keyboard-x50q/autocad-profile.png',
big2: '/images/das-keyboard-x50q/autocad-screenshot.png',
thumb: '/images/das-keyboard-x50q/autocad-logo.png'
},
{
text : ' Counter-Strike',
id: '3',
big: '/images/das-keyboard-x50q/counterstrike-profile.png',
big2: '/images/das-keyboard-x50q/counterstrike-screenshot.jpg',
thumb: '/images/das-keyboard-x50q/counterstrike-logo.png'
},
{
text : 'League of Legends',
id: '4',
big: '/images/das-keyboard-x50q/leagueoflegends-profile.png',
big2: '/images/das-keyboard-x50q/leagueoflegends-screenshot.png',
thumb: '/images/das-keyboard-x50q/leagueoflegends-logo.jpg'
}
],
}
}
});
</script>
I'd rotate the filter from .thumbnails to .thumbnail-image>img instead and add a filter: none; to .thumbnail-image:active>img
Your CSS should look like this:
.thumbnails {
display: flex;
justify-content: space-evenly;
flex-direction: row;
}
.thumbnail-image {
display: fixed;
align-items: center;
cursor: pointer;
padding: 2px;
}
.thumbnail-image>img {
width: 100%;
height: auto;
transition: all 250ms;
filter: grayscale(100%);
}
.thumbnail-image:active>img {
box-shadow: 2px 2px 6px 1px rgba(0, 0, 0, 0.5);
visibility: hidden;
filter: none;
}
The problem is that when you add the grayscale filter to the container of class thumbnails, you are essentially overwriting anything that may have been set inside. If you want to affect the thumbnail images, you should make it as specific as possible, that's why .thumbnail-image>img is your primary target. Furthermore, when you click on the thumbnail you need to undo this change so .thumbnail-image:active>img is your override.
To achieve the wished result add this attribute class="active" to the img tag as follow:
<img :src="image.thumb" class="active"/>
and add the following rule to your CSS :
.active{
filter: sepia(100%) hue-rotate(19deg) saturate(98) brightness(98%) ;
border:3px solid #fff;
}
this gives a light green color but you could change the filter functions to achieve the desired colour.
I wrote some code with three things in mind:
Highlighting a selection's border using 'on click'.
Selecting one item will remove the highlight from the other item.
The ability to deselect each item on click.
I've managed to get everything working for the most part, but I don't particularly like how complex the code is for the radial dot that appears when one item is selected.
Below is an example of what I'm talking about, particularly I'm looking for ways to refactor the code below into something a little more legible (shorter).
$(this).children('.radial').children().toggleClass('checked').parents('.itembox')
.siblings().children('.radial').children().removeClass('checked');
Here's a working example for more context (line 10):
var raceInternet = false;
var racePhone = false;
var raceTv = false;
$(function() {
var $targetDiv = $('#race-internet > .itembox');
var $radialDot = $('.radial > .center-dot');
$targetDiv.on('click', function() {
$(this).toggleClass('user-selected').siblings().removeClass('user-selected');
//Is it possible to refactor Line 10?
$(this).children('.radial').children().toggleClass('checked').parents('.itembox').siblings().children('.radial').children().removeClass('checked');
if ($targetDiv.is('.user-selected')) {
raceInternet = true;
} else {
raceInternet = false;
}
})
})
.itembox-container {
display: flex;
}
.boxes-2 {
width: calc((100% - 25px)/2);
margin: 10px;
padding: 10px;
}
.itembox {
position: relative;
display: inline-block;
border: 5px solid #e8e8e8;
border-radius: 10px;
cursor: pointer;
}
.user-selected {
border: 5px solid #E16E5B;
}
.itembox h4 {
color: #22ddc0;
font-weight: 700;
}
span.price {
display: inline-block;
font-weight: 400;
float: right;
color: #22ddc0;
}
.itembox > ul {
list-style: none;
}
.itembox > ul > li {
line-height: 3;
}
.radial {
position: absolute;
float: right;
height: 35px;
width: 35px;
padding: 2px;
border: 5px solid #e8e8e8;
border-radius: 50%;
top: 43%;
right: 10px;
}
.center-dot {
display: none;
position: relative;
height: 21px;
width: 21px;
background-color: #E16E5B;
border-radius: 50%;
}
.checked {
display: block;
}
.prime-aux:first-of-type {
top: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container">
<!-- Primary Content Container -->
<div class="prime-aux">
<div id="race-internet" class="itembox-container">
<div class="itembox boxes-2">
<h4>Gigabit Internet <span class="price">$60/mo</span></h4>
<ul>
<li>1,000 Mbps</li>
<li>No data caps</li>
</ul>
<div class="radial">
<div class="center-dot"></div>
</div>
</div>
<div class="itembox boxes-2">
<h4>Basic Internet <span class="price">$25/mo</span></h4>
<ul>
<li>25 Mbps</li>
<li>No data caps</li>
</ul>
<div class="radial">
<div class="center-dot"></div>
</div>
</div>
</div>
</div>
</section>
<!-- Primary Content Container End -->
View on JS Fiddle
You can eliminate a lot of your jQuery by just leveraging CSS. Typically, if I want to toggle a feature, I have it either display: block; or display: none; based upon a CSS selector. Then, I just use jQuery to toggle the parent element's class name. So for example:
.item.selected .checkmark {
display: block;
}
.item .checkmark {
display: none;
}
$('.item').click(function(){ $(this).toggleClass('selected') });
JSFiddle