Sticky element doesn't work well with scale - javascript

I have a div element which is set to 'sticky' to top of its parent div. The parent div is inside a div which is scaled. While everything works as expected if scale is set to 1, the sticky element doesn't stick if the scale is set to non 1 values, such as 1.5 or 0.5.
Please see the code here:
.scale {
height: unset;
transform: scale(1.5);
transform-origin: left top;
width: calc(66.6667%);
}
.container {
height: 1200px;
border: 1px solid;
}
.sticky {
position: sticky;
top: 0;
z-index: 1;
background: red;
}
<html>
<body>
<div class='scale'>
<div class='container'>
<div class='sticky'>
I should stick to top
</div>
</div>
<div>Other parts needed to scale</div>
</div>
</body>
</html>
If we set scale to 1.5 (transform: scale(1.5)), the sticky element is moving to the bottom as I scroll the page. If I set scale to 0.5, it will just scroll off the screen. If it's set to 1, everything works fine.
I am wondering how to keep both the 'sticky' and 'scale' working in this scenario. Thanks for any help!

The problem is that you're scaling the parent div, if you use 1 as a scale then the sticky div will move by 1:1 ratio
1.5 as scale will be 1.5:1 ratio so when you scroll by 100px, the sticky div will move 150px, making it go down
0.5 as scale will be 0.5:1 so it so it will move by 50px if you scroll down 100px, making it look like it's moving up

Related

Show a large image that can scroll into a smaller viewport

I need to show a large image into a smaller div, enabling scrolling horizontally to view it. The outer div should extend up to the viewport size (which can be variable, depending on devices), but not more than it.
I have tried this way:
#outer-div {
max-width:300px; //just a guess, but I need the exact viewport size here
overflow:auto;
}
img {
position: absolute;
left: 50%;
-webkit-transform: translateX(-50%);
}
<div id="outer-div">
<img name="slideImg" src="https://socrates.dyndns-server.com/meteosurf/previsioni/0000.GIF" border=0>'
</div>
with no luck...
This is the JSFiddle.
All you need to do is constrain the size of the image container element (I assume outer-div here) and then set that container's overflow.
To set the max-width to the viewport width, use: max-width:100vw;
$(function(){
var imgWidth = document.querySelector("#outer-div img").width;
// Scroll the container 1/2 the width of the image
$("#outer-div").scrollLeft((imgWidth - $("#outer-div").width()) / 2);
});
#outer-div {
max-width:100vw; /* No wider than 100% of the viewport width */
overflow-X:scroll; /* show scroll bar for horizontal scrolling */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="outer-div">
<img src="http://study.com/cimages/videopreview/types-of-weather-maps-imagesscreen_169365.png">
</div>

Increase padding on X elements when Y element's width decreases

The body element by default is of course taking up 100% width so when the browser window is resized this width in pixels will obviously decrease. For every pixel the body width is decreased I want to increase the padding of a group of elements ( header, main, and footer ) by 1 pixel. Not sure where to start. Here is a basic set up:
function start() {
//code here..
}
start();
#import url( 'https://necolas.github.io/normalize.css/latest/normalize.css' );
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body, header, main, footer {
padding: 1%;
}
header, main, footer {
height: 33.333%;
}
div {
height: 100%;
background-color: #444;
color: #ddd;
}
p {
margin: 0;
padding: 0;
position: relative;
top: 50%;
transform: translateY( -50% );
text-align: center;
}
<header>
<div>
<p>When this snippet is made <b>Full page</b>.</p>
</div>
</header>
<main>
<div>
<p>And the browser window width is <i>decreased</i>.</p>
</div>
</main>
<footer>
<div>
<p>The padding on these rectangles should <i>increase</i>.</p>
</div>
</footer>
When the browser window is resized and body width decreased I want the padding value on header, width, and height to increase proportionately.
I originally tried accomplishing this without JavaScript utilizing CSS viewport units. That did not work out very well.
PS: I'm trying not to use Jquery.
EDIT: I just realized this but it might be worth pointing out that the default padding behavior is to decrease in value as the containing elements width decreases. As both top & bottom and left & right padding is calculated by the containers width as can be seen when my snippet is resized.
padding: 0 calc( 500px - 50vw );
This works, but only for a limited range of viewport sizes (500px - 1000px).
The issue with doing the calculation in just CSS is that there will have to be a defined upper and lower bound, because viewports could in theory be thousands of pixels wide and it will have exhausted the amount of padding available to it at some point.
My code works by setting the upper limit with the value of 500px, so 1000px total when applied to left and right, and then the lower limit is the half of that by the value of 50vw, or in other words 50%. If you play with these values you can hopefully align the upper and lower bounds to suit your needs.
http://codepen.io/zepha/pen/QpMRYQ

