Positioning text according to the screen - javascript

Please check this out http://jsfiddle.net/e8UQn/
In the display screen, you can see the the text at the bottom position when you drag the scroll bar down, I've set the position of #text-box to absolute which is necessary to show the position at the specified top and left position.
What I need is when the browser shrinks, the backstretch image is looking perfect, but the text needs to modify its position so that the scroll bar should not be shown.
There should not be any change in top and left property, because those values are dynamically derived from my web application which is necessary. Is there any possibility in changing the values dynamically according to the screen size?
Thanks!

You need to position #text-box relative to the bottom of the window:
#text-box {
position: absolute;
display: inline-block;
zoom: 1;
bottom: 20px; /* This value here */
left: 51px;
padding-top: 10px;
padding-left: 20px;
}
Fiddle: http://jsfiddle.net/e8UQn/2/
If you don't have the ability to change that output, overwrite the top value:
#text-box {
top: 'auto';
bottom: 20px;
}

updated:
try this:
var t = $(window).height() - $("#text-box").outerHeight();
$("#text-box").css("top", t);
http://jsfiddle.net/e8UQn/3/

Related

CSS arrow placement "top" is not based off top of page when setting absolute value

I am setting the position of the arrow seen in the screenshot using the calculation in the typescript, however, the position is getting based from the top of the black popup instead of the top of the screen.
top of screen to middle of button = 250px
top of popup to arrow = 250px
So the offset is correct but it is using the top of the popup for 0px instead of the top of the screen. What can I do to place the arrow using the top of the screen or fix my formula to account for the positioning?
When I use relative positioning:
When I use absolute positioning:
Here is how the css looks (I tried setting relative to absolute which doesn't work:
.menu-popup {
--arrow-left-offset: 50%;
--arrow-top-offset: 50%;
padding: var(--spacing-s) 0;
margin: 10px;
position: relative;
&::after {
content: ' ';
position: absolute;
}
// The placement of the arrow
&.menu-popup-right.standard-variant::after {
top: var(--arrow-top-offset);
right: 100%; /* To the left of the menu-popup */
margin-top: -5px;
}
}
I am then updatinging the css variable like this:
// Changes the placement of the arrow:
private changeArrowPlacement() {
if (typeof this.menu === 'undefined') return;
// The button
const tRect = this.triggerRef.nativeElement.getBoundingClientRect();
// The menu
const mRect = this.menu.nativeElement.getBoundingClientRect();
if (typeof this.position === 'string' && ['left', 'right'].includes(this.position)) {
const top = tRect.height / 2 + tRect.top + 'px';
this.setArrowOffset('top', top);
}
}
// Sets the the css property:
private setArrowOffset(position: 'left' | 'top', value: string) {
if (typeof this.menu === 'undefined') return;
this.menu.nativeElement.style.setProperty('--arrow-left-offset', '0%');
this.menu.nativeElement.style.setProperty('--arrow-top-offset', '0%');
this.menu.nativeElement.style.setProperty(`--arrow-${position}-offset`, value);
}
The popup is generated via Angular CDK, which creates a div element.
Here is a simple mockup of the html
<!-- Created by me -->
<div id="application">
<button (click)="openPopup()">Open Popup</button>
</div>
<!-- Created by Angular CDK -->
<div class="overlay">
<div class="pane">
<div class="menu-popup">
</div>
</div>
</div>
Here is what angular generates for the popup:
/* Overlay element */
.overlay {
top: 0px;
left: 0px;
height: 100%;
width: 100%;
position: absolute;
}
/* Overlay Pane */
.pane {
top: 144.5px;
left: 573.844px;
}
absolute is positioned relative to the parent relative container. So, just remove position: relative from parent container, and you're good to go - your absolute will be then relative to the page body itself (if there's no other containers with position set in between).
Also, if you have no control over parent container, you can try using fixed for your arrow. Note though, it's position will be fixed even if you scroll the page - it will stay in its place on screen.
Finally, you could just place your absolutely positioned arrow by experimentally finding the right coordinates for it. Note, you could use not only px as units, but also %. Or even transform: translate(X, Y); where X and Y could also be either pixels or percentiles.
So it looks like the calculation that I needed was this as it takes into account relative positioning:
const top = tRect.top - mRect.top + tRect.height / 2 + 'px';
Get the top of the button
Get the top of the menu
Subtract the two to get the difference (arrow is now placed at the top of the button)
Add half the height of the button (arrow is now placed at half the height of the button)
This works if the button is at the top, bottom, left, right, or center of the page.

