Pseudo-element appear on focus but not on click - javascript

The idea is to enable those users that browse through on a website with their keyboard, using tab to get some really meaningful feedback of where their focus is currently at, beyond the default blue outline which usually is missed and or break visual design.
You can in fact create an ::after pseudo-element to appear only on focus state, and you can preview the snippet below that it works fantastic (probably not on old browsers).
The problem is, is it possible to hide the arrow so the user doesn't see it when he clicks on the button (which triggers :active state while click is pressed but also :focus from the moment it has been pressed), but still have it there if someone is using tab to browse through the website.
I cannot think of any way of using CSS for achieving this. Would it only be possible through JavaScript? Google is doing it, if you search for something and press tab and browse with your keyboard, you'll see where your focus is with an arrow on the left.
EDIT: I've seen the other question. And it's helpful for a JavaScript approach. But my question is about whether is possible to do it purely with CSS. For example I've just updated chaining :active:focus in the selector and the arrow now appears only once you release the click.
.row{
text-align: center;
margin: 1rem 0;
}
button{
position: relative;
text-shadow: 0 0 0;
box-shadow: 0 0 0;
background: #eee;
border: 0;
margin: 0;
padding: 1rem 2rem;
transition: all 0.2s ease;
}
button:hover{
background: dodgerblue;
color: #fff;
}
button:active{
top: 2px;
background: #eee;
color: #888;
}
button:focus{
outline: none;
}
button:focus::after{
content: "▲";
position: absolute;
bottom: -1.5rem;
font-size: 1.5rem;
font-weight: bold;
color: dodgerblue;
left: 0; right: 0;
margin: auto;
animation: pulsing 1s ease infinite;
}
button:active:focus::after{
content: "";
}
#keyframes pulsing{
0%,
100%{
bottom: -1.5rem;
}
50%{
bottom: -1.75rem;
}
}
<div class="row">
<button>First</button>
<button>Second</button>
<button>Third</button>
<button>Fourth</button>
</div>

I don't think there is a pure CSS solution for this problem. You can try to differ between mouse and keyboard with using the :hover pseudo class, but the result is only fine as long you are not leaving the focused button...
Edit: I added a body:hover workaround, maybe its sufficient for you?
.row{
text-align: center;
margin: 1rem 0;
}
button{
position: relative;
text-shadow: 0 0 0;
box-shadow: 0 0 0;
background: #eee;
border: 0;
margin: 0;
padding: 1rem 2rem;
transition: all 0.2s ease;
}
button:hover{
background: dodgerblue;
color: #fff;
}
button:active{
top: 2px;
background: #eee;
color: #888;
}
button:focus{
outline: none;
}
button:focus::after{
content: "▲";
position: absolute;
bottom: -1.5rem;
font-size: 1.5rem;
font-weight: bold;
color: dodgerblue;
left: 0; right: 0;
margin: auto;
animation: pulsing 1s ease infinite;
}
button:active:focus::after,
button:hover::after,
body:hover button::after{
content: "" !important;
}
body {
height: 100vh;
width: 100vw;
}
#keyframes pulsing{
0%,
100%{
bottom: -1.5rem;
}
50%{
bottom: -1.75rem;
}
}
<div class="row">
<button>First</button>
<button>Second</button>
<button>Third</button>
<button>Fourth</button>
</div>

Related

How to Hide the Back Side of Door Once Open? Vanilla JS/CSS Door Animation

