I have an example on http://jsfiddle.net/SsYwH/
In case it don't work
HTML:
<div class="container">
<div class="absolute">
Testing absolute<br />
Even more testing absolute<br />
</div>
A little test<br />
</div>
CSS:
.container {
background: green;
}
.absolute {
position: absolute;
background: red;
}
Problem
I use jQuery to create a slider-effect. To do that I need to set position absolute.
The red block in my code is the position absolute slider.
The green block is the container.
I still want the container to be set by it's childs height. Now it don't know it because of the position absolute. Solution?
Absolutely positioned elements do not count towards the container's contents in terms of flow and sizing. Once you position something absolutely, it will be as if it didn't exist as far as the container's concerned, so there's no way for the container to "get information" from the child through CSS.
If you must allow for your scroller to have a height determined by its child elements without Javascript, your only choice may be to use relative positioning.
Then you'll also need to use jQuery to fix the height of the container div. Like so:
http://jsfiddle.net/khalifah/SsYwH/24/
$( document ).ready(function() {
$( ".container" ).each(function() {
var newHeight = 0, $this = $( this );
$.each( $this.children(), function() {
newHeight += $( this ).height();
});
$this.height( newHeight );
});
});
This is wrong however, since an absolute positioned element can sit outside of it's container. What you really what is something that will find the bottom of the element that sits lowest in the containing div, with respect to the view.
jQuery('.container > .absolute').each(function() {
jQuery(this).parent().height('+=' + jQuery(this).height());
jQuery(this).css('position', 'absolute');
});
.container {
background: green;
position: relative;
}
.absolute {
position: absolute;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="absolute">Testing absolute<br />Even more testing absolute<br /></div>
Yo
</div>
This should do what you are wanting. Note that this assumes that the absolutely positioned element must be an immediate child.
Also note that you remove the '+=' + in the height function if you want the parent element to have 100% height of it's child element.
http://jsfiddle.net/SsYwH/21/
You can do something like this with jquery. Call ghoape(jqueryElement).
var ghoape = function getHeightOfAbsolutelyPositionedElement( element ){
var max_y = 0;
$.each( $(element).find('*'), function(idx, desc){
max_y = Math.max(max_y, $(desc).offset().top + $(desc).height() );
});
return max_y - $(element).offset().top;
}
This will go through all the descendants and find the max height and return the difference between the childs.offset() + its height and then subtract that from the elements offset.
Related
I want to assign height to parent div based on the child content (here SVG is my child which can have different content based on data). If I assign fixed height either to parent or the child, it gives issue when content changes. It works fine for the width (automatically alter div width based on content) but not for height. Here is my code snippet.
React.useEffect(() => {
// calling legend function and passing div id to function
colorLegend("#legend");
}, [dep]);
function colorLegend(legend: string) {
// logic
if (colorLegend) {
select(legend)
.append("svg")
.attr("overflow","visible")
.attr("width", 150 + "px")
.call(colorLegend);
}
}
return (
<div style={{position: "absolute",right: 16,top:
10,backgroundColor: "black",borderRadius: "5px",padding:
"10px"}}>
<label style={{ color: "#6F6F6F" }}>
{name}
</label>
<div id="legend"></div>
</div>
);
Fiddle link: https://jsfiddle.net/1sv3Lwar/
I think the reason your parent <div> isn't "growing" vertically is because you are using:
position: "absolute"
Using absolute positioning or floats will cause this.
Although, assuming you need the absolute positioning, so adding: overflow: hidden should do the trick.
Using Aurelia, I created a very simple component with HTML:
<template>
<h1
draggable="true"
css="width: ${width}px;
height: ${height}px;
color:${color};
left: ${left}">
${message}
</h1>
</template>
And TypeScript:
export class Navigation {
message: string = 'Component Text';
width = '400'
height = '250'
color = 'red'
left = '100'
}
All the CSS attributes works as expected, except the left: 100px
The objective is to use the top and left to dynamically set the position of the component. This is also the reason for the draggable="true" attribute.
I can see in the rendered HTML the left: 100px is present but has no effect.
Am I doing something wrong?
Position CSS property should be set to 'relative' or 'absolute' in order to get it working: http://www.w3schools.com/cssref/pr_pos_left.asp
From what I can tell, although jQuery-Mobile-powered pages can contain divs with overflow set to scroll or auto, and these divs can be scrolled with the one-screen bar or the mouse wheel, they cannot be scrolled using the arrow keys, page-up/page-down, or home/end.
Instead, the official "page" div (with data-role="page") absorbs all this input. Perhaps other divs can't even acquire focus, I'm not sure.
Is there any way around this?
EDIT: JSfiddle of simple example: https://jsfiddle.net/qogz0shx/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js">
</script>
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css"/>
<style>
#outer {
overflow:scroll;
height: 50vh;
width: 50vw;
}
#inner {
height: 500vh;
width: 500vw;
}
</style>
<div data-role="page">
<div id="outer">
<div id="inner"></div>
</div>
</div>
Same example without the external files: https://jsfiddle.net/xr0hjjjc/
<style>
#outer {
overflow:scroll;
height: 50vh;
width: 50vw;
}
#inner {
height: 500vh;
width: 500vw;
}
</style>
<div data-role="page">
<div id="outer">
<div id="inner"></div>
</div>
</div>
In Chrome, if you click on the div in the second example and press the arrow keys, you should see the scroll bars move. If you do the same with the first one, they won't.
You're right, internal <div>s cannot be scrolled using keyboard. My approach to this limitation is simple:
create new handler for up/down/PageUp/PageDown keys
when those keys are pressed, get element under mouse
if the element contains the keyboardScroll class, scroll it accordingly
So, mouse position sets which element has to be scrolled.
Updated JSFiddle (click to focus the "run" quadrant before scrolling)
JavaScript
var currentMousePos = { x: -1, y: -1 };
$(document).on("pageinit", "#page", function(event)
{
$(document).mousemove(function(event)
{
currentMousePos.x = event.pageX;
currentMousePos.y = event.pageY;
});
// keyboard handler
$(document).on("keydown", function(e)
{
// get element under mouse
var element = document.elementFromPoint(currentMousePos.x, currentMousePos.y);
// search for scrollable element in parents
while (!$(element).hasClass("keyboardScroll") && $(element).parents().length !== 0)
element = element.parentElement;
if (!$(element).hasClass("keyboardScroll"))
return; // no scrollable element found
// set scroll "speed"
var delta = 10;
if (e.keyCode === 38) // up
delta *= -1;
else if (e.keyCode === 40) // down
delta *= 1;
else if (e.keyCode === 33) // pageup
delta *= -10;
else if (e.keyCode === 34) // pagedown
delta *= 10;
else
return;
// scroll element
$(element).scrollTop($(element).scrollTop() + delta);
// stop event from propagating to jQuery Mobile handlers
e.preventDefault();
e.stopPropagation();
});
});
On revisiting this with new searches ("focus" is a better keyword here than "scroll"), I discovered a much simpler solution.
Just give the div in question a tabindex attribute, to make it focus-able. Make the value -1 so it won't interfere with the tabindex of anything else. (This means that if the user keeps pressing tab, the div in question will never be focused. Change the index to a positive number if you want it to be focus-able that way).
<div id="outer" tabindex="-1"> </div>
<!-- Containing element with overflow:scroll or whatever -->
and that's it. Once the div is clicked it should override whatever jQuery Mobile does to prohibit focus. New JSFiddle here.
i'm making a website with 3 div columns that have overflow: scroll. (see screensho there: https://dl.dropboxusercontent.com/u/13769038/Schermafbeelding%202015-05-04%20om%2017.37.40kopie.jpg)
I want to make the image scrolling divs infinite as in: they should loop. The end of the div should be connected with the beginning of the div seamless.
I found this fiddle: http://jsfiddle.net/2L23c/
this is exactly what i want to do, but it wont work in my html. I think it is using the body to scroll and not a individual div, and since my body is height: 100% it will not scroll properly.
any way to make this work? here's the JS from the fiddle:
(function($){
$(document).ready(function(){
var html = $(".what").html();
var what = '<div class="what">'+html+'</div>';
$(window).scrollTop(1);
$(window).scroll(function() {
if ( $(window).scrollTop() >= ($('body').height() - $(window).height()) ) {
$(".what").last().after(what);
if ($(".what").length > 2) {
$(".what").last().prev().remove();
$(window).scrollTop($(window).scrollTop() - $(".what").first().height());
}
}
else if ( $(window).scrollTop() == 0 ) {
$(".what").first().before(what);
$(window).scrollTop($(".what").first().height());
if ($(".what").length > 2) {
$(".what").last().remove();
}
}
});
});
})( jQuery );
html
<div class="what">
<img src="http://1.bp.blogspot.com/_27Ai9FzK4gE/SQzMV9lH2jI/AAAAAAAAAYU/zY9yp_HpCx8/s400/brick_wall.jpg"/>
<img src="http://4.bp.blogspot.com/-5Olo8-EgrZI/TZBqclcfPqI/AAAAAAAAC5c/920EyWecwiU/s640/background_brick_wall.jpg"/>
<img src="http://www.macrobusiness.com.au/wp-content/uploads/2012/12/Brick-Wall-With-Lights-stock4221-large.png"/>
<img src="http://parktownprawn.com/wp-content/uploads/2013/04/brick-stone-wall-grey.jpg"/>
CSS
div.what{
width:400px;
margin: 0 auto;
}
IMG{
max-width:400px;
}
Mathieu
Right now when i summon a popup it appears over the header and then slides down beneath it. Check out what it looks like now.
I would like the popup to slide down from underneath the header. I've tried setting the z index of the popup lower than the header but it didnt do anything. Apparently you need to explicitly set the positioning of elements to use z index but when I did that it totally messed up the UI.
Here's the relevant code
HTML:
<div data-role="popup" id="alertPopup" class="ui-content" data-shadow="false" data-transition="slidedown" data-dismissible="false" data-corners="false" data-position-to="origin">
<p id="popupText"></p>
</div>
JS:
var horizontal = Math.floor(window.innerWidth/2);
var vertical = 80;
var popupOptions = {
x: horizontal,
y: vertical
};
if (status == google.maps.DirectionsStatus.ZERO_RESULTS) {
$("#popupText").text("No transit options could be found.");//using popups instead of alerts because these will go away by themselves instead of forcing user to tap.
$("#alertPopup").popup("open",popupOptions);
setTimeout(function() {
$("#alertPopup").popup("close");
}, 3000);
}
http://jsfiddle.net/guanzo/gvsqenvf/
I think that using a jQM popup widget will not work for this because jQM creates a transparent overlay that covers the page, then a popup container above the overlay and then it places the popup within the container. So there is no way to have the popup be under the header.
Instead, you could use an absolutely positioned DIV for your popup and use the jQuery slideToggle() method to display it.
Add the notification div to the content:
<div data-role="content" id="content">
<div id="notify" class="ui-body-inherit ui-content">
<p id="notifyText">hello</p>
</div>
I am Content
</div>
Setup the CSS to absolutely position the div and hide it until needed:
#notify {
border-width: 1px;
border-style: solid;
display: none;
position: absolute;
}
#notify p {
margin: 0;
}
In the script, set the text, calculate position and show it with slide toggle (I added a timeout on the show just so the fiddle can finish drawing the page before the notification is shown).
$("#notifyText").text("No transit options could be found.");
var $notify = $("#notify");
var vertical = $(".ui-header").outerHeight() -1; //height of header
var w = $notify.width();
var left = (Math.floor((window.innerWidth - w) / 2));
$notify.css({ left: w + "px", top: vertical + "px"});
setTimeout(function() {
$notify.slideToggle(500); //delay showing for the fiddle
}, 500);
setTimeout(function() {
$notify.slideToggle(500);
}, 5000);
Your updated FIDDLE