Background offset from bottom with jquery - javascript

I'm trying to write a script with jquery that substitutes the CSS calc() function for browser compatibility. What I'm trying to rewrite is background-position: center calc(100% - 80px);
My attempt was somewhat like this:
$(window).resize(function () {
$('#element').css('background-position', 'center 100%').css('background-position', '-=80px');
});
but then what do I substract from, the first or the second value? I needed help on that, couldn't think of any possible solution :/
EDIT
To make it more clear, I was trying to have my background image positioned 'center bottom' with 80px y-axis offset, '100%' in this case equals 'bottom'.
ONE MORE EDIT
So finally, I found out.
For this to work, we need to have an img element somewhere on the page with display:none, containing the background image in original width. Let's give it an ID #referrer. We could as well create it with jquery and set the img's src to the element's background image, but it's rather complicated, we'd need to get the background image url from the DOM's CSS, so we just create it manually.
like this:
<img src="our-img.png" style="display:none;" id="referrer" />
then we can call this function when needed (in my case on window resize)
function larg() {
foo = $('#element').height() - $('#referrer').height();
$('#element').css('background-position-y', foo + 'px');
};
That's how we make the image's bottom aligned with the element's bottom.
Now all we need to do to make an offset is add the numeric value of offset pixels to foo.
We can modify our function to take an argument, so we don't have to modify it everytime we change our offset.
function larg(bar) {
foo = $('#element').height() - $('#referrer').height() + bar;
$('#element').css('background-position-y', foo + 'px');
};
Then we can call it basically from anywhere, in this fiddle, it's called by buttons onClick after resizing the div like this:
<button onClick="$('#element').css('height', '300px');larg(-80);">300/-80</button>
Note that it's not universal and works only if the background image is in original size.
FINAL EDIT
Don't ask me why didn't I know it.
background-position: center bottom 80px;
But I wrote a rather cool piece of code, right?
This line of CSS doesn't work in IE8, therefore the code is useful, though minimally.

if you want to be sure about parameter, you can use background-position-y only (not far all browsers)
(you can even simply add 80px transperent margin directly to your picture and always use background-position: center bottom; in css)
FINALLY I made working demo with unusual solution
$('#slide').css('background-position', 'center bottom 80px')

Related

Move text while one word is being animated

I'm working on an animating text element.
The element changes one work with animation. Much like in this example.
http://www.thepetedesign.com/demos/jquery_super_simple_text_rotator_demo.html
The thing is I don't like that when I change one word, the other words around it shift abruptly. I'm trying to use an effect where the other words that move around shift in a nice way. Like in this example.
http://www.thepetedesign.com/demos/jquery_super_simple_text_rotator_demo.html
Does anyone know how to do this? or link me to a relevant solution?
I'm using HTML, CSS, and JS
There may be other ways of doing it but the most consistent cross browser way of doing it that I can think of is this. This is some guidance but code samples would be helpful.
You'll need to have the animated word wrapped in an extra span. Then you'll want to define the width of the outer span to be the width of the inner span before animation. You can do this with CSS if you know what the width will be or you can do it dynamically like this:
$(outerSelector).width( $(innerSelector).width() + 'px');
Animate the text then animate the width change:
$(outerSelector).animate({width: $(innerSelector).width() +'px'}, 500);
This really only works for making it smaller. You can use this method for making the word bigger but you need to know the final width of the word first. Then you could simply have one span and do this:
$(selector).animate({width:newWidth}, 500);
If you're not worried about cross browser compatibility or if you can assume that everyone using the site will have a CSS 3 enabled browser then you can do it with CSS:
selector {
transition: width 0.5s;
}
Then you for shrinking text you would need to again set the outer span width like above, but after the animation of the text you could simply do this:
$(outerSelector).width( $(innerSelector).width() + 'px');
This has the same problem with needing to know that width in advance for transitioning to longer text. You could find out the width using another span with identical text.
.copy {
position: absolute;
left: -100%;
}
Then you could get the width of the copied version and use that as the new width for animation.

Positioning div elements left & top not working with content in FireFox