So I have a door animation using vanilla JS with CSS for the styling. Is there a way to hid the backside of the door when it's open?
As well as making the door not clickable. (I don't have it as toggle, but you can still interact with the button.)
Basically I just want a back background and not see the backwards "1" when the door is open.
Any ideas on how to make that happen? I imagine it's adding another div with style, but I really am not sure after goofing around with this for a while.
Cheers!
Codepen here: https://codepen.io/LovelyAndy/pen/LYZKEvB
HTML:
<div>
<div class="door-back">
<button class="door">1</button>
</div>
</div>
CSS
.door-back {
position: relative;
height: 105px;
width: 105px;
background-image: url("https://i.redd.it/e84gxikhoul21.jpg");
border-radius: 50px;
background-size: cover;
margin: 0 auto;
margin-top:50px;
}
.door {
position: absolute;
height: 105px;
width: 105px;
font-size: 1.5em;
color: white;
border: 2px solid goldenrod;
border-radius: 50px;
background: black;
cursor: pointer;
transform-origin: left;
transition: all 0.5s ease-in-out;
}
.doorOpen {
transform: perspective(1200px) translateZ(0px) translateX(0px) translateY(0px)
rotateY(-150deg);
}
.d1 {
top: 100px;
left: 60px;
}
JS
const doorEl = document.querySelector(".door");
doorEl.addEventListener('click', openTheDoor)
function openTheDoor() {
doorEl.classList.add("doorOpen");
}
Possible solution: change the text color on transition:
const doorEl = document.querySelector(".door");
doorEl.addEventListener('click', openTheDoor)
function openTheDoor() {
doorEl.classList.toggle("doorOpen");
}
.door-back {
position: relative;
height: 105px;
width: 105px;
background-image: url("https://i.redd.it/e84gxikhoul21.jpg");
border-radius: 50px;
background-size: cover;
margin: 0 auto;
margin-top: 50px;
}
.door {
position: absolute;
height: 105px;
width: 105px;
font-size: 1.5em;
color: white;
border: 2px solid goldenrod;
border-radius: 50px;
background: black;
cursor: pointer;
transform-origin: left;
transition: transform .5s ease-in-out,
color 0s .3s linear
}
.doorOpen {
transform: perspective(1200px) translateZ(0px) translateX(0px) translateY(0px) rotateY(-150deg);
color:black;
}
.d1 {
top: 100px;
left: 60px;
}
<div>
<div class="door-back">
<button class="door">1</button>
</div>
</div>
You can achieve both disable the click on door button and not to show the '1' after the door is open in CSS.
.doorOpen {
...other css
// you just need add this property which disables click
pointer-events: none;
color: black;
}
Making the text color black will make it complete black.
If you completely want to remove the text '1' then you can do like below.
const doorEl = document.querySelector(".door");
doorEl.addEventListener('click', openTheDoor)
function openTheDoor() {
doorEl.classList.add("doorOpen");
doorEl.textContent='';
}
These are two ways I can think of.
You can try to do something like this https://codepen.io/dom-the-dev/pen/MWeqaJq just have a button on the opposite side that acts like the back of the door
<div>
<div class="door-back">
<button class="door front">1</button>
<button class="door back">2</button>
</div>

why css transition is not working with js

<button className={this.state.isSaveDraft===true?
"cts_not_allowed stepper_btn_back" : "stepper_btn_back"} onClick={
this.state.isSaveDraft===false && this.approval_submitHandler} >
Update An
<p className='warning_message' >You have changed Metadata, please re calculate pre-opso</p>
</button>
.cts_not_allowed{
// pointer-events: none;
cursor: not-allowed !important;
position: relative;
transition: width 2s;
}
.warning_message{
display: none;
transition: 0.9s ease-in-out;
}
.cts_not_allowed:hover .warning_message{
display: block;
position: absolute;
bottom: 3vw;
right: 1vw;
// background-color: #ffffff;
border: 1px solid #ffffff;
width: 30vw;
color: red;
}
i tried everything also search a lot but dont know where the problem is in code mostly i used this transition with hover and it works for me iam using position relative and absolute thanks for help
Probably something like this:
.cts_not_allowed {
/* pointer-events: none; */
cursor: not-allowed !important;
position: relative;
transition: width 2s; /* is this used anywhere? */
}
.warning_message {
position: absolute;
bottom: 3vw;
right: 1vw;
/* background-color: #ffffff; */
border: 1px solid #ffffff;
width: 30vw;
color: red;
opacity: 0;
pointer-events: none;
transition: opacity 0.9s ease-in-out;
}
.cts_not_allowed:hover .warning_message {
opacity: 1;
pointer-events: auto;
}
Note that commenting out in CSS only works with /* ... */. CSS doesn't understand //, only SCSS does.
Also you cannot transition between display: none and display: block. Use opacity instead.
Depending on where it sits you might want to toggle pointer-events of your warning-message, too.

Whatsapp active chat list item animation

I was wondering if there is an easy way of creating the animation, similar to Whatsapp one.
When you are on chat screen and go back to chat list, an active element is highlighted gray for a moment (so it shows which chat was opened before).
Is there not complicated way of doing this in JS or CSS? Hopefully most of you guys know what I'm talking about. Unfortunately can't find any examples in the net...
Here is a example of how you could achieve the effect, but with no more details on your project i can't do more.
var li = $('li');
var messages = $('.messages');
var close = $('.close');
li.on('click', function(){
$(this).addClass('active');
messages.addClass('active');
});
close.on('click', function(){
messages.removeClass('active');
li.removeClass('active');
});
html,
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.info {
margin-bottom: 20px;
padding-left: 15px;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
background: #ececec;
padding: 10px;
border-bottom: 2px solid black;
cursor: pointer;
transition: background .2s .3s;
}
li.active {
background: gray;
transition: background .3s;
}
.messages {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
transition: transform .3s;
transform: translateX(100%);
padding: 20px;
}
.messages.active {
transform: translateX(0);
}
.close {
display: inline-flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
position: absolute;
right: 70px;
top: 30px;
background: black;
color: white;
border-radius: 50%;
font-size: 20px;
cursor: pointer;
}
.close:hover {
opacity: .7;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="info" >Click on a person, and close the discussion by clicking on the "X" to see the effect.</p>
<ul>
<li>Bob</li>
<li>Steven</li>
<li>Marie</li>
<li>Marc</li>
<li>Jack</li>
<li>Edouardo</li>
</ul>
<div class="messages">
A lot of messages bla bla ...
...
<span class="close">X</span>
</div>

Make arrow in button point down after menu slides out

I have a button that has an arrow appended to it when a user hovers over it. When clicked, a content div slides out in its wrapper using jQuery.slideToggle().
Once the div slides out, I want to make the arrow in the button rotate 180 degrees to signify that pressing it will make the content div go down if clicked again.
I made a JsFiddle to show what I have so far: https://jsfiddle.net/414mwv17/
What would be the best way to make the arrow point down after the button is clicked?
Create a new class for how you want the carat to appear :
#makeGroupButton span.rotate:after
{
transition: opacity 0.5s, top 0.5s, right 0.5s;
transform: rotate(135deg);
}
Note the class addition in the selector.
Then change the javascript/jQuery to just toggle that class:
$('#makeGroupButton').bind('click', function(){
$('#slideout').slideToggle(500);
$(this).children('span').toggleClass('rotate');
});
You can't directly select the :after and :before pseudo selectors with jQuery, so just changing the class, and adding CSS is customarily the easiest method.
Updated fiddle
Have started it for you to build on. Check this out and let me know your feedback. Thanks!
Added the following style:
#makeGroupButton span.open:after {
border: 3px solid #FFF;
border-top: none;
border-right: none;
margin-top: -15px;
}
and some js too:
$('#makeGroupButton').bind('click', function(event) {
event.preventDefault();
$('#slideout').slideToggle(500);
$(this).find('span').toggleClass('open');
});
#wrapper{
height: 500px;
width: 300px;
position:relative;
border: 2px solid blue;
}
#slideout {
height: 95%;
width: 95%;
border: 2px solid red;
position: absolute;
bottom: 0;
left: 2.5%;
}
#makeGroupButton
{
clear: both;
text-align: center;
color: white;
width: 220px;
background:black;
overflow: hidden;
transition: all 0.5s;
}
#makeGroupButton:hover, #makeGroupButton:active
{
text-decoration: none;
background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
}
#makeGroupButton span
{
display: inline-block;
position: relative;
padding-right: 0;
transition: padding-right 0.5s;
}
#makeGroupButton span:after
{
content: '';
position: absolute;
top: 0;
right: -20px;
opacity: 0;
width: 15px;
height: 15px;
margin-top: -5px;
background: rgba(0, 0, 0, 0);
border: 3px solid #FFF;
border-bottom: none;
border-left: none;
transition: opacity 0.5s, top 0.5s, right 0.5s;
transform: rotate(-45deg);
}
#makeGroupButton:hover span, #makeGroupButton:active span
{
padding-right: 30px;
}
#makeGroupButton:hover span:after, #makeGroupButton:active span:after
{
transition: opacity 0.5s, top 0.5s, right 0.5s;
opacity: 1;
border-color: white;
right: 0;
top: 50%;
}
#makeGroupButton span.open:after {
border: 3px solid #FFF;
border-top: none;
border-right: none;
margin-top: -15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="slideout" style="display: none;"></div>
</div>
<a href="#" id="makeGroupButton">
<span>New Group</span>
</a>
I would add a class rotate on click then apply the following css :
#makeGroupButton.rotate span:after {
top: 0px;
-webkit-transform: rotate(-228deg) !important;
}
I have update your js fiddle https://jsfiddle.net/414mwv17/2/.
A much cleaner way to do it would be use an arrow icon then just rotate that icon by 180 degrees.
Hope this helps