Clipping a site display with an overlay div in a given viewport

I am querying how it is possible to have a site, for arguments sake StackOverflow, where an overlay div can hide all of the content apart from what is inside the div. I suppose like a camera, you can only see whats in the viewfinder, not outside of it. I want for the moment for the viewfinder to be fixed.
I found: Fiddle
which is close, but not quite. I have tried to google and ask friend devs but no luck in the resource department. Anyone got any ideas to get me started?
<html>
<div class="content">
<h1>All the page content divs</h1>
</div>
<div id="viewport-window"></div>
</html>
You can do this by applying a clip-path style to the main element you want the overlay to be over (for instance body if you want the whole page). You could possibly also use clip for more browser support, but do keep in mind it is being deprecated.
Demo
Has a static clip-path, but when moving mouse around it will change to a 200x200 viewport that follows the mouse
jQuery(document).mousemove(function(e){
var width = jQuery(document).width();
var height = jQuery(document.body).height();
var viewW = 200;
var viewH = 200;
var top = e.pageY - (viewH/2);
var right = (width-e.pageX) - (viewW/2);
var bottom = (height-e.pageY) - (viewH/2);
var left = e.pageX - (viewW/2);
var style = "inset("+top+"px "+right+"px "+bottom+"px "+left+"px)";
jQuery(document.body).css({
"-webkit-clip-path":style,
"-moz-clip-path":style,
"clip-path":style
});
});
body {
-webkit-clip-path:inset(20px 200px 200px 40px);
-moz-clip-path:inset(20px 200px 200px 40px);
clip-path:inset(20px 200px 200px 40px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img src="https://placekitten.com/g/500/500" />
Actually, you can do this without an "overlay" element.
Just use a giant box-shadow and a high z-index.
In this example I've used a :hover and the 'overlay` is slightly transparent.
.wrapper {
width: 80%;
margin: auto;
text-align: center;
}
.box {
width: 100px;
height: 100px;
margin: 1em;
display: inline-block;
vertical-align: top;
background: plum;
position: relative;
}
.box:hover {
box-shadow: 0 0 0 10000px rgba(0, 0, 0, 0.75);
z-index: 9999;
}
<div class="wrapper">
<div class="box">Lorem ipsum.</div>
<div class="box">Lorem ipsum.</div>
<div class="box">Lorem ipsum.</div>
</div>
Of course, this effect is purely visual the other elements are still accessible.
You can also do that in 2 steps for example:
First, create a div to overlay entire page and hide everything.
Second, create a clone of your div(to be shown) with absolute position which has the same coordinates of the original location, and increase its z-index.
So, the logic is to hide everyting and show what you want over it. You could also visualize it with css or jquery animations.

Position fixed elements to stick the edges of their sibling

How can I make two fixed elements stay with their sibling element.
<div class="left-img"> IMAGE HERE </div> <!-- fixed positioned -->
<div class="container"> Lorem ipsum... </div>
<div class="right-img"> IMAGE HERE </div> <!-- fixed positioned -->
Here is a fiddle. So far I set:
top: 50%;
To center it vertically. But when the window re sizes horizontally the fixed elements are need to stay with their sibling, the container. How in jQuery or CSS can I do this?
I thought about doing something like
$(window).resize(function() {
$('img').css("right", /*size here*/);
$('.right-side-img');
})
But I'm not sure how I would set the window size. I'm using bootstrap so all my content is in the container and I would like to set an image to stay in the middle on the outside of each side.
You could achieve that by setting an explicit width of the left and right absolutely positioned elements and using a proper value for left/right properties.
Example Here.
.left-img,
.right-img{
position: fixed;
background: blue;
top: 50%; /* <------ 15% -----> */
width: 12%; /* = ((100% - 70%) / 2) - 3%
| | | |
width of the body --- | | --- needed gap for left/right (*)
width of the container ----- ----- get remaining width for each side */
}
.left-img { left: 3%; } /* (*) The gap between edges of the page and elements */
.right-img{ right: 3%; }
For unequal widths you could use CSS3 calc() function in order to calculate the needed value for left and right properties depending on the width of each fixed positioned element.
Example Here
.left-img {
width: 150px;
left: calc(15% - 150px);
}
.right-img{
width: 100px;
right: calc(15% - 100px);
}
It's worth noting that calc() is supported in IE9+.
Here is the old answer which seems to be under a misunderstanding

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