Extremely strange behaviour with div height change in IE7 and IE8 - javascript

I have a very simple HTML/JS code, which expands the size of a div on mouse over and collapses it again on mouse out. The code looks like this:
CSS:
.sign-in-up {
position: absolute;
left: 780px;
background-color: #8599b2;
font-size: 9pt;
line-height: 23px;
color:white;
text-align: center;
height: 25px; /* note this height 25px */
width: 164px;
overflow: hidden;
}
Then I have my div in HTML:
<div class="sign-in-up" id="sign-in-up"
onmouseover="$(this).css('height','55px')"
onmouseout= "$(this).css('height','25px')">
my html goes here
</div>
This works perfectly fine in Firefox (from version 3 and up), Safari, Chrome, Opera and IE9 - but does not work on IE8 or IE7. When I mouse-over the div, visually nothing changes. I tried changing the onmouseover to be
onmouseover="$(this).css('height','55px');alert($(this).height())"
and the alert box shows correct height of 55px, however visually on screen nothing changes and the div is still shown as 25px height.
I've tried every possible thing there is - with exactly the same results. It seems like IE is changing the height of the div in the dom but is not redrawing the div on the screen to match its new height.
At this stage I'm totally lost. Any help is greatly appreciated.
Edit
Thank you all that replied. After much head banging against the wall (computer screen in this case), the issue turned out to be caused by interference from curvycorners - a javascript library to imitate rounded corners (border radius) in older versions of IE. Once it did its job it would actively prevent redraws of the affected elements.
After removing rounded corners, everything works fine, although it looks worse - but at least it works. I'll investigate other options for rounded corners.

Thank you all that replied. After much head banging against the wall (computer screen in this case), the issue turned out to be caused by interference from curvycorners - a javascript library to imitate rounded corners (border radius) in older versions of IE. Once it did its job it would actively prevent redraws of the affected elements.
After removing rounded corners, everything works fine, although it looks worse - but at least it works. I'll investigate other options for rounded corners.

Have you tried to do
$(this).height(55)
instead of
$(this).css('height','55px')

it's actually working
http://jsbin.com/ebejew

I'd tend to go for a more CSS driven approach. This pulls out your presentation into CSS where it belongs.
#sign-in-up {
height:25px;
}
#sign-in-up.expanded {
height:55px;
}
Js
$(this).addClass('expanded');
$(this).removeClass('expanded');

Use this simple jQuery:
$(document).ready(function() {
$(".sign-in-up").hover(function() {
$(this).animate({
height: 55
}, 10);
}, function() {
$(this).animate({
height: 25
}, 10);
});
});​

Related

IE 10 does not re-apply padding on text-inputs