I've got a webpage with a full-screen canvas. Over the canvas I'm going to place and position divs that will contain UI elements for the canvas. I'm using jQuery to create the divs and give them the css style they need. I also re-position and/or re-size them in JavaScript upon window re-size. The problem is, as soon as I enter even one space into a div, FireFox says 'NO!' and seems to ignore any css changes made by JavaScript, even if I remove the content of the div again.
Here's some technical details:
The div I'll show is a fullscreen div that overlays the canvas and functions as dim-screen in case there are dialogs the user has opened so the canvas appears darker and extra attention is pulled towards the dialog.
The css I'm using is:
.ui_layer {
position: absolute;
top:0px;
left:0px;
}
#ui_layer_dim {
background-color: #000000;
opacity: 0.5;
}
In JavaScript I have my own function that creates the div, but it runs this jQuery:
$("<div id='ui_layer_dim' class='ui_layer' style='z-index:1'/>");
Then, on onWindowResize (tiggered by a window 'resize' eventlistener), I change the div's width and height to fit the new window size:
gameUI.layers["ui_layer_dim"].onWindowResize = function() {
this.css("width", window.innerWidth + "px");
this.css("height", window.innerHeight + "px");
};
In Chrome this works perfectly, even if I place content in the div. FireFox works, but only when the div is in it's initial state. One change to the div's contents and 'BOOM it goes': No more dynamic sizing.
I've tried the different css position settings, tried setting the width and height attributes using the css function, using the style function of the element and using setAttribute to see if it's caused by some sort of incompatibility; the results didn't change.
I've run a series of tests to see what happens to the html as soon as content is placed into the div and noticed something weird: The inspector and css rules won't show changes to the width and height of the window's innerWidth and innerHeight. Neither does the div itself, but I've set up some logging to view info about the window's innerWidth and innerHeight before setting the div's width and height and some logging about the div's width and height after setting it, and that actually shows the correct dimensions...
After building and testing the system for several days I have no clue anymore what could cause the problem. Like I've said before: Chrome works as it should so I know my code technically works, but it might just be that a different approach is needed to make it work in FireFox. I hope anyone knows. Help would be greatly appreciated!
Edit: Here's a fiddle with the code, try running in FireFox, resize the result, it should resize the grey div as well. Now, right click the result, go to the inspector and put some text or even a space inside the div and resize again. Not working for me. Link: http://jsfiddle.net/UsLL6/
Edit 2: Here's a screenshot that will hopefully clear up the problem I'm having. Marked yellow is the initial state of the browser width, I set it to very narrow to be able to show the problem more clearly. Marked orange is the state after I made the browser wider a bit. You can see the grey div doesn't resize with it as it should, neither do the inspector value and the CSS rules value, but the console shows the correct value. The first ("Setting property:.....") was retrieved from window.innerWidth, the second ("Property height now has....") was retrieved from the actual width property from the div element using style.getPropertyValue.
Just noticed IE gives the same result as FireFox, but yea..IE....
Is your gameUI.layers known by mozilla?
Did you try the jQuery solution?
$(window).resize(function(){
$('#ui_layer_dim').width(window.innerWidth);
$('#ui_layer_dim').height(window.innerHeight);
});
When adding and removing content from the div using JavaScript it works. Even though the problem does not exist for me anymore I'm still very confused by the fact that editing the div in the FF inspector creates such a weird result.

Applying position:absolute to a style via jQuery fails to center div horizontally upon first page load

