Hover + Opacity change is causing double tap on iOS safari - javascript

I have a form that is using Opacity: 0 by default, and Opacity: 1 when clicked. This is causing a double click issue in iOS. I see this is a known issue and has been discussed many times regarding links. Disabling the Opacity or removing the :hover effect fixes this issue, but I cannot access the css directly.
My issue is that I am bringing in a .css file that another team owns. So I cannot make changes directly to the .css file.
Is there a way I can override these css values?
js form using formik
<form action="#" novalidate="">
<div class="form__input">
<div class="example-tootip">
<span class="input__contain">
<input name="phoneNumber" type="tel" inputmode="numeric"
autocomplete="off" title="Please fill out this field" aria-label="phoneNumber"
placeholder="000-000-0000" required="" value="">
<label class="input__title" for="example-phoneNumber">Phone number</label>
</span>
</div>
</div>
</form>
css
form input {
opacity: 0
}
.input__contain + input:focus, .input__contain + input:hover, .input__contain + input:valid {
border-radius: inherit;
opacity: 1
}
What I've tried but did not work:
/* iOS bug causing double tap issue */
#media (max-width: 767px) and (hover: none) and (pointer: coarse) {
form input {
opacity: 0;
}
.input__contain + input:hover {
border-radius: inherit !important;
opacity: 1 !important
}
}
#media (max-width: 767px) and (hover: hover) {
form input {
opacity: 0;
}
.input__contain + input:hover {
border-radius: inherit !important;
opacity: 1 !important
}
}

Related

How to set animation to flip to a different component in angular?

First question here. Please bear if I missed out anything. I'll try to add more details as soon as mentioned.
In my angular project, I have regular login and register form components and want to implement the flip animation to transition between them.
On click, the parent div has a flip animation and it "flips" from one component "front" to another "back" and vice-versa. The problem is that since the "back" component goes through transform: rotateY(180deg); the component's form field and animations don't work properly.
Due to this, even simple hover animations did not work as expected.
How should I implement this transition for both components + animations to work as expected?
Thank you for your time!
I followed the flip animation method given here but it is probably works fine just for display data and has problems when we put in a component with animations to the "back" side.
Adding a gif for better understanding of the entire problem : Entire problem in working
It's difficult know what happens.
I imagine you have any kind of confict with the name of some class of there're a problem using position absolute in your cards. check the "z-index" of your class. (I feel that the "border" you see is the border or the input in "front" - try enclosed each "face" in a div with position relative-)
With this .css
.scene {
perspective: 600px;
max-width:400px;
margin:auto auto 1rem;
}
.card {
position: relative;
transition: transform 1s;
transform-style: preserve-3d;
box-shadow: 0 .5rem 1rem rgba(0,0,0,.15);
background: white;
}
.card__face {
float:left;
width:100%;
margin-right: -100%;
backface-visibility: hidden;
}
.card__face div{
padding:1rem;
background: white;
display:flex;
flex-direction: column;
backface-visibility: hidden;
}
.card::after{
display:block;
content:'';
clear:both;
}
.card__face--back {
transform: rotateY( 180deg );
}
.card.is-flipped {
transform: rotateY(180deg);
}
And this .html
<div class="scene">
<div #card class="card" [class.is-flipped]="toogle">
<div class="card__face card__face--front">
<div>
<mat-form-field appearance="outline">
<mat-label>Input front</mat-label>
<input matInput />
</mat-form-field>
<button mat-raised-button color="primary" (click)="toogle=!toogle">
click
</button>
</div>
</div>
<div class="card__face card__face--back">
<div>
<mat-form-field appearance="outline">
<mat-label>Input back</mat-label>
<input matInput />
</mat-form-field>
<button mat-raised-button color="accent" (click)="toogle=!toogle">
click
</button>
</div>
</div>
</div>
</div>
In this stackblitz that use material-angular looks like work
NOTE: It's necessary add in styles.css
.scene .mat-mdc-raised-button .mdc-button__label{
z-index: 0;
}
Because the raised-button add to the span a z-index:0

How to impact different class or HTML elements when hovering over a button?

