I was looking at the canvas app The Eatery has created and I noticed how the layout is fluid. Specifically the #main column's left margin enlarges as the page is widened. I looked through the CSS with Chrome's inspector and I can't see what property is set that starts with a default distance from the left edge, but that grows with the length of the page. There is an inline style, but I don't understand how it's relative to the width of the window.
I can duplicate it using something like left:5%; but I don't think that's what's happening in particular on this page. Because, watching it in the inspector, it's pixel-based sizing and using a percent keeps the percents in the CSS. Any idea what's happening on that page that I can't seem to duplicate?
I've looked through a ton of the fixed-width questions on SO, but none of the answers seem to do it.
It's made by javascript onresize event.
In this particular the code is:
var a=$(window).width()
b=184;
$("#main").css("left", Math.max( (a-500-600)/2, 20) ),
$(window).height() < 800 ?
($("#hand, .hand-image").addClass("smaller") , b=96 ) :
$("#hand, .hand-image" ).removeClass( "smaller" ), $("#app-store").css("right", Math.min(a-850, b ) );
-- remove from the source code --
The idea is simple, take the width of document or window and move the div to a position based on the size. In the case, the left value is the higher between (a-500-600)/2 and 20 (px).
Related
I'm having an issue with the scrollTop property in JavaScript and was hoping someone could help. According to MDN, the value corresponds to a pixel offset, which makes sense. What I'm having trouble with is the fact that it doesn't seem to be that simple. Here's a Codepen example: http://codepen.io/anon/pen/vGJZMV
I want to create a shrinking header effect in which the header shrinks up to a certain point upon scroll and then stops. Sounds simple enough (and should be). I'm listening to the 'scroll' event on my scrollable element and subtracting the value from the maximum header height, with some conditionals ensuring it stays between my desired amounts. I'm not using any kind of scalar multiplier on my difference function so, in my mind, there should be no parallax scrolling effect happening between the scrollable area and the header (though in my example, there clearly is). Any ideas?
EDIT:
To better clarify the problem, I want the header to shrink at the same rate the text scrolls so that the text does not go behind the header until the header is at its minimum height. The way it is now, the vertical translation of the content box effectively causes the text to move twice as fast as its scrollTop value because it's both scrolling and translating.
If by "parallax scrolling effect", you mean that the header shrinks slower than the content scrolls, then it is because of your CSS. In your CSS, you have a line that says transition all 0.3s ease for your header. This means that all properties will not have changes apply immediately, but will "animate" for 0.3s with an easing. Every time you change header height, it would take 0.3s, regardless of whatever is happening in the rest of the world.
If you remove that line, header should shrink at the same rate as your content.
After realizing what the real issue was (the text container translating vertically while also scrolling), I was able to resolve it by padding the top of the content container by the scroll amount, thereby pushing the text down to compensate for the container's vertical movement. This updated pen shows the result, in case anyone is interested:
http://codepen.io/sunny-mittal/pen/LNjgEK
The relevant changes to the previous code are surrounded with asterisks:
header.on 'scrolling' (_, howmuch) ->
if howmuch is 0
header.css 'height' 150
**content.css 'padding-top' 0**
else if howmuch >= 50
header.css 'height' 100
**content.css 'padding-top' 50**
else
header.css 'height' 150 - howmuch
**content.css 'padding-top' howmuch**
I tried several other codes mentioned here on stackoverflow, all work in specific positions and specific distances. I tried to use the MAP> AREA tag, but the plugins found can not keep resizing, leaving the point completely out of the picture.
Need to position an element over an image in a specific point.
Other words, the image will reduce when I resize the browser and the point must be kept exactly where he is.
Look at the example of three images:
1 - Image FULL and point in the correct place;
2 - Medium image. Here has begun to lose;
3 - Not much smaller image. Here now very out;
I am currently using this code:
$('.btParede').css("top", ( $('.imageBox').offset().top + 200 ) + "px");
$('.btParede').css("left", ( $('.imageBox').offset().left + $('.imageBox').width() - 400 ) + "px");
There is a more specific position relative to another element when it is resized without losing the specific point?
Thanks
**** I forgot to mentioned this ****
I use "fitToParent" jQuery resize to aspect ratio to scale and reload and maintain aspect ratio of the image inside the document
Here is another example http://jsfiddle.net/Tyriar/ypb5P/1/ that works fine when resize, but when reload, mess it up.. Anyone experienced this? Works one way and not another?
Thanks again!
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.
I have an container element which is sort of a layout container for its children and based on some attributes I have to arrange children.
I need simple way to set outerHeight of an element, something like,
$(e).setOuterHeight(200);
jQuery's outerHeight does not set the height at all, indeed its a readonly method.
$(e).height(200); // this clips my element
In above method, I loose borders of input of type text.
My element's children are docked based on available space and some other criteria based on data that it holds, simple layouts like float,clear etc will not work because padding etc change dynamically based on sizes. I will finally end up using Table, even if I dont want to but have no choice, but anyway thanks for the help.
Now when element is sized to more then children then there is no problem, but sometimes container element may have lesser height then the children and that time, I need to increase the size.
function calculateSize(e){
var s = {
width: $(e).innerWidth(),
height: 0
};
var ae = new Enumerator(e.children);
while(ae.next()){
var child = ae.current();
// I have tried all alternatives
// for following lines
// child.clientHeight || child.offsetHeight
// $(child).outerHeight()
// $(child).innerHeight()
s.height += $(child).outerHeight();
}
if(s.height > $(e).height()){
$(e).height(s.height);
}
}
function layoutChildren(e){
....
/// for every child c
/// some steps before
var heightForChildren =
calculatedWithPadMarginBorder(availableHeight,c);
/// tried combinations
$(c).height(heightForChildren);
/// last statement fails for button
/// as button's padding cuts itself
/// removing padding in calculation
/// cuts other input elements !!
/// some steps after
....
}
I need some explanation of how to calculate runtime height/width including/excluding padding/margin/border etc and how to set it correctly so that I dont run into problems. I cant keep on trying all permutations combinations as I dont see a correct documentation even on jQuery website.
Fixed height calculations are fine, but this is kind of a dynamic element which resizes itself and arranges children in specific order.
Problem is there is no way to set outerHeight, when we set height/width of an element, the height/width is actually inner height/width without taking margin into consideration, while when we want to resize parent, we need outerHeight, but we cannot set back the outerHeight that easily.
My calculateSize and layoutChildren are two separate methods and two separate algorithms because parent will be resized to sum of all children's height. And then height is simply divided by no. of children stacked one above other. My calculation is perfect, but in my layoutChildren method I have "outerHeight" and "outerWidth" of element and have no idea on how to set it correctly by using jQuery or any other way.
.outerHeight( value )
version added: 1.8.0
you can use jQuery.outerHeight(value) to set the value of an element's outer height. Ex: $foo.outerHeight( 200 )
If you don't have a special requirement, a standard element by default sizes its height to match its children. If you style the to float:left or float:right its default width will then also be that to contain all its children.
Ok, this is strange but this is the Answer.
There are weird controls,
SELECT
BUTTON (INPUT[type=submit|reset|button])
WebKit Browsers
Padding and Border are considered as part of OuterWidth for all controls
Padding and Border must be added to Width as OuterWidth for all controls
Padding and Border are considered as part of InnerWidth for "weird controls"
Padding and Border must be subtracted from Width before setting the Width for all "non weird controls"
Non WebKit Browsers
Padding and Border are considered as part of OuterWidth for all non "weird controls"
Padding and Border must be added to Width as OuterWidth for all non "weird controls"
Padding and Border are considered as part of InnerWidth for all non "weird controls"
Padding and Border must be subtracted from Width before setting the Width for all "non weird controls"
I would be happy to help, but I simply do not understand your question.
In regards to the documentation of the dimensions methods of jQuery I found that http://api.jquery.com/category/css/ holds documentation on both innerWidth(), innerHeight(), outerWidth() and outerHeight().
I hope this helps, otherwise, try reading through your question, making it more obvious what you need the answer for.
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!