I have an IE 10 specific issue concerning text-inputs and padding that gives me a lot of headache. Here's a textual description of the setup and of what is happening but there is also a running example here:
https://jsfiddle.net/41nq3pt1/5/
I've omitted the CSS below, because it's a bit larger, please look at the JSFiddle. Help is really appreciated and I'm not only looking for a solution but also for an explanation why IE 10 is behaving weird.
Description
This is the HTML structure of my input element:
<div class="input">
<label class="input__label" for="input">Floating label</label>
<input class="input__input" type="text" id="input">
</div>
Initial State: In the initial state of the input field, there is an absolutely positioned label centered in the vertical middle of the input. This is done by giving it a padding-top. The padding of the input itself is adjusted so that the blinking cursor appears on the same height as the label.
Input has content: When typing something in the field, the label is moved upwards by reducing its padding-top while simultaneously increasing the input's padding-top to move it downward a little. Alternating the padding is done by adding a class via Javascript:
// jQuery 1.12.4
$('.input__input').on('keyup input', function() {
if (!$(this).val() || $(this).val() == "") {
$(this).closest('.input').removeClass('input--has-content');
} else {
$(this).closest('.input').addClass('input--has-content');
}
});
After deleting content: When the input is found to be empty, the class that alters the padding is removed and the input should be in its initial state. Now, despite working in all current browsers even down to IE 8 (I didn't test older versions), IE 10 apparently does not change the padding of the input element back, see this screenshot: IE 10 vs. other browsers after step 4.
Steps to reproduce
Click into the input field, see the cursor blinking on the same line as the label
Type something, the label should move upwards, the cursor moves slightly downwards
Remove every input by hitting backspace
The label moves down again and the cursor should blink on the same line as in step 1.
Thanks for any help!
Thanks to Marks comment, I experimented a bit with line-heights and eventually came to a solution that doesn't rely on line-heights but solves the problem by using a transparent border.
Solution: https://jsfiddle.net/41nq3pt1/16/
Instead of increasing the padding-top of the input when it has content, I set the height from 5rem to 4rem and give it a transparent border-top. This seems to work in all major browsers (tested in IE 9, 10, 11, Edge and the current Chrome, Firefox, Safari). Here is the important code block with annotations:
.input__input {
width: 15rem;
height: 5rem; // set a fixed height
padding-left: 1rem; // removed padding-top
font-size: 1rem;
font-family: inherit;
border: 0;
outline: 1px solid #ccc;
}
.input--has-content .input__input {
border-top: 1rem solid transparent; // replaced padding-top
height: 4rem; // keep total height at 5rem
}
I would still like to know why the original version didn't work in IE 10 but – oh well – I'm happy that I've found a fix that isn't too hacky.

Angular Material - md-virtual-repeat in list - scroll/loading/display issue

When scrolling down a list under md-virtual-repeat there is an inconsistency between scroll and display speed. Items are not being displayed fast enough to keep up with the scroll speed. It also scrolls 'past the list' so that white space is displayed at the bottom (whereas it should have stopped scrolling).
See codepen: http://codepen.io/sweatherly/pen/PzKRLz
md-list-item, md-list-item ._md-list-item-inner {
min-height: 32px;
}
The problem is aggravated by changing min-height on "md-list-item, md-list-item ._md-list-item-inner" away from it's default value. On codepen, the problem is non-existent when the min-height is not changed (running on my local machine with Chrome it is worse but not terrible. However, it is more problematic at certain screen sizes).
I played with the CSS and googled for a few hours but found nothing that solved the problem. Any ideas?
I noticed a similar problem a while ago and came across the md-item-size attribute of md-virtual-repeat.
Its description in the docs is as follows:
The height or width of the repeated elements (which must be identical
for each element). Optional. Will attempt to read the size from the
dom if missing, but still assumes that all repeated nodes have same
height or width.
I've added this to your example
<md-list-item md-virtual-repeat="test in testings" class="repeated-item" flex="" md-item-size="48">
where 48 is the height of the md-list-item, and removed
md-list-item, md-list-item ._md-list-item-inner {
min-height: 32px;
}
CodePen
The scrolling appears to be smooth and without a white space at the bottom.
I also changed this CSS so that the scroll within the md-virtual-repeat-container works correctly
.md-virtual-repeat-container.md-orient-vertical {
height: calc(100% - 100px);
}

Is there a workaround for the IE11 table cell padding bug? [duplicate]

It seems I've stumbled on an annoying Internet Explorer 11 layout bug. (Ugh, I thought these days were behind us.)
In the following example, the padding on the right table cell disappears when you hover over it in IE11:
http://jsfiddle.net/xx4Z4/
This seems to arise because of an incredibly specific CSS scenario:
The element uses display: table-cell
The element uses percentage-based padding, e.g., padding: 0 5%
A subelement adds text-decoration: underline when the parent element is hovered over
If you change any of those three things, the problem goes away.
This seems to be an IE11 bug, but I'm wondering: Can anyone think of a workaround for this problem without abandoning display: table-cell and percentage-based padding?
Again a IE11 problem that seems so unusual. I see that the percentage padding is not even calculated and is not applied in the layout. However the text is still padded according to the padding percentage. So i would assume the text is positioned with the padding but after the positioning the percentage padding is "disabled".
I can't tell you why this happens. But if you really want to fix these you might want to use these quick fixes.
Use margin
Because the percentage bug only occurs on the padding of a table-cell, you can actually use a margin on the span itself.
span
{
margin-left: 10%;
}
and ofcourse reset the padding of the sides:
div.table-cell {
display: table-cell;
padding: 20px 0;
}
This "solution" is not as dynamic as with percentage padding on the table-cell itself.
Why not?
It's because the percentage takes is value from it's parent element, the table-cell. Where as the table-cell did take it's percentage value based on the tabel. Now when you would just use left-margin: 5%;. It would be half of the space as it should be. This is because it take the 10% on the table-cell width. Where the table-cell width is table width devided by its cells(table width / table cell).
So to fix that i did 5 times the amount of cells (5 * 2 in this case), which would result in the right percentage.
However this is not dynamic when you want to add more cells.
jsFiddle
Use border
Use border which its position is "reserved" before the padding is resetted.
Reserved border
span
{
border-bottom: 1px solid transparent;
}
Change property that doesn't need re-calculation of position; color
div.table-cell-bug:hover span
{
border-bottom-color: black;
}
Now note that there will still be no padding in the layout. As soon as a property is assigned which has not been calculated before the padding did reset(the same time the text position is determed) the positions will be re-calculated.
jsFiddle
I hope one of these quick fixes work for you.
I see you sended a bug report to MS. Keep us up-to-date when you get a reply, i would appreciate it :)
Strange, no one mentioned to set table-layout:fixed; It's really important, otherwise the padding/width won't be calculated correctly on IE (and some other weird side-effects, depending on the use case), especially when you are using images inside it.
<style>
.table { display:table; table-layout:fixed; }
.table-cell { display:table-cell; }
</style>
<div class="table">
<div class="table-cell"></div>
<div class="table-cell"></div>
<div class="table-cell"></div>
</div>
Adding invisible top and bottom borders seems to fix the problem.
a {
border: solid rgba(0,0,0,0);
border-width: thin 0;
}
This prevents the anchors from moving on hover or focus.
I use rgba(0,0,0,0) instead of transparent for better compatibility with old IE which displays transparent in colour while rgba is rendered invalid and not displayed at all.
We had a similar scenario where none of the solutions above worked.
Instead we animate the width of our affected div after the page has loaded:
if (!!navigator.userAgent.match(/Trident\/7\./)){
$("#karina-rosner2").animate({'width': '20.1%'},1);
$("#karina-rosner2").animate({'width': '20%'},1);
}
This forces IE11 to recalculate the div's relative padding value and solved our problem well.
This can be "helpfully" solved by setting the paddding css-rules like this ->
element:hover,
element:active,
element:focus {
// padding example
padding-left: 1.5%;
}
Rememeber to set this only for IE since it can make all normal browser behave like a disco.
EDIT: Flexbox works for IE 10 and above so this "solution" is only needed for ie 9 and below.
These are all really good answers, and the media query option works well to identify only IE which has this problem with display:table-cell
What I did that I found worked well was employ vertical-align as a great way to direct the text contained within the display:table-cell element to where I wanted it to reside. Usually vertical-align doesn't do much to formatting, UNLESS it is in a table.
Here is my simplified HTML:
<li id="table-cell-element">
<a href="#">
<img src="event.png"/>
<small>Register for Event</small>
</a>
</li>
And here is the CSS:
#media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
li {vertical-align:middle; display:table-cell; width:15%; font-size:1.2em; line-height:1.2em; padding:2%; margin:0;}
li a {display:inline-block;}
li img {display:inline-block; vertical-align:middle; padding-right:5px; float:left; max-with:30px;}
small {display:block; font-size:60%; font-weight:bold; color:#333;}
}
You may also have to adjust the li a:hover {line-height} depending on what is in your CSS for those elements
Also, if you want this to work for IE 9 and below I suggest using conditional comments that add an "ie" class to the <html> tag and then create an IE9 style sheet. Thankfully the styling required for IE9 is relatively the same. But I only tested through IE9 and I am uncertain of your results for IE8 and IE7.