I have a button in React and when I hover over it a funky saw animation happens. However, the effect I truly want is for the H1 tag on the page to have the saw animation in the background occur when I hover over the button. Yet, whenever I add a className and try to target that in the button:hover css, I get no effect. I've tried .btn:hover h1 and .btn:hover."classname" and a number of other combinations. yet none work.
How can I target a class, div, or h1 when hovering over a button that is not directly connected to the class, div, or h1 that will have the effect?
The current CSS I'm using for this, which works for the button itself, is:
.btn {
color: black;
}
.btn:hover {
animation: sawtooth 0.35s infinite linear;
background: linear-gradient(45deg, #d3f169 0.5em, transparent 0.5em) 0 0 / 1em 1em
, linear-gradient(-45deg, #d3f169 0.5em, transparent 0.5em) 0 0 / 1em 1em;
color: adjust-hue($color,180);
}
#keyframes sawtooth {
100% {
background-position: 1em 0;
}
}
The template I have is:
return (
<div className="App">
<h1>Question Genie</h1>
<button className="btn" onClick={this.displayQuestion}>View Unanswered Questions</button>
{questions}
</div>
);
}
}
You can use a next sibling selector (~) and flexbox column-reverse to accomplish this. The main issue here is that there is no previous sibling selector in CSS
So, you can reorder the HTML so that <h1> is after the <button>, like this:
<div class="App">
<button class="btn" onClick={this.displayQuestion}>View Unanswered Questions</button>
<h1>Question Genie</h1>
</div>
and then you can use flex-direction: column-reverse; (or even order: -1 on the button) to make the <h1> appear above the <button>
CSS:
.App {
display: flex;
flex-direction: column-reverse;
align-items: flex-start;
}
.btn:hover ~ h1 {
animation: sawtooth 0.35s infinite linear;
... rest of the stuff
}
Here's the codepen: https://codepen.io/palash/pen/ZvVNav
Be sure to check flexbox support here https://caniuse.com/#feat=flexbox
Just use javascript...
<button onmouseover="H1_ID.style.animation='sawtooth 0.35s infinite linear';" onmouseout="H1_ID.style.animation='none';"></button>

How to remove anchor from url after checking radio button?

I need to remove an anchor from url or "untarget" the element when i click on radio button.
Here's the code, when i click on a link from the first page i want to have control on specific element on the second page (for example changing font color) but the problem I am struggling with is i can't "untarget" it by using css after i choose sth else from the radio button list and there are simultaneously highlighted two links at the same time.
First page:
OFERTA
<ul>
<li>webdesign</li>
<li>grafika</li>
<li>kampania</li>
</ul>
Second page:
<style type="text/css">
*{
clear: both;
}
label:target{
color: red;
}
#webdesign:target ~ #wd, #grafika:target ~ #gr, #kampania:target ~ #kp{
visibility: visible;
z-index: 10;
}
input[type=radio]:checked + #webdesign, input[type=radio]:checked + #grafika, input[type=radio]:checked + #kampania{
color: red;
}
input[type=radio]:checked + #webdesign ~ #wd, input[type=radio]:checked + #grafika ~ #gr, input[type=radio]:checked + #kampania ~ #kp{
visibility: visible;
z-index: 100;
}
#wd, #gr, #kp{
width: 500px;
height: 100px;
visibility: hidden;
position: absolute;
z-index: 0;
}
#wd{
background: red;
}
#gr{
background: green;
}
#kp{
background: blue;
}
</style>
HOME
<input type="radio" id="webdesign1" name="labels">
<label for="webdesign1" id="webdesign">webdesign</label>
<input type="radio" id="grafika1" name="labels">
<label for="grafika1" id="grafika">grafika</label>
<input type="radio" id="kampania1" name="labels">
<label for="kampania1" id="kampania">kampania</label>
<div id="wd"></div>
<div id="gr"></div>
<div id="kp"></div>
It's simple. Attach the first change event of any radio, than remove the hash part from the URL.
Assuming you are using jQuery:
$('input:radio').one('change', function(){
location.hash = '';
});
http://jsbin.com/wesotoh/edit?html,js

Slider of images with undefined height

