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
Related
I am working on a one-pager WordPress site, and I need to hide the logo of the page (#logo) on the first section (#home). The whole page is a one-pager, so the first section does not need the logo, in fact it should only appear for the other sections below the first one.
Can this be accomplished using CSS?
If it is, then I also want to change the color of the menu elements for the first section, and be something else for the others.
Short answer: No.
You will need to write some JavaScript or jQuery to determine when the first section (i.e. home section) is no longer in the view window.
The logo is typically within the <header>. It's one element within the HTML markup. It does not have a relationship to the sections. With styling, you position it where you want and then scroll the document to view the rest of the content sections.
I assume with this being a one-pager, you want the <header> to be fixed. It's a good assumption since you want to display the logo in the same spot for each section, except the first one.
How
There are many ways to accomplish this behavior. Essentially, you need to determine if the home section is in the browser window or not. When it is, the logo is hidden; else, it's displayed.
One strategy is:
Set the position where the logo will show by grabbing the 2nd section's position in the document (i.e. its offset().top position).
Then determine where the 1st section is within the window. If it's > showPosition, then it's out of view.
Here's some code to get you started. You'll need to adapt it for your specific needs.
(function ( $, window, document ) {
"use strict";
var sectionContainers,
showPosition = 400;
var init = function () {
initSection();
logoHandler();
}
function initSection() {
sectionContainers = $( '.section-container' );
showPosition = $( sectionContainers[1] ).offset().top;
}
function logoHandler() {
var $logo = $( '#logo' );
if ( $( sectionContainers[0] ).offset().top >= showPosition ) {
$logo.show();
}
$( window ).scroll( function () {
if ( $( this ).scrollTop() > showPosition ) {
$logo.show();
} else {
$logo.hide();
}
} );
}
$( document ).ready( function () {
init();
} );
}( jQuery, window, document ));
body {
color: #fff;
}
.site-header {
position: fixed;
}
.site-logo {
font-weight: bold;
border: 5px solid #fff;
padding: 10px;
}
.section-container {
width: 100%;
height: 400px;
text-align: center;
padding: 50px 5%;
background-color: #627f00;
}
.section-container:nth-child(odd) {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header class="site-header" itemscope itemtype="http://schema.org/WPHeader">
<p id="logo" class="site-logo" itemprop="headline" style="display: none;">Logo</p>
</header>
<section id="home" class="section-container">
this is the home section
</section>
<section id="about" class="section-container">
this is the about section
</section>
<section id="about" class="section-container">
this is the portfolio section
</section>
JSFiddle
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 have a background image that I'm maintaining its aspect ratio like so (see fiddle):
.wrapper{
width: 100%;
max-width: 703px;
}
.greeting {
background-image: url('ANIV_ARG_CELEB.jpg');
background-repeat: no-repeat;
background-size:contain;
background-position:left;
position: relative;
min-width: 300px;
min-height: 300px;
width: 100%;
padding: 34.6% 0 0 0;
}
<div class="wrapper">
<div class="greeting texttop" style="background-image: url('top/ANIV_BOW.jpg');">
<div class="message">
<form action="" method="post">
<textarea name="text"></textarea>
</form>
</div>
</div>
</div>
This works great only now I'm trying to place a textbox within the div so that it stays at the top of the image on all devices.
This setup works well for mobile, placing the textbox at the top, however as the screen size grows the textbox becomes lower and lower.
Perhaps this can't be done in a fluid form and needs media queries?
If I understood correctly, you are trying to move the textbox in relative to the image position. The image can be transformed to Landscape or portrait based on vertical or horizontal resize of the window. This is not possible using just css. This can be solved using javascript if you know the dimensions of the Image.
In your case, the image dimensions are 774 X 543. So, here is the solution for that:
Javascript
$(function () {
var w = 774;
var h = 543;
function setMessageBox() {
var greeting = $('.greeting');
var height = greeting.height();
var width = greeting.width();
console.log(height);
if (width > (w / h) * height) {
$('.greeting.texttop .message').css('top', '0px');
} else {
var vHeight = (h * width) / w;
var topSpace = (height - vHeight) / 2;
$('.greeting.texttop .message').css('top', topSpace.toFixed(2) + 'px');
}
}
setMessageBox();
window.onresize = setMessageBox;
});
Working Fiddle
I want to show a div by hovering over its parent.
The code is quite big so I'll try to explain.
On the site there is a scrollable div (overflow:auto) which shows a table.
-> it shows 10 lines of the table and the rest (nearly 30) must be scrolled.
In every tr of my table there is a div(hover_over) that has a child-div (show_by_hower)
By hovering over the div (hover_over) the child-div (show_by_hower) should be displayed.
That works so far but the child-div (show_by_hower) is always under the scrolling div.
If I remove the overflow:auto; from the scrollable div it all works fine but I need the overflow auto.
#hover_over
{
position:relative;
width:20px;height:20px;
}
#hover_over:hover div
{
position:absolute;
display:block;
z-index:999;
width:310px;
height:125px;
}
#hover_over div { display:none; }
There is no other positioning in the code.
Here is a jsFiddle with one possible solution. I'm using jQuery's .hover() method to animate an element outside of the table and fill it with the content contained inside the table. This way, your pop-up element is not restricted to the bounds of the table.
Here is the jQuery code:
$(function() {
$(".hover_over").hover( function() {
hovDiv = $(this);
showDiv = $(".show_hover");
showDiv.html(hovDiv.children("div").html());
showDiv.css("top", hovDiv.offset().top)
showDiv.css("left", hovDiv.offset().left + hovDiv.width()).show();
}, function() {
$(".show_hover").hide();
});
});
And the HTML:
<div class="theTable">
<div class="hover_over">1
<div>I'm hidden! 1</div>
</div>
<div class="hover_over">2
<div>I'm hidden! 2</div>
</div>
<div class="hover_over">3
<div>I'm hidden! 3</div>
</div>
<div class="hover_over">4
<div>I'm hidden! 4</div>
</div>
<div class="hover_over">5
<div>I'm hidden! 5</div>
</div>
</div>
<div class="show_hover"></div>
And the CSS:
.show_hover {
display:none;
position:absolute;
background-color:black;
width:100px;
height:20px;
font-size:14px;
color:white;
}
.hover_over div { display:none; }
Update
Because you asked, I decided to make this work with plain javascript. It is not as easy to read, but the same idea applies: move the popup div outside the table and dynamically add the desired content and positioning with onmouseover and onmouseout event handlers.
Here is the new jsFiddle.
And here is the relevant code:
Javascript
(function() {
function hoverIn() {
var hovDiv = this;
var showDiv = document.getElementById("show_hover");
showDiv.innerHTML = hovDiv.children[0].innerHTML;
showDiv.className = "see";
var newTop = hovDiv.offsetTop + hovDiv.offsetParent.offsetTop + hovDiv.offsetParent.offsetParent.offsetTop;
showDiv.style.top = "" + newTop + "px";
var newLeft = hovDiv.offsetLeft + hovDiv.offsetParent.offsetLeft + hovDiv.offsetParent.offsetParent.offsetLeft + hovDiv.clientWidth;
showDiv.style.left = "" + newLeft + "px";
};
function hoverOut() {
document.getElementById("show_hover").className = "";
};
var hoverDivs = document.getElementsByClassName("hoverdiv");
for(var i = 0; i < hoverDivs.length; i++)
{
hoverDivs[i].onmouseover = hoverIn;
hoverDivs[i].onmouseout = hoverOut;
}
})();
CSS
#show_hover
{
display:none;
position:absolute;
top:0;
left:0;
}
#show_hover.see {
display:block;
background-color:green;
width:400px;
height:80px;
position:absolute;
top:20px;
left:20px;
}
Update 2
This answer is getting insanely long. Here's the new jsFiddle. This update allows you to hover over the shown div to interact with the objects inside. I made use of the basic idea behind the hoverIntent jQuery plugin, which is to place the onmouseout handler behind a setTimeout call that allows you half a second to move your mouse into the popup before it disappears. It's a bit fidgety, so you might play with the wait time until it does what you want.
Also, see this StackOverflow question if you want to just check to see where the mouse is at any given moment and trigger the show/hide behavior off that.
That said, here's the important part of the update:
var mouseInShowHover = false;
var showDiv = document.getElementById("show_hover");
showDiv.onmouseover = function() { mouseInShowHover = true; }
showDiv.onmouseout = function() {
mouseInShowHover = false;
showDiv.className = "";
}
function hoverOut() {
setTimeout( function() {
if( !mouseInShowHover )
showDiv.className = "";
}, 500);
};
Well, your JSFiddle example worked fine for me, so I'm assuming you're using IE8 or something that has very strict z-index rules.
Try adding this:
#divscroll tr:hover {
position:relative;
z-index:1;
}
JSFiddle example.
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.