Unexpected behavior when trying to center element of dynamic width horizontally using outerWidth() and $(window).resize()

Edit 1 (reduced the problem to a jsfiddle):
I removed some unnecessary detail of the original problem.
I am trying to center a popup in the window. Because of how it will be used in the original context, the popup's width will be dynamic. Its only contents will be text, but it won't be known how long that text will be. In most cases it will fit on one line, but if the text is longer and the user has a lower screen resolution, it may need to occupy 2 lines, and I would like to keep all the text on the screen. The text is static in the jsfiddle, so that is obviously not what is causing the issue. I'm just clarifying in case anyone is wondering why I haven't tried setting a width for the popup. I'm using jquery to get the width using outerWidth() and $(window).resize() to trigger the centering function when the browser window is resized.
It works fine as long as the popup's width is smaller than the element containing it. I would like for the popup to just take the full width of its container if it is made small enough that the text has to go to two lines. As you will see in the video below, if you make a large adjustment in the browser window size, the width isn't always being reported correctly, which is causing the element to have a space on the left side instead of being centered. In other words, outerWidth() is reporting a width different than what is being rendered by the browser.
See this video for a demonstration of the problem: http://youtu.be/Tnq6nrrDKvw
This is happening for me in Firefox, Chrome, IE, Opera, and Safari. Perhaps it is a problem with jquery's outerWidth function. Or perhaps I don't understand something about how it is supposed to work. Is there another method to accomplish what I'm trying to do?
Here is the javascript, nothing too complicated:
function center_horizontally(id)
{
var windowWidth = document.documentElement.clientWidth;
var popupWidth = $(id).outerWidth();
var new_left = Math.max(0, windowWidth/2 - popupWidth / 2);
...
$(id).css('left', new_left + 'px');
}
$(function(){
$(window).resize(function() {
center_horizontally('#popup');
});
center_horizontally('#popup');
});
The only important css is that the popup has position: fixed and no set width or height. If I set the width of the popup, it sticks along the left side like it should, but the text extends beyond the right boundary. I would like to keep all the text on the screen and have it take the full width and jump some text down to the next line if needed. When the width gets low enough for that to happen, I just want the notice to occupy the entire width of the viewing area.
http://jsfiddle.net/dnag/qHjVG/5/
Edit 2 (the solution):
This is the solution I ended up using thanks to the help I got.
http://jsfiddle.net/dnag/qHjVG/44/
Instead of repositioning the popups, the popups are left with an auto width and display: inline-block. They are contained inside a div with fixed positioning. When the window is resized, the containing div is resized and repositioned. You can specify how much horiziontal space you want outside of the popups when the windows is reduced by changing the number in the function. There might be a way to do this with css only, but I'm just happy to have something functional at the moment.
So I might be misunderstanding but you don't need JS at all for this effect. This seems like a case of beating the sh!t out of something with a JS-hammer instead of using some CSS-fu. I've included two examples in my HTML below one with just a single line of text, one with more than that (3 lines when I plugged it into the fiddle)
I don't have a damn fiddle account so here is the pertinent pieces from your fiddle:
1) no JS needed. (especially not things like outerwidth et al which can cause unnecessary reflows/repaints.
2) HTML
<div id="popup">
This is some sample text, just a little bit of sample text.
</div>
<div id="popup" style="top:120px;">
This is some sample text, just a little bit of sample text.
This is some sample This is some sample text, just a little bit of sample text.
This is some sample This is some sample text, just a little bit of sample text.
This is some sample
</div>
3) CSS
#popup {
background: #FFF;
position: fixed;
top: 50px;
left: 0;
border: 1px solid #000;
box-shadow: 0 0 3px #CCC;
padding: 10px;
width:auto;
max-width:100%;
}
--EDIT-- ALT version centered like the top of the question implies:
HTML
<div id="popupWrapper">
<div id="popup">
This is some sample text, just a little bit of sample text. little bit
</div>
<div id="popup">
This is some sample text, just a little bit of sample text. little bit of s little bit of s little bit of s
</div>
<div id="popup" style="top:120px;">
This is some sample text, just a little bit of sample text.
This is some sample This is some sample text, just a little bit of sample text.
This is some sample This is some sample text, just a little bit of sample text.
This is some sample
</div>
</div>
CSS
#popupWrapper {
width: 100%;
text-align:center;
position:absolute;
}
#popup {
background: #FFF;
top: 50px;
border: 1px solid #000;
box-shadow: 0 0 3px #CCC;
padding: 10px;
max-width:100%;
display: inline-block;
}