jQuery UI Draggable / Resizable - Align To Other Than Top Left

Is there any way to switch jQuery UI Draggable / Resizable to use other alignment than from top left, such as bottom right so it does not conflict with DOM objects that are aligned other than top left?
So I can use CSS properties such as right or bottom instead of left or top.
I have a demo and gives result 'auto' from the CSS right position when originally set with Right as 10px and Left unspecified.
In Firefox it gives the calculated pixels whereas Chrome and Internet Explorer gives the result of auto.
Is there any easier way to calculate the pixel value when the result is 'auto'?
https://jsfiddle.net/zerolfc/53apo8z7/
<div class="drag"></div>
.drag {
position: absolute;
right: 10px;
top: 10px;
width: 100px;
height: 100px;
background-color: blue;
}
$('.drag').draggable({
stop: function(e,ui){
console.log( 'Right position: '+$('.drag').css('right') );
}
});

Bootstrap navbar overlapping content when using affix

I want
A site banner with a navbar below
The banner to disappear when scrolling down, but the navbar to
remain fixed
I found this jsfiddle which provides the above solution:
http://jsfiddle.net/DTcHh/541/
Two main points of code:
//js
$('#topnavbar').affix({
offset: {
top: $('#banner').height()
}
});
//css
#topnavbar.affix {
position: fixed;
top: 0;
width: 100%;
}
My problem now is when you scroll down to the point where the 'affix' happens. If you look carefully at that point it kinda jumps, and now the navbar is overlapping the first 4 lines in the paragraph
Any ideas how to get rid of that overlap?
You need to displace the fixed .navbar element by adding padding-top to the body element equal to the height of the fixed element.
You can listen to the affix.bs.affix/affix-top.bs.affix events and then determine whether the padding should be equal to the element's height or removed:
Updated Example - the jump you were seeing no longer occurs.
$('#topnavbar').on('affix.bs.affix affix-top.bs.affix', function (e) {
var padding = e.type === 'affix' ? $(this).height() : '';
$('body').css('padding-top', padding);
});
Add "z-index:10;" to your topnavbar.affix class in css.
position: fixed;
top: 0;
width: 100%;
z-index:10;

javascript/jQuery – Keep a div scrolled to the bottom while resizing the page vertically?

I'm having trouble keeping the .content div's scroll pinned to the bottom when resizing the page vertically, i.e., When the footer moves upward during a user resizing the screen, the word "window" should be the absolute last thing to move out of visibility. The footer should push the words "Just Some Text" into the scrollable content, while "Window" should remain visible and atop the footer div. Right now, however, the opposite occurs: when the page is resized, footer moves upwards covering the words "window" followed by "the," then "of," etc, leaving "Just Some Text" visible. Like I said earlier, it needs to be the "opposite" so to speak.
So my question is: How do I continuously keep scroll to the bottom during a page resize?
Here's a fiddle:
http://jsfiddle.net/N672c/2/
I have a basic html structure here for the purposes of this question:
<header></header>
<div id="content_id" class="content">
<div class="container">
Just<br>
Some<br>
Text.<br>
Try<br>
resizing<br>
the<br>
height<br>
of<br>
the<br>
window
</div>
</div>
<footer></footer>
Some CSS as well:
header, footer {
position: fixed;
left: 0; right: 0;
height: 100px;
background: teal;
}
header { top: 0 }
footer { bottom: 0 }
.content {
position: fixed;
top: 100px; bottom: 100px;
left: 0; right: 0;
overflow-y: scroll;
}
.container {
padding: 20px;
position: absolute;
left: 0;
right: 0;
bottom: 0;
}
And a small amount of javascript:
var $content = $('.content'),
$container = $('.container'),
containerHeight = $container.outerHeight();
$(window).resize(function () {
$container.css({
position: $content.innerHeight() > containerHeight ? 'absolute' : 'static'
});
}).resize();
You can set the scroller to the desired position by using the scrollTop method, which takes one argument, the offset value.
Here you can add a scrollTop method to your 'content' block with an offset of the container block height which is the height you want to keep it as constant.
So add this into your resize function.
$content.scrollTop($container.height());
This'll keep you scrolled to the end on resizing.
Here's a quick check http://jsfiddle.net/4LQnW/6/
In the resize method just add:
$content.scrollTop($content.height());
This will keep $content scrolled to the bottom constantly: http://jsfiddle.net/N672c/4/

