CSS3 animation every time class is applied (Firefox bug?) - class

There is some problem with CSS3 native animation I've bumped into with Firefox (tried in v17) while Chrome is ok.
The sample is also available on Codepen:
http://codepen.io/anon/pen/yxteC
The code is also duplicated below.
I apply some class to some element (tried to apply that with JS on hovering, but hovering by itself works absolutely the same way (:hover selector instead of .hover class)).
So, the problem is that in Firefox the animation triggers only once: the first time the class had been applied. Any next time it does not.
That works perfectly in Chrome. I did not test any other browsers though (IE still does not widely support that, and Opera... well, it does not bother me much for now).
One more detail: if not to hide/show internal element (display:none/block), then it works ok in Firefox (but that's obviously not a solution).
I would really ask not to add any comments related to general cleanliness and possible improvements of the code. That's just an example.
HTML:
<div>
<span>menu</span>
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
</div>
CSS:
ul
{
display: none;
}
div.hover ul
{
display: block;
}
div li
{
position: relative;
top: -10px;
}
div.hover li
{
-webkit-animation: filterAppear 0.5s;
-moz-animation: filterAppear 0.5s;
top: 0;
opacity: 1;
-webkit-animation: filterItemAppear 0.1s;
-moz-animation: filterItemAppear 0.1s;
-webkit-animation-fill-mode: backwards;
-moz-animation-fill-mode: backwards;
}
div.hover li:nth-child(1)
{
-webkit-animation-delay: 0.15s;
-moz-animation-delay: 0.15s;
}
div.hover li:nth-child(2)
{
-webkit-animation-delay: 0.35s;
-moz-animation-delay: 0.35s;
}
div.hover li:nth-child(3)
{
-webkit-animation-delay: 0.55s;
-moz-animation-delay: 0.55s;
}
#-webkit-keyframes filterItemAppear
{
from { opacity:0; top:-25px; }
to { opacity:1; top:0; }
}
#-moz-keyframes filterItemAppear
{
from { opacity:0; top:-25px; }
to { opacity:1; top:0; }
}

I had similar problem and today I'll find the solution.
Firefox must notice the DOM manipulation somehow. So we must add .width() or setTimeout. Width solution is cleaner IMO.
Look at my edited CodePen for your example http://cdpn.io/yhbfB.
(More about it at http://css-tricks.com/restart-css-animation/)

Related

Ionic 5 Modal over modal is missing ion-backdrop

Why is my ion-backdrop + modal shadow styling not working when I open a modal on top of another modal?
PREFACE: This was working fine with V4, but broken on the upgrade to V5. I don’t want to change my page approach, just fix the CSS/whatever is actually causing the issue below.
My app opens a modal page with custom css to make it full screen.
I can then open another normal modal (but not full screen) over the
top. This 2nd modal is missing the ion-backdrop and its border shadow
styling.
I can see the ion-backdrop is definitely in the DOM, but it’s
obviously not showing.
Step1 Fine
enter image description here
Step 2 - broken ion-backdrop:
enter image description here
Showing my custom modal:
async showClipboard() {
const modal = await this._ModalController.create({
component: ClipboardPage,
cssClass: 'custom-round-modal',
componentProps: {
user: this.user
},
showBackdrop: true
});
await modal.present();
}
The CSS:
#media only screen and (min-width: 768px) {
.custom-round-modal {
.modal-wrapper {
border-radius: 15px !important;
-moz-border-radius: 15px !important;
-webkit-border-radius: 15px !important;
.ion-page {
border-radius: 15px !important;
-moz-border-radius: 15px !important;
-webkit-border-radius: 15px !important;
}
}
}
}
First off, I think you pasted the same screenshot twice by mistake. But I'm having the same issue, so I know what you mean.
It looks like Ionic 5 introduced this css for the modals:
.sc-ion-modal-ios-h:first-of-type {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
}
Which means when you show multiple modals at the same time, only the first one will get the backdrop.
A possible workaround is to add the backdrop yourself to your global css using something like this:
ion-modal {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
}
Or use the css class Ionic is using (but note that this one is iOS specific, so you'd likely need to do the same with the Android-equivalent class):
.sc-ion-modal-ios-h {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
}
NOTE: This will likely not look good if you are showing multiple modals on top of each other that are not fullscreen, since you'll be getting multiple backdrops on top of each other (so they'll get increasingly darker). But since your issue is a non-fullscreen modal on top of a fullscreen one, I think it will work in your case.
Hopefully the Ionic team will come up with a more elegant solution to this issue.
Thank you krisloekkegaard for your code, that helped me really out.
I want to add that it will only work if placed in the global sass or css files! You cannot do that from a component's style-file, because the modal will be created outside of it.
The following lines are a bit more precise, because they will activate the backdrop only on the last modal. Even if you have 10 stacked modals, there will be only the backdrop of the first and the backdrop of the last element overlaying each other.
.sc-ion-modal-md-h:last-of-type {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
.sc-ion-modal-ios-h:last-of-type {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
This is addressed now in the Ionic Documentation.
Please see under 'Customization' section for ion-modal : https://ionicframework.com/docs/api/modal
Add the following CSS to your modal class -
ion-modal.stack-modal {
--box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
I solved the issue adding the following css into variables.css file in Ionic v5. Give a chance.
.backdrop-no-scroll {
ion-router-outlet {
background: white;
}

Ionic 4: How to overflow div from Ionic Header or Toolbar?

I want create a drop down menu or popover within ionic toolbar. I tried with several ways but can not solve. Its always hidden like bellow,
I trying css like bellow,
.popover{
border: 1px solid black;
height: 350px;
width: 150px;
position: absolute;
z-index: 99999999;
background: yellow;
}
ion-header{
contain: none;
}
ion-toolbar{
contain: none;
}
Please give me a suggestion or an alternative idea. Please do not give any predictive answer if you are not familiar with ionic.
I don't know about Ionic 4 but on Ionic 5, a solution would be this when you debug on the console :
ion-toolbar {
contain: none;
.toolbar-container {
overflow: visible;
contain: none;
}
}
However, the .toolbar-container is an element in the shadow dom of the <ion-toolbar> component and its overflow and contain properties are not css variables and there is no part attribute on this element neither. So there is actually no way to override those properties.
I'm considering using this package, but for me it seems like overkill to use js and timeout for setting a pretty simple style... :
https://www.npmjs.com/package/shadow-dom-inject-styles
I had a similar problem when I had to make a searchbar overflow underneath the header (design thing). I was struggling a while and it popped in place suddenly when I place the searchbar outside of the toolbar and gave it position absolute:
<ion-head>
<ion-toolbar>
<!-- My stuff here -->
</ion-toolbar>
<ion-searchbar></ion-searchbar>
<ion-header>
My css looks like this:
ion-toolbar {
display: flex; // I need this for something else, but maybe has an influence
}
ion-searchbar {
padding: 0 1em .5em 1em;
transform: translateY(-50%);
z-index: 99999;
position: absolute;
}
Hope it helps somebody.
In case anyone is still looking for the solution. Here is how I managed to fixed it in react. It's a bit hacky solution, but most likely the only one ATM.
First we need to style the toolbar (pass a className or style to component:
.your-toolbar-classname {
overflow: visible!important;
contain: none!important;
}
Then we have to also style the shadow-root parts. Se we can use the useEffect after the header is mounted and set the style
// Header.tsx
...
useEffect(() => {
const style = document.createElement('style');
style.innerHTML =
'.toolbar-container { overflow: visible!important; contain: none!important; }';
toolbarRef.current.shadowRoot.appendChild(style);
}, []);
...
Just use ion-menu, its a build in ionic component
https://ionicframework.com/docs/api/menu
There is also ion-popover
You should look at the ionic docs before posting on stack

CSS/HTML iphone puts some additional space around edges of background image position. how do i remove it?

Summary
I've created a box with CSS and HTML. It scales horizontally and vertically, and maintains a nice gradient background and rounded corners. It only uses a single PNG background image (with multiple sprites). It works in IE7+
I'm not using CSS3, because there are subtleties in the corners and borders that make that almost impossible to reproduce with CSS3 alone. Also, it has to work in IE7 and 8.
I've had success making it work in all browsers that it needs to, but the problem is the iphone
Demo
A working example here:
http://www.trevorsimonton.com/iosbg/index.html
At the bottom of that page, I have links to output in various devices and browsers. It also works great on my HTC Evo, but I don't have the ability to post a screenshot from that device.
The problem
For some reason, there seems to be some kind of padding or margin or border or something on around the background image of each div. I've posted screenshots of these at the above site, and a few at the bottom of this post.
This only appears on the iphone.
It works great on the latest releases of Chrome, Safari and Firefox.
It also works great in IE7, IE8 and IE9
User zoom is disabled, and the scale is locked at 1.0
The code
The box has complex markup to allow it to scale and show image borders in IE7+
The markup is like this:
HTML
<div class='ksrfasw'>
<div class='content-container'>
<!-- top and top-right corner -->
<div class='ksrfasw-top'><div> </div></div>
<!-- right shadow, stretches down right side -->
<div class='ksrfasw-rs'>
<!-- left shadow, stretches down left side -->
<div class='ksrfasw-ls'>
<!-- inner gradient -->
<div class="ksrfasw-tab-content">
<!-- inner padding -->
<div class="ksrfasw-tab-content-inner">
CONTENT -- FINALLY!
</div>
</div>
</div>
</div>
<!-- bottom and bottom-right corner -->
<div class='ksrfasw-bottom'><div> </div></div>
</div>
</div>
The background image of each key div is the same. "box.png" -- that
contains all the different "sprites" for the various parts of the
puzzle.
There's also a "brace" inside the box to make min-height work in IE7.
Yes this markup seems excessive... but it does work as expected in all
browsers. It's a totally scalable, rounded corner, gradient
x-browser box.
CSS:
.ksrfasw-top,
.ksrfasw-top div,
.ksrfasw-ls,
.ksrfasw-rs,
.ksrfasw-bottom,
.ksrfasw-bottom div,
.ksrfasw-tab
{
background-image:url("box.png");
background-repeat:no-repeat;
padding:0px;
margin:0px;
border:0px;
outline:0px;
width:100%;
background-size:725px 1120px;
}
.ksrfasw-top div
{
background-position:0px -40px;
}
.ksrfasw-top
{
background-position:100% -60px;
padding-right:12px;
}
.ksrfasw-rs
{
background-position:100% -600px;
padding-right:12px;
}
.ksrfasw-ls
{
background-position:0 -100px;
}
.ksrfasw-bottom div
{
background-position:0px -20px;
}
.ksrfasw-bottom
{
background-position:100% 0px;
padding-right:12px;
}
.ksrfasw-brace
{
height:190px;
float:right;
width:1px;
}
.ksrfasw,
.ksrfasw-content-container
{
position:relative;
}
.ksrfasw-tabbed
{
padding-top:34px;
}
.ksrfasw-content-container
{
z-index:5;
}
.ksrfasw-tab
{
position:absolute;
width:154px;
display:block;
text-decoration:none;
height:61px;
top:0px;
}
.ksrfasw-tab-location
{
left:1px;
}
.ksrfasw-tab-name
{
left:151px;
}
.ksrfasw-tab-active
{
z-index:10;
background-position:-515px -700px;
}
.ksrfasw-tab-active-first .ksrfasw-tab-active
{
background-position:-515px -780px;
}
.ksrfasw-tab-active-first .ksrfasw-top div
{
background-position:5px -40px;
}
.ksrfasw-tab-inactive
{
z-index:1;
background-position:-515px -620px;
}
.ksrfasw-tab-content-inner
{
padding:20px 25px;
}
body
{
text-align:center;
}
#wrapper
{
width:95%;
max-width:700px;
min-width:300px;
margin:0 auto;
}
/**
* Markup free clearing.
*
* #see http://perishablepress.com/press/2009/12/06/new-clearfix-hack
*/
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
/* IE6 */
* html .clearfix {
height: 1%;
}
/* IE7 */
*:first-child + html .clearfix {
min-height: 1%;
}
.clearfix:after {
font-size: 0;
}
(Note: there are other things going on in the CSS and HTML to create tabs over the box... don't worry about that. in the example i have 1 box with tabs, and another without. both exibit the same behaviour)
iPhone Screenshots showing problem
Here is one:
and a zoomed version of the mysterious "padding"
iPad screenshot showing expectation
here's a rendering by ipad, working as expected:
I've tried all i can with background-position, position, top, left, margin, padding, border and even background-size properties, and although it works great on every device tested, (including ipad!) these lines just won't go away on iphone.
Is there something about iphone that spaces background images that I can prevent??
thanks, let me know if more examples or explanation of the linked example are necessary.
its the image. if you zoom in any browser, you see the same lines as on the iphone.
i think it comes from the retina-display, doubling all pixels.
you can make a proper image at double size and set it with an media query like
#media only screen and (-webkit-min-device-pixel-ratio: 2) {
.ksrfasw-top,.ksrfasw-top div,.ksrfasw-ls,.ksrfasw-rs,
.ksrfasw-bottom,.ksrfasw-bottom,div,.ksrfasw-tab{
background-image:url("box-doublesize.png");
}
this should fix your issue.

IE9 multiple select overflow while printing

I'm having problems with IE9 ignoring the select borders when printing a multiple select.
Here's how to recreate the problem:
Open IE9 on Windows 7.
Go to w3schools's multiple select edit page.
Now highlight the options and copy/paste until there is a long list of duplicates.
Then remove the size attribute.
Click on "Edit and Click Me" so that the page reloads and you now have your modified select in the second panel.
Now, print the document (even using the XPS viewer).
For me, all of the options are printed on the page, even though the select is only 4 option elements tall. This still happens to some degree if you leave the "size" attribute at the default value of 2, but it's far more obvious when it is changed or removed.
Is anyone else experiencing this? Is this an IE bug? Does anyone know of a workaround?
You can work around this by viewing the site in IE9's compatibility mode. Usually IE will determine that it cannot display a site properly and give you the option to turn on compatibility mode from within the address bar but sometimes you need to explicitly set it.
How to turn on compatibility mode - http://www.sevenforums.com/tutorials/1196-internet-explorer-compatibility-view-turn-off.html - I used the first one in method 2.
There doesn't seem to be any CSS solution for this. Instead, I wrote a small jQuery script that copies the <select multiple> contents into a <div>, so that it can be printed. Then I applied some CSS to make it look like a select, and only show the copy when actually printing.
Script:
//jQuery required
$(function() {
if(!$.browser.msie) return false;
$('select[multiple]').each(function() {
$lPrintableDiv = $('<div data-for="' + this.id + '" />').addClass($(this).attr('class')).addClass('printable');
//update printable on changes
$(this).after($lPrintableDiv).change(function($aEvent){
updatePrintable($aEvent.target);
});
//run once on load
updatePrintable(this);
});
});
function updatePrintable($aTarget) {
var $lSelect = $($aTarget);
var $lSelected = $($aTarget).val();
var $lPrintable = $('[data-for="'+$aTarget.id+'"]');
$($lPrintable).width($lSelect.width()).height($lSelect.height());
$($lPrintable).html('');
$($aTarget).children().each(function($lElm){
$lVal = $(this).val();
$lLabel = $('<label />').text($lVal);
$lOption = $('<input type="checkbox" />').val($lVal);
if($(this).is(':selected'))
$lOption.prop('checked', true);
$lPrintable.append($lOption).append($lLabel);
});
}
CSS:
.printable {
border: 1px solid grey;
display: none;
overflow: auto;
}
.printable label {
display: block;
font: .8em sans-serif;
overflow: hidden;
white-space: nowrap;
}
.printable [type="checkbox"] {
display: none;
}
.printable [type="checkbox"]:checked + label {
background: #3399ff;
color: white;
}
#media print {
select[multiple] { display: none; }
.printable { display: inline-block; }
.printable [type="checkbox"]:checked + label { background: grey; }
}
Also see the jsFiddle and original post about this fix

JQTOUCH - Anytime loading occurs, add a loading class?

I'm using JQTOUCH and in JQTOUCH several of the links are being loading via AJAX and then sliding in. The problem is that there is no loading indication provided to users.
I'd like a way to add a Loading class with an AJAX spinner, when ever the an ajax call is loading, and have the class removed when the loading is done, and the page is displayed.
Any ideas?
the showPageByHref() answer is partially correct.
But, instead of
$('body').append('<div id="loadinginprogress">Loading...</div>');
You need
$('.current').append('<div id="loadinginprogress">Loading...</div>');
Body is too general for jqtouch, need to be specific to the currently displayed DIV-page
showPageByHref() function in jqtouch js is a good start. i added it right into ajax call so the please wait will not flicker when you click on link that is already loaded etc.
In short - add loading div (id loadinginprogress in exmaple) right before the ajax call and remove later "success" or "error". the ajax call section would look something like that (shortened it ):
function showPageByHref(href, options) {
...
if (href != '#'){
$('body').append('<div id="loadinginprogress">Loading...</div>');
$.ajax({
url: href,
data: settings.data,
type: settings.method,
success: function (data, textStatus) {
$('#loadinginprogress').remove()
var firstPage = insertPages(data, settings.animation);
if (firstPage)
{
if (settings.method == 'GET' && jQTSettings.cacheGetRequests && settings.$referrer)
{
settings.$referrer.attr('href', '#' + firstPage.attr('id'));
}
if (settings.callback) {
settings.callback(true);
}
}
},
error: function (data) {
$('#loadinginprogress').remove()
if (settings.$referrer) settings.$referrer.unselect();
if (settings.callback) {
settings.callback(false);
}
}
});
}
...
}
css for loading div would be something like:
#loadinginprogress {
-webkit-border-radius: 10px;
background-color: rgba(0,0,0,.5);
color: white;
font-size: 18px;
font-weight: bold;
height: 80px;
left: 60px;
line-height: 80px;
margin: 0 auto;
position: absolute;
text-align: center;
top: 120px;
width: 200px;
z-index: 5000;
}
This is the basic behavior if your links are li class="arrow" elements. how are you displaying your links and where do you want the loading-spinner to display?
Thank you for your different posts. They helped me a lot.
I have a solution to propose without patching the jQtouch code on which jQTouch relies.
It uses jQuery ajax capabilities.
$(document).ready(function() {
...
$('#jqt').ajaxStart(function() {
console.log("ajaxStart");
...
}).ajaxSuccess(function() {
console.log("ajaxSuccess");
...
}).ajaxError(function() {
console.log("ajaxError");
....
});
....
});
more details available in this jQuery doc page.
You could add a custom event handler, and trigger the loading.gif everytime the click on the specific element was done.
I just answered Darin Parker's question. Just check it out it may help you.