I'm trying to create a slider of images (previous/next) so the images slide to the left when I click "previous" and to the right when I click "next" with 0.5s of slowness, so it takes some animation. And when I reach the last image and click "next", I want images to "run backwards" to the first one, the same when I'm in the first one and click "previous", so it "run forward" until the last one.
I want the same behaviour this JSFiddle shows. (but I don't need the timer to move images automatically and don't need the "triggers" buttons, just "previous" and "next").
The problem here is that my images don't have fixed size. I define a width in percentage and can't define a height because I have responsive design, the image resizes as I resize the browser window.
The jQuery to previous/next actions is pretty easy, but I just can't find a way to add this animation when I remove/add the "active" class to my images (so they become visible or not).
I have already tried putting all images side by side and showing only the first one (setting container width equals to image width), so when I click "next" I just "move" the container to the left so it begins to display the next image, but it doesn't work because once I can't define the height of the images, they will appear underneath each other, not side by side.
JSFiddle
HTML
<div class="images">
<img class="active" src="1.jpg">
<img src="2.jpg">
<img src="3.jpg">
</div>
<div class="previous">previous</div>
<div class="next">next</div>
CSS
img {
width: 100px;
display: none;
float: left;
}
img.active {
display: block;
}
jQuery
$('.next').on('click', function() {
var active = $('img.active');
var next = active.next('img');
if (next.length) {
active.removeClass('active');
next.addClass('active');
} else {
active.removeClass('active');
$('.images img:first').addClass('active');
}
});
Well the problem is the height for sliding.
First you need to have an element which is the "picture frame" which hold all the other images. That's important.
For better imagination a picture:
Now you have several technics to show and hide images. One could be to set the opacity. When using transition: opacity .15s ease-in-out; The one Picture is fading out and the next on is fading in.
For the slideshow effect is given to the position of the visible image to its width to the left and the image previously purely new to his wide to the right and then to 0. Thus, moves the current picture on the left the frame out and the new comes out right in.
And here is the difficulty if the height is not the same. If the current image 300px high and the new 400px, so the image frame here would adjust his height immediately once the new image start to be visible.
The content below would start to jump with each slide.
Is that so desired???
If yes, I can make you an example how it works.
You can actually do this in Pure CSS!
You use an ID and a label (with a for attribute=for the targeted id)
That's basically it. All you have left is to style it! (Forked from Joshua Hibbert's Pen)
body {
background: #f7f4e2;
}
/* Slides */
.slider input {
display: none;
}
/* Buttons */
.slider label {
display: none;
cursor: pointer;
position: absolute;
top: 6em;
left: 50%;
transform: translateX(-50%);
color: #fff;
background: #000;
padding: 1.36em .5em;
opacity: .6;
font-size: 19px;
font-family: fantasy;
font-weight: bold;
transition: .25s;
}
.slider label:hover {
opacity: 1;
}
.previous {
margin-left: -188px;
}
.next {
margin-left: 188px;
}
#slide1:checked ~ .buttons .slide1 {
display: block;
}
#slide2:checked ~ .buttons .slide2 {
display: block;
}
#slide3:checked ~ .buttons .slide3 {
display: block;
}
#slide4:checked ~ .buttons .slide4 {
display: block;
}
/* Images */
.slider {
position: absolute;
top: 50%;
left: 50%;
width: 400px;
height: 300px;
margin-top: -150px;
margin-left: -200px;
white-space: nowrap;
padding: 0;
float: left;
transition: .25s;
overflow: hidden;
box-shadow: 0 0 0 3.12px #e8e8e8,
0 0 0 12.64px #eaebe4,
0 0 0 27.12px #000,
0 24px 3.824em 5.12px #000;
}
.slide {
width: 500em;
transition: .25s;
}
.slider img {
float: left;
width: 400px;
height: 300px;
}
#slide1:checked ~ .slide {
margin: 0;
}
#slide2:checked ~ .slide {
margin: 0 0 0 -400px;
}
#slide3:checked ~ .slide {
margin: 0 0 0 -800px;
}
#slide4:checked ~ .slide {
margin: 0 0 0 -1200px;
}
<div class="slider">
<input type="radio" name="slide" id="slide1" checked="true" />
<input type="radio" name="slide" id="slide2" />
<input type="radio" name="slide" id="slide3" />
<input type="radio" name="slide" id="slide4" />
<div class="buttons">
<!-- Slide 1 -->
<label for="slide4" class="slide1 previous"><</label>
<label for="slide2" class="slide1 next">></label>
<!-- Slide 2 -->
<label for="slide1" class="slide2 previous"><</label>
<label for="slide3" class="slide2 next">></label>
<!-- Slide 3 -->
<label for="slide2" class="slide3 previous"><</label>
<label for="slide4" class="slide3 next">></label>
<!-- Slide 4 -->
<label for="slide3" class="slide4 previous"><</label>
<label for="slide1" class="slide4 next">></label>
</div>
<div class="slide">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/872485/coldchase.jpg">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/980517/icehut_sm.jpg">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/943660/hq_sm.jpg">
<img src="http://dribbble.s3.amazonaws.com/users/322/screenshots/599584/home.jpg">
</div>
</div>
Although this method is the most compatible (except for old versions of IE) and depending on how you animate it this method can be more time consuming than a JS method, but can also be faster, it just depends on how you want the animations to go, or you could use a css library that does this for you.
Here are some css image sliders I recommend.
10 Amazing Pure CSS3 Image Sliders
http://bashooka.com/coding/pure-css3-image-sliders/
Pure CSS Image Slider Without Javascript #Codeconvey is a good solution for what you're looking for, but lots of CSS
http://codeconvey.com/pure-css-image-slider/
The downside to these along with what you're working on is that you can't touch to slide on a phone or tablet which is more common now a days with photo galleries.
I recommend checking out Fotorama it's amazing! :)
Perhaps not the ideal situation but at least it will give you an idea. you can use the animation function of jQuery and I also changed your code a bit. See demo here
Within your HTML I would say this:
<div id="images">
<div class="images-wrapper">
<img src="http://www.cutestpaw.com/wp-content/uploads/2016/02/In-the-spotlight.jpg">
<img src="http://www.cutestpaw.com/wp-content/uploads/2016/02/Bath-time-with-ducky.jpg">
<img src="http://www.cutestpaw.com/wp-content/uploads/2016/03/FB_IMG_1452981788903.jpg">
<img src="http://www.pictures-of-cats.org/images/Pixiebob-cat-list-of-cat-breeds-pictures-of-cats.jpg" />
</div>
</div>
<div class="previous">
previous
</div>
<div class="next">
next
</div>
and within your jQuery code you can animate the width:
$('.images-wrapper img:gt(0)').hide();
$('.next').click(function() {
$('.images-wrapper img:first-child').animate({width:'toggle'},350).next().fadeIn().end().appendTo('.images-wrapper');
});
$('.previous').click(function() {
$('.images-wrapper img:first-child').animate({width:'toggle'},350);
$('.images-wrapper img:last-child').prependTo('.images-wrapper').fadeOut();
$('.images-wrapper img:first-child').fadeIn();
});
With this implementation the whole process of changing and adding the active class to the image is removed and replaced by animation functions
Simplest solution (I think) is to force the items to be of the same size, by placing them in a div. You can even have the div show the image without the use of an img tag, by using the background-image CSS feature (see http://www.w3schools.com/css/css3_backgrounds.asp for more details).
The item CSS could look like:
.item {
background-size: contain;
background-position: center;
}
and in each item in the HTML:
<div class='item' style='background-image: url(img1.jpg)' />
<div class='item' style='background-image: url(img2.jpg)' />
<div class='item' style='background-image: url(img3.jpg)' />
I finally got there.
HERE is the fiddle with the solution I developed.
The main problem in the implementation of this image slider was that images, althought were all the same size, have dynamic width (defined in % on CSS) and dynamic height (not defined on CSS).
The solution was basically put an "fake" image (with opacity: 0) inside my container so the container get the actual size of images I will use in the slider; put a div to "hold" the real images with position: absolute and give it a width calculted by number of images * 100%; and for last, give each image in my slider a width of x%, based on number of images.
In the jQuery, I "move" the "images holder div" always by %, never by static values, once the width of everything can change if I resize the window.
If you start to slide the images to the left and right and then resize the window, you will see that it continues to work perfectly.
I have implemented using css3 animations. However this will require manipulating animation values in css every time a slide gets added or removed.
#keyframes slideAnim {
0% {
transform: translateX(0)
}
12.5% {
transform: translateX(0%);
}
25% {
transform: translateX(-25%);
}
37.5% {
transform: translateX(-25%)
}
50% {
transform: translateX(-50%)
}
62.5% {
transform: translateX(-50%)
}
75% {
transform: translateX(00%);
}
89.5% {
transform: translateX(00%)
}
100% {
transform: translateX(00%)
}
}
Here the animation values are set such that there is a pause between slide transitions. I have added a parent frame to show only one slide at a time.
Please refer this fiddle.