CSS absolute positioning elements inside a div

I have a .wall div with a some .toy divs inside it. I want to arrange the toys inside the wall. float:left property has done it for me nicely.
Now the problem is I want to add position:absolute for the toy divs to make it draggable later. How can I do this either via Javascript or via CSS?
Applying position:absolute, all toys will come to the top left corner of the wall overlying and hiding each other.
The width and height of the wall is constant but the width and height of the toys is variable, also the number of toy divs is dynamic and as the number increases toys need to arrange as rows.
Any suggessions will be helpful, please note the I can not avoid the use of position:absolute for dragging.
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<style>
body{
text-align:center;
}
.clearfix{
clear:both;
}
.wall {
border: 5px solid #cde;
margin:auto;
width:200px;
padding:10px;
}
.toy{
background-color: #BBCCEE;
border:1px solid #8899BB;
margin:5px;
width: auto;
padding:5px;
float:left;
}
.tall{
padding-top:10px;
}
</style>
<script>
$(document).ready(function() {
$('.toy').each(function(index) {
var position = $(this).offset();
var prevPosition = $(this).prev().offset();
$(this).css({
//top: position.top,
//left:position.left,
//position:'absolute',
});
});
});
</script>
<div class='wall'>
<div class='toy'>T1</div>
<div class='toy'>T2</div>
<div class='toy'>T3333333</div>
<div class='toy'>T4</div>
<div class='toy'>T5</div>
<div class='toy tall'>T6</div>
<div class='toy'>T7</div>
<div class='toy'>T8</div>
<div class='clearfix'></div>
</div>
Here is the code at JSBin.
Add
position:relative
To the wall div
I am working on a website that does exactly that (sorry for the non-english stuff):
http://moveit.canassa.com/cartao/4/
The link is now broken but here is a jsFiddle that shows what I am talking about:
http://jsfiddle.net/canassa/Z9N3L/
The "toy" div is using a position absolute:
.toy{
width: 100px;
height: 25px;
position: absolute;
z-index: 0;
}
The problem with the position absolute is that the toy will be relative to page and not the "wall" container, in order to fix that you must make the wall container relative:
#wall{
position: relative;
overflow: hidden;
}
The overflow:hidden is also a nice trick that I found. It makes the draggable objects go "under" the wall container.
There is no big secret to make it draggable, using jQuery:
// Creates a toy div inside the wall
$(MV.wallId).append('<div class="toy" id="' + this.getId() + '"></div>');
box = this.getBox(); // return the "toy" that I've just created.
$('#' + this.getId()).draggable(); // make it draggable
This would be a lot easier if you just used the jQueryUI .draggable(). It doesn't require the elements to be positioned.
If you're dead set on using this plugin, then you have the right idea. Let the elements flow into place and then calculate their position and set position: absolute and whatever the left and top end up being at runtime.
Set the .wall to be position: relative. Then:
var tPos;
$('.toy').each(function(index) {
tPos = $(this).position();
$(this).css({
left: tPos.left,
top: tPos.top
});
};
$('.toy').css({
position: absolute
});
The height of the .wall and the width of each .toy collapse when the toys are absolutely positioned but you can just add a few more lines to get/set their width and height in the above .each loops.
This obviously doesn't work if new toys can be added dynamically without a page reload as you suggest. To handle that you could switch them back to position: relative, add the new one, get the position of the new one in the flow, then set the position and switch back to position: absolute. Any elements that had been dragged out of place would be gaps in the flow, but I don't see any easy way around that.
the element in that the absolute should be positioned, must have the style position:relative.
(must be a parent of the target element)
The container div for every .toy must have position:relative set. That way, the position 0 for its children elements becomes its top left corner. Like this:
<div class="parent">
<div class="child">Blah.</div>
<div class="child">Blah.</div>
</div>
And:
.parent {
position: relative;
}
.child {
position: absolute;
left: 10px; /* This is 10 pixels from the parents left side */
top: 10px; /* This is 10 pixels from the parents top side */
}
Good luck.

Categories