jQuery scrollTop() does not work in scrolling DIV on mobile browsers, alternatives?

I am trying to scroll to a specific location in a scrolling DIV. Right now I am using a pixel offset with the jQuery scrollTop() function which works great on desktop browsers but it does not work on android mobiles browsers with the exception of Google's Chrome Android browser (do not have an iOS device to test if that works). All the solutions I have found are for page (window) scrolling and not for scrolling in a DIV, anyone have any suggestions on what else I can use to accomplish the same task?
Here is a example:
http://jsfiddle.net/aQpPc/
http://jsfiddle.net/aQpPc/embedded/result/
Other things I have tried that work in desktop browsers:
document.getElementById('ID_of_element_in_a_DIV').scrollIntoView();
document.getElementById('ID_of_DIV').scrollTop = 200;
EDIT 3/11/13:
This is a know android browser issue: https://code.google.com/p/android/issues/detail?id=19625
One user in the bug report suggested a workaround:
because the issue only seems to appear when the overflow property is
set to scroll, you can first set it to 'hidden', set the scrollTop
property, then reset it back to 'scroll' (or auto). The scrollTop
property seems to be honored when the element is re-rendered with
scrollbars. It's not clear if this has any unexpected side-effects,
but "it works on my machine!"
This worked for me:
setTimeout( function() {
$(div).scrollTop(0)
}, 500 );
A workaound that worked for me: first, temporarily set the overflow property to 'hidden', then set the scrollTop property, then set the overflow property back to 'scroll' (or auto). The scrollTop value seems to be kept intact and honored when the overflow property is set back to 'scroll'. This was a pretty trivial workaround that worked on all browsers I tested on (desktop and mobile). I didn't test it exhaustively, and I didn't test with transitions in place, so there may be side-effects that I haven't encountered... Your mileage may vary - but it's an easy thing to try.
I found the answer here http://blog.jonathanargentiero.com/jquery-scrolltop-not-working-on-mobile-devices-iphone-ipad-android-phones/
Mobile phones doesn't understand $('html,body') so u can do the following for mobile
if(navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/)) {
window.scrollTo(0)
} else {
// default `$('html,body')` code for scrolling
}
OR
simply use $('body') instead of $('html, body').
rather than using the scroll, scrollTo, or scrollTop methods (which give me problems in mobile), I recommend setting an ID on your top DOM element (like #top), and just using:
document.getElementById("top").scrollIntoView();
that works the best for me so far across all devices and browsers.
I have a couple solutions for you to try. You will have to test them yourself, as I have not tried them in a mobile browser before, but here they are:
Use jQuery's .css() method (or .animate() depending on what your eventual goal us) to adjust the top margin (note: you would have to change the overflow to hidden and wrap the text in an inner div, which would be the element whose to margin you are adjusting)
Do the same thing as in the first solution, except set the embedded div's position to relative and adjust it's top attribute.
Let me know if you need help with any if this or have any more questions about this. Good luck! :)
Note that although I have not tested these in mobile before they are based on CSS standards, not jQuery functions, so they should work.
Temporarily setting the overflow property to 'hidden', as recommended in #Allan Nienhuis' answer, does not work on Android 4.0.3, for instance (which is, e.g., what the Kindle Fire 2s are running) - when you set overflow back to scroll, the element scrolls back to the top.
Alternatives:
Roll your own scrolling via a helper function, as demonstrated here - while this is simple to implement, it is bare-bones in that it doesn't give you inertial scrolling or overscrolling.
Use a library such as iScroll, which implements its own, sophisticated scrolling (inertial, overscrolling) based on CSS transformations.
Using iScroll requires a bit of setup, though: you need a wrapper div with fixed height and style overflow: hidden and the element to scroll should have no overflow style. This jsFiddle demo shows how it's done.
The only way i could achieve scrolling to the top of the page on a Galaxy Tab was hiding the page body for 100ms while scrolling. Using jQuery:
$("body").hide();
window.scrollTo(0, 0);
setTimeout(function(){ $("body").show() }, 100);
Try using jQuery's .animate method:
$('.div').animate({ scrollTo: x; });
Where x is equal to the position of the div you want to scroll to the top of.
Did you try this ?
$("html").scrollTop(0);
jQuery(document).ready(function($) {
$(".scroll").click(function(event){
event.preventDefault();
$('html,body').animate({scrollTop:$(this.hash).offset().top}, 1500);
});
});
Use the following code:
$("body").animate( { scrollTop: 50, }, 800, function(){
$("body").clearQueue();
} );
These solutions did not work for me. I know someone mentioned mobile detection but their approach did not work for me. It finally dawned on me to use mobile detection to deliver two different CSS styles for each case. Maybe not ideal but it for sure works. Temporarily changing the styles with js also suggested above did not work for me.
I had a two column layout with independently scrolling divs, each set to overflow:scroll and the body had to be set to overflow:hidden. I need to use scrollTop on one of the columns and no solutions worked.
I used wp_is_mobile() (Wordpress function) and if mobile true, overflow: hidden is removed from body and the divs with overflow:scroll have that css removed. Finally, scrollTop worked on mobile.
$(document).ready(function (){
$(window).scroll(function(){
if($(this).scrollTop() > 100){
$('.scrollup').fadeIn();
}
else{
$('.scrollup').fadeOut();
}
});
$('.scrollup').click(function(){
if (navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/)) {
window.scrollTo(0,0);
}
else{
$('html,body').animate({
scrollTop: 0
}, 500, function(){
$('html,body').clearQueue();
});
}
});
});
body{
height: 1500px;
}
.scrollup {
bottom: 135px;
height: 40px;
width: 40px;
display: none;
background: #000;
border: 2px solid #fff;
border-radius: 100%;
box-shadow: 1px 3px 5px #000;
text-align: center;
font-size: 25px;
color: #fff;
cursor: pointer;
position: fixed;
right: 12px;
line-height: 36px;
z-index: 25;
}
svg{
fill: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="scrollup">
<svg height="35" viewBox="0 0 512 512" width="30">
<polygon points="396.6,352 416,331.3 256,160 96,331.3 115.3,352 256,201.5 "/>
</svg>
</div>
I had the same problem and solved it by using jquery .offset() instead.
http://api.jquery.com/offset/
$('#yourFineElement').offset({ top: X, left Y)});

Categories