This is a followup to my question here. I would like to understand why applying position:absolute to the CSS of a div via jQuery fails, while applying it in a static style works. Here are two jsfiddle examples:
Works: http://jsfiddle.net/jasper/Ty6Af/2/
No worky: http://jsfiddle.net/Ty6Af/3/
Note that the only difference between the two is where I apply position:absolute. Vertical centering always works, but horizontal centering does not work when the page loads for the first time. If you manually re-size the window the div will center correctly.
All of my testing has been on Chrome under Ubuntu thus far.
Anyway, I'm just now delving into the world of web development and these are exactly the kinds of 'quirks' that I need to begin understanding.
EDIT:
#Jasper found something interesting. If you make two calls to .css(), first applying position and subsequently applying a margin, it works. I would love to understand why. Here is an example: http://jsfiddle.net/jasper/Ty6Af/5/
So the issue is with how the width of the div is calculated by the browser depending on its position.
If the div is set to position : static (by default) then it's width is 100% of it's parents width and the element is not allowed to move around the page.
If the div is set to position : relative then it's width is 100% of it's parents width but it can be moved around with left.
If the div is set to position : absolute then its width is determined by the actual content of the div, for instance if there is only a 200px wide <span> element within the div then the div will be 200px wide.
You can test these observations by changing the CSS of your jsfiddle to specify position : relative (etc...) and remove the JavaScript that makes the div position : absolute, then use your Developer Tools to inspect the element and it's calculated width.
The problem with your code is that it sets the position : absolute at the same time it sets the margin of the element by using its width/height (which are calculated differently depending on the position of the element).
If you want to set the position of the div in JavaScript then you can do something like this:
$(function() {
//notice I cached the selector so it can be used in the future as well as set the position of the div
$signuparea = $('#signuparea').css({position : 'absolute'});
$(window).resize(function() {
$signuparea.css({
'margin-top' : '-' + Math.round($signuparea.height() / 2) + 'px',
'margin-left' : '-' + Math.round($signuparea.width() / 2) + 'px',
});
}).trigger('resize');
});
Here's a jsfiddle: http://jsfiddle.net/jasper/Ty6Af/8/
I believe the problem is that when you apply your left and right in your second fiddle, you have yet to add position absolute to the div. Hence, the browser has no idea what do with the left and right values and ignores them initially.
Practically speaking in your second fiddle, you only actually add the position:absolute on the resize trigger. So before you resize your actual div has no positioning.
If you instead add the position absolute on load it works fine:http://jsfiddle.net/Ty6Af/9/
Notice that if you give it position:relative from the start (like this http://jsfiddle.net/Ty6Af/11/ ) it allready applies both the left and right value. The reason you can't actually see the effect of "left" is because it is a block element.
I hope that answers your question, I'm not quite clear on where you are stuck.
http://jsfiddle.net/Ty6Af/7/ this should work, the trigger function in jquery has bugs with chrome so you have to run the function on load too.
The problem seems to be that position:absolute; negates the current layout and requires you to position it.....
See: http://jsfiddle.net/ZHaRD/
Which Jasper explains much more eloquently than myself!

Set an element height via CSS or JavaScript/JQuery

This should be simple but nothing's working:
Question
How do you set the height of a webpage to be, lets say, exactly 4000 pixels—in such a way that scroll bars exist even when the page is blank?
Background
I'm new to JavaScript/JQuery but very experienced with similar technologies. I'm trying to do some fancy effects based on scrolling the page. To accomplish this methodically, as a first step I'm looking to make a "really tall" page. From there I will hide/display items based on the scroll height with pseudo-code along the lines of:
function onScrollEvent() {
var height = scroll height
var sectionIndex = Math.floor(height / MAX_SECTION_HEIGHT);
for each item in my array of graphics
if item index != sectionIndex then item.fadeOut else item.fadeIn
}
Once I have that working, I'll start creating the effects I want to see. The problem is, I can't make the stupid page "really tall."
Summary
When I set the height style property of the main-content div, it doesn't seem to trigger scroll bars unless there's actual content on the page. How do I make the page "permanently tall," so to speak? That is, I want the page to behave (scroll) as though it has 4000 pixels of content even if there's only one line of text on the page. Right now it behaves as though there's a call to:
height = Math.min(height of contents, height of div style)
Have you tried min-height for body, or html tags? min-height requires the element to be at least that height regardless of the content contained.
CSS
html, body{
min-height: 4000px;
}
Live Demo
Reference
Easy in CSS:
body
{
height: 4000px;
}
Example here.
This is the simplest way. min-height is not supported by all browsers. This is a specific height that you can set to the body tag (essentially the webpage itself) to make it really tall.
In your CSS add:
body
{
min-height: 4000px;
}
And you'll also need:
body
{
height: 4000px;
}
for internet explorer (via IE's conditional comments).
In Chrome 10, on OSX 10.6 -- this renders a complete blank page with scroll on the Y axis, hope this is how you meant:
http://pastie.org/1674432

How to keep an absolutely positioned element directly over the position of inline one?

This is a follow up question to How can I stop an IFrame reloading when I change it's position in the DOM? if you want the background.
I have an inline div <div id="leaderboard-slot"></div> (with a fixed width and height) and another div ("leaderboard-loader") further down the page with the actual content for that div.
For various reasons (see previous thread), I am unable to simply do an appendChild or similar.
Instead, I'm hoping to position leaderboard-loader such that it takes up the space "reserved" by leaderboard slot. I've used some jQuery methods to do this:
var loader = $('leaderboard-loader');
var dest = $('leaderboard-slot');
var pos = dest.getPosition();
loader.setStyle('top', pos.y + 'px');
loader.setStyle('left', pos.x + 'px');
which I fire on document load and resize. However, if other elements within the page cause a reflow, then the target div moves, but the loader doesn't.
Is there a safe way of doing this - it needs to work when I know nothing else about the page (ie I can't just make this call on any other methods that might cause a reflow, because I don't know what those are).
Any help would be much appreciated - thank you :)
If I understand your question correctly, there is no need for Javascript. Just put leaderboard-loader in front of the leaderboard-slot tag, give it position: absolute and identical width and height. If slot is a normal element, loader will float above it and cover it perfectly.
<div id="leaderboard-loader"></div><div id="leaderboard-slot"></div>
I'm starting to regret my answer now. Hopefully you can find something better than the absolute positioning workaround. But, in the spirit of kludgey solutions, you could call the repositioning script on a timer. sigh.
You could put them both in the same relative positioned, 0 margin div, with the temporary div z-indexed on top of the slow loader.
Make them both absoluely positioned in the parent, not the window, at 0:0 and the same size.
You can use opacity and fade one in as you fade the other one out, or just swap visibility:hidden and visible for the two elements when you are ready..

Categories

Resources