Artboard Style Layout Using CSS Transform Scale

I'd like to have the .container and .box scale in and out from the one I clicked on. The problem I'm running into is when I scale in and out, it scales in and out from the first .box div, not the one I clicked on.
Each .box will contain it's own unique content, so when viewing this in "Artboard" view (Zoomed Out), I want people to be able to see what's contained in that particular .box. When people click on one of the boxes, I want it to scale back to (1) to cover the viewport. And if the person is on the 4th .box and they click "Zoom Out", I want it to zoom out from that particular .box.
Each box will be the size of the viewport, which is how it's set up now.
Does anyone have a solution in CSS only? Or is this something that can be better accomplished in JS? I'm not a JS expert, I'm just getting into it, so I'm curious if there's something I can do in some simple JS.
Please see my codepen:
http://codepen.io/jareko999/pen/eZGLZB
HTML
<div class="bar">
<button class="zoomout" onclick="zoomOut()">Zoom Out</button>
</div>
<div class="container">
<div class="artboard">
<div class="box">
<i class="fa fa-diamond"></i>
</div>
<div class="box">
<i class="fa fa-bolt"></i>
</div>
<div class="box">
<i class="fa fa-flag"></i>
</div>
<div class="box">
<i class="fa fa-flask"></i>
</div>
</div>
</div>
CSS
body {
margin: 0;
padding: 0;
height: 100vh;
width: 100%;
background: #e1e1e1;
overflow-y: hidden;
}
.bar {
position: fixed;
display: flex;
flex-direction: row;
box-sizing: border-box;
bottom: 0;
width: 100%;
height: 80px;
background: white;
padding: 14px 0;
z-index: 1;
}
.zoomout {
-webkit-appearance: none;
border: none;
outline: 0;
width: 100px;
height: 40px;
margin: auto;
background: black;
color: white;
border-radius: 10px;
cursor: pointer;
}
.container {
height: 100vh;
width: 100%;
transition: .2s ease-out;
transform: scale(1);
}
.container-small {
height: 100vh;
width: 100%;
transition: .2s ease-out;
transform: scale(.7);
}
.artboard {
height: 100%;
width: 100%;
display: flex;
display: -webkit-flex;
background: #e1e1e1;
}
.box {
padding-top: 44vh;
box-sizing: border-box;
text-align: center;
flex-shrink: 0;
width: 100%;
height: 100%;
box-shadow: 0 2px 4px #a9a9a9;
background: linear-gradient(to right, #276cd6 , #00a651);
transition: .2s ease-out;
transform: scale(1);
}
.box-small {
padding-top: 44vh;
box-sizing: border-box;
text-align: center;
flex-shrink: 0;
width: 100%;
height: 100%;
box-shadow: 0 2px 4px #a9a9a9;
background: linear-gradient(to right, #276cd6 , #00a651);
transition: .2s ease-out;
transform: scale(.9);
cursor: pointer;
}
.box i {
color: #e1e1e1;
font-size: 3em;
}
.overflow {
overflow: hidden;
}
.remove {
display: none;
}
::-webkit-scrollbar {
width: 12px;
height: 4px;
}
/* Track */
::-webkit-scrollbar-track {
background: white;
-webkit-border-radius: 10px;
border-radius: 10px;
}
/* Handle */
::-webkit-scrollbar-thumb {
-webkit-border-radius: 100px;
border-radius: 100px;
background: #4099ff;
}
JS
$(document).ready(function() {
$('.container').addClass('overflow');
});
function zoomOut() {
$('.bar').addClass('remove');
$('.box').addClass('box-small');
$('.container').removeClass('overflow');
$('.container').addClass('container-small');
}
$('.box').click(function() {
$('.bar').removeClass('remove');
$('.box').removeClass('box-small');
$('.container').addClass('overflow');
$('.container').removeClass('container-small');
});
What you're trying to achieve can be done using a CSS only method.
This method relies on using location hashes (url.com#foobar) and the :target pseudo selector.
The :target pseudo selector allows you to target the element which has the id matching the location hash. For example, imagine you have an element with the id "foobar", the #foobar:target selector will only apply if you have navigated to url.com#foobar. You can create a link with the href attribute pointing #foobar to have a button trigger this pseudo selector.
In your case, you can apply the zoom out styles when the #container location hash is matched, and only show the slide matched by the location hash.
The drawback of this method is that you have to add ids, and add links to actually trigger the :target pseudo class.
My explanation might not be clear, so I put up this demo:
http://codepen.io/ntim/pen/ONxGJd

Categories

Resources