What are the drawbacks in my form design logic?

$('.login_links_register').click(
function () {
$("body").addClass("removeScroll");
$(".login_form_container").show();
$("#registerForm").show();
$(".login_form_container").css('top', '0px');
/*$('.overlay').addClass('visible');*/
});
$(document).on('click', ".close_button",
function (event) {
var negativeHeight = -1 * ($('.login_form_container').offset().top + $(this).parents('.login_form_container').height());
$(".login_form_container").css('top', negativeHeight);
//$(".login_form_container").slideUp();
/*$('.overlay').removeClass('visible');*/
setTimeout(function () {
$('.overlay').addClass('displayNone');
$(".login_links").removeClass("popup_opened");
$("#loginForm").hide();
$("#registerForm").hide();
$("body").removeClass("removeScroll");
}, 500); /*Execute a set of statements after a statement completion. To make it faster reduce the milliseconds*/
});
input[type="text"], input[type="password"] {
border: 1px solid #aaa;
}
.header2 {
background-color:#E1E3E5;
/*have to change */
/*padding: 15px 0;*/
}
.right {
float: right;
clear:both;
/*To avoid problems caused by float - but check it may cause some problems check for it*/
}
/*Instead overflow:auto(or) hidden*/
.clearboth::after {
clear: both;
content:"";
display: block;
visibility: hidden;
}
.displayNone {
display: none;
}
.emailField, .passwordField {
width: 200px;
padding: 5px;
}
/*to remove unnecessary margin caused by ul element */
.login_links_list {
/*margin:10px 0;*/
padding: 0px;
margin: 0;
}
.login_links.right {
margin-right: 70px;
/*Same as Login container*/
}
/*login_link ul li element*/
.login_links_list_ele, .login_links_list_label
/*can apply al these properties to anchor tag instead li */
{
float: left;
list-style: outside none none;
transition: all 0.5s ease 0s;
}
.login_links_list_label {
padding: 15px;
}
.login_links_register, .login_links_login {
/*border-right:1px solid #ccc;
border-left: 1px solid #ccc;*/
float:left;
padding:15px;
}
.login_form_container.right {
border: 1px solid #aaa;
margin-right: 70px;
/* For better alignment. Instead kissing the edge of the screen*/
transition: all 1s ease 0s;
position: relative;
top: -173px;
/* For Styling. instead displayNone*/
z-index: 2;
}
/*positioning close button*/
.close_button {
cursor: pointer;
float: right;
position: relative;
top: -15px;
right: -15px;
width: 17px;
}
.loginDiv.right {
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="headers header2 clearboth" id="header2">
<nav class="login_links right">
<ul class="login_links_list right">
<li class="login_links_list_label">Are you a member?</li>
<li id="login_links_register" class="login_links_list_ele login_links_register">Register</li>
<li id="login_links_login" class="login_links_list_ele login_links_login">login</li>
</ul>
</nav>
</div>
<div class="login_form_container right displayNone">
<form class="right registerForm" id="registerForm" method="POST" action="lib/registration_validate.php">
<img class="close_button close_popup close_register_form" src="image/close_icon.png"></img>
<div class="register_input">
<input autocomplete="off" class="register_links emailID" type="text" placeholder="Email ID" name="email"/>
</div>
<div class="register_input">
<input type="password" autocomplete="off" class="register_links password" placeholder="Password" name="password"/>
</div>
<div class="register_input">
<input autocomplete="off" class="register_links conf_password" type="password" placeholder="Confirm Password" name="confirmPassword"/>
</div>
<div class="register_submission">
<input type="submit" value="Register" name="submit" class="register_button"></input>
<div class="custom_checkbox_div">
<input id="custom_checkbox" class="custom_checkbox_input" type="checkbox" value="Remember Me" name="remMeCheckbox"/>
<label for="custom_checkbox" class="custom_checkbox_label"></label>
<label class="custom_checkbox_string" for="custom_checkbox">Remember Me</label>
</div>
</div>
This is in my HTML page. I have negative top to show and hide forms for better views.
Please clear me the following doubts
1) I have to send the data to server when user submits form. I do client-side and server-side validation. If client-side validation fails, I 'll show the errors in the form itself. If there is any server-side error, how do i show this in the form?
My ideas:
I have to insert some php error tags in the html page and change my filetype to php from html so that if there is any server side error i ll insert the error in those tags.
<span class="error">* <?php echo $emailErr;?></span>
Something like the above.
(or)
Take the user to another php page where user re-enter the details. and handles all the error in the same page.
2) What are the problems with this type of negative top form design?
Please let me know the problems and suitable solutions so that i get clean design. I don't want the code only the idea.
There are couple of ways to do it but I am gonna stay low here by giving more of a hint to what you can do.
Using AJAX to submit form?
If the validation fails in PHP...
Create an associative array containing all the error messages and a key like submitError set to TRUE.
json_encode the array and die or return it.
In your JavaScript AJAX success callback, check for the existence of submitError key in the response.
If true, parse and display all messages from the JSON response you received. Done!
NOT using AJAX?
You can utilize $_SESSION to store the errors and related messages & set a flag for error.
When the page loads/submits, check if $_SESSION contains that flag.
If it does, pull the messages from session and display to the user.
Once displayed, clear those things from $_SESSION
These things can be done for small applications. If you are using some kind of framework like CodeIgniter or Laravel, you may want to check their session flash methods.
About Negative Top Form Design
I don't see much of a problem there unless it's covering up something vital beneath it when opened. Specially on mobile version( if you plan to do that).

Categories

Resources