This is my problem, I have a div and inside 2 divs, one is centered and the other one is fixed on the left, the problem is when I resize the screen the centered div overlaps the fixed one, what I wanted to do is detect when the centered div overlaps the other div and change its left value with javascript, but is not working, any ideas?
This is my design:
<div id="content-wrap">
<div id="content">
</div>
<div id="leftbar">
</div>
</div>
and the CSS:
#content-wrap
{
clear: both;
float: left;
width: 100%;
}
#content
{
text-align: left;
padding: 0;
margin: 0 auto;
height: 470px;
width: 760px;
overflow: auto;
}
#leftbar
{
background-color: transparent;
width: 200px;
height: 470px;
position: absolute;
top: 185px;
left: 50px;
}
and this is the javascript code:
window.onload = function Centrar() {
var leftBar = $get("leftbar");
if (leftBar != null) {
var content = $get("content");
var size = leftBar.offsetLeft + leftBar.offsetWidth;
if (content.offsetLeft < size) {
content.style.left = size + 20 + 'px';
}
}
}
Thanks in advance for any help.
The easiest fix would be to apply a min-width to your #content-wrap container that prevented the overlap from occurring:
#content-wrap {
clear: both;
float: left;
width: 100%;
/* #leftbar width x 2 + #content width */
min-width: 1160px;
}
However, if you want to use Javascript, you'll need to attach the code to the window load and resize events:
$(window).bind('load resize', function() {
var content = $('#content');
var leftbar = $('#leftbar');
// get the right edge of the #leftbar
var leftbarEdge = leftbar.width() + leftbar.offset().left;
// check if an overlap has occured and adjust #content left position if yes
if (leftbarEdge > content.offset().left) {
content.css({
left: leftbarEdge - content.offset().left
});
}
});
The last change you'll need to apply to get this working is to set #content to position: relative in the CSS so it respects the left property you're setting with Javascript:
#content {
position: relative;
/* remaining css */
}
You can see it in action here.
Related
I'm trying to center and scale an image inside a container. In the following diagrams, the pink box is a 16:9 container and the blue box is the image.
If the image is wider than the container, it will scale to fit.
If the image is taller than the container, it will also scale to fit.
If the image fits in the container, it will simply be centered.
As you can see in the diagrams, there is also a caption div aligned to the bottom left of the image, and a close icon aligned to the top right.
Here is the code I have now:
/* The page */
.container {
width: 100%;
height: 100%;
}
/* 16:9 container */
.imageWrapper {
padding-bottom: 56.25%;
position: relative;
width: 100%;
border: 1px solid red;
}
.imageInnerWrapper {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
}
/* The image, footer and close button all need to fit inside the container */
.imageAndFooterWrapper {
display: inline-flex;
flex-direction: column;
position: relative;
border: 1px solid lightblue;
}
.image {
max-height: 100%;
object-fit: contain;
}
.footer {
text-align: left;
}
.closeButton {
position: absolute;
top: -30px;
right: -30px;
}
<div class="container">
<div class="imageWrapper">
<div class="imageInnerWrapper">
<div class="imageAndFooterWrapper">
<img class="image" src="https://images.theconversation.com/files/204986/original/file-20180206-14104-1hyhea9.jpg?ixlib=rb-1.1.0&rect=0%2C1212%2C5550%2C2775&q=45&auto=format&w=1356&h=668&fit=crop">
<div class="footer">
Caption
</div>
<div class="closeButton">X</div>
</div>
</div>
</div>
</div>
The following CodePen contains the above code, with some examples of different sized images.
https://codepen.io/anon/pen/NMKxxm
This may not be a direct answer to your question but usually when I have to do something like this, I use a div with a background image instead of an img tag. Using a div with a bg image allows you to use styles like background-image, background-position and background-size which allow you to create the effect as described by you.
Sample:
var imgDiv = $('.image')[0];
var closeButton = $('.fixed-el')[0];
var img = document.createElement('img');
img.src = getComputedStyle(imgDiv).backgroundImage.split('"')[1];
var calculate_positions = {
img_width: img.naturalWidth,
img_height: img.naturalHeight,
img_ratio: function() {
return calculate_positions.img_width / calculate_positions.img_height;
},
elm_ratio: function(elm) {
return $(elm).width() / $(elm).height();
},
img_offset: function(elm) {
var offset = []; //[x,y]
if (calculate_positions.elm_ratio(elm) > calculate_positions.img_ratio()) {
//centered x height 100%
var scale_percent = $(elm).height() / calculate_positions.img_height;
var scaled_width = calculate_positions.img_width * scale_percent;
var x_offset = ($(elm).width() - scaled_width) / 2;
offset = [x_offset, 0];
} else {
//centered y width 100%
var scale_percent = $(elm).width() / calculate_positions.img_width;
var scaled_height = calculate_positions.img_height * scale_percent;
var y_offset = ($(elm).height() - scaled_height) / 2;
offset = [0, y_offset];
}
return offset;
}
}
function updatePosition() {
var offset = calculate_positions.img_offset($('div.image'));
closeButton.style.top = offset[1] + 'px';
closeButton.style.left = offset[0] + 'px';
}
$(window).resize(updatePosition)
$(img).load(function() {
updatePosition();
});
div.image {
width: 100%;
background-image: url('http://via.placeholder.com/100x100');
background-position: center;
background-size: contain;
background-repeat: no-repeat;
flex: 1;
}
html,
body,
div.container {
width: 100%;
height: 100%
}
div.container {
display: flex;
position: relative;
flex-direction: column;
}
div.fixed-el {
position: absolute;
width: 20px;
height: 20px;
background: red;
}
div.caption {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="image"></div>
<div class="caption">Some caption here</div>
<div class="fixed-el"></div>
</div>
EDIT:
You can change the image size in the styles and resize the window to see the scaling in action.
I also noticed the comment which mentioned that you do not want to use background image as it will clip the image. This will not happen if you use background-size:contain
EDIT 2:
It turns out you can actually figure out what the coordinates of the image are and position other elements around it. Have created a dirty hack to demonstrate this (mixed jQuery and vanilla JS, no proper scoping etc).. But you should be able to get the main idea and implement a neater solution. The main idea is derived from this question on SO
I have some code that moves an image/element across the screen multiple times. The idea is that I'm trying to create a simple add bar with the image moving within the add bar, the element acting as the border of the bar/the actual bar.
With my current setup, the image moves outside of the element during animation despite being places within the /.
fiddle (may need to find new image) :http://jsfiddle.net/rwowf5j8/3/
<body onload="setInterval(function(){anim(document.getElementById('test'), 'left', 'px', 300, 800, 500)}, 600)">
<div id="Advert">
<img src="JS.png" id="test">
</div>
</body>
<script>
function anim(elem,style,unit,from,to,time) {
if( !elem) return;
var start = new Date().getTime(),
timer = setInterval(function() {
var step = Math.min(1,(new Date().getTime()-start)/time);
elem.style[style] = (from+step*(to-from))+unit;
if( step == 1) clearInterval(timer);
},30);
elem.style[style] = from+unit;
}
</script>
</body>
#Advert {
background-color: white;
border-style: solid;
border-width: 2px;
width: 500px;
height: 225px;
left: 300px;
}
#test {
position: absolute;
left: 140px;
}
Giving your container relative positioning and hiding the overflowing elements will stop your issue:
#Advert {
background-color: white;
border-style: solid;
border-width: 2px;
width: 500px;
height: 225px;
overflow: hidden;
position: relative;
}
Because the container is now relative I've also removed the left: 300px.
http://jsfiddle.net/rwowf5j8/6/
http://jsfiddle.net/rwowf5j8/5/
add
#Advert {
position: relative;
/*left: 300px;*/
overflow: hidden;
}
Also, left: 300px won't work unless you add position: relative.
<div id="header"></div>
<div id="sticky"></div>
<div id="section"></div>
<div id="footer"></div>
<style>
body { margin: 0px; background-color: #e3e3e3; }
#header { background-color: #cb5454; height: 140px; }
#sticky { background-color: #546bcb; height: 70px; }
#section { height: 1500px; }
#footer { background-color: #cb5454; height: 140px; }
</style>
Here is my code: http://jsfiddle.net/uaqh018d/
I want #sticky to stick to the top of the page after scrolling past #header. I also want it hidden until stuck. And then of course have it unstick+hide again after scrolling back up to #header.
How can I achieve this?
I would recommend adding a class to #sticky when it's ready to be fixed to the top of the screen, and then removing that class when you want to 'unstick' it. Then you can manipulate that class in CSS.
e.g. for a class fixed you'd put the following in your CSS:
#sticky {
display: none;
background-color: #546bcb;
height: 70px;
}
#sticky.fixed {
display: block;
position: fixed;
top: 0;
width: 100%;
}
And then your jQuery would look like this:
$(window).scroll(function() {
var distanceFromTop = $(this).scrollTop();
if (distanceFromTop >= $('#header').height()) {
$('#sticky').addClass('fixed');
} else {
$('#sticky').removeClass('fixed');
}
});
Here's an updated FIDDLE
I might also recommend some jQuery fade or slide effects (see the fiddle).
You can use position: fixed and in js detect when user scroll like this:
$(document).scroll(function() {
//detect when user scroll to top and set position to relative else sets position to fixed
$("#sticky").css({
"top": "0",
"position": $(this).scrollTop() > 140 ? "fixed" : "relative"
});
});
body {
margin: 0px;
background-color: #e3e3e3;
}
#header {
background-color: #cb5454;
height: 140px;
}
#sticky {
background-color: #546bcb;
height: 70px;
width: 100%;
position: fixed;
}
#section {
height: 1500px;
}
#footer {
background-color: #cb5454;
height: 140px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header"></div>
<div id="sticky"></div>
<div id="section"></div>
<div id="footer"></div>
References
.scroll()
In my case, the div I wanted to be sticky was inside of another div (ie. not stuck to the page, but in another fixed div on the side of the page). Here's my adaptation of #bowhart's answer to solving this problem given a React component (sticky_adapter.js):
module.exports.makeItSticky = function(thisReactComponent, parentScrollNode = window) {
const thisNode = $(ReactDOM.findDOMNode(thisReactComponent));
const position = thisNode.position();
// Uncomment for verbose logging
//console.log("Initial position: " + UIUtils.stringify(position));
const scrollContainer = $(parentScrollNode);
scrollContainer.scroll(() => {
const distanceFromTop = scrollContainer.scrollTop();
// Uncomment for verbose logging
//console.log("ScrollTop: " + distanceFromTop);
if (distanceFromTop > position.top) {
thisNode.addClass("stick-to-top");
} else {
thisNode.removeClass("stick-to-top");
}
});
};
Now, to make any React component sticky, I just add to the class:
componentDidMount() {
StickyAdapter.makeItSticky(this, ".some-other-div-which-is-the-container");
}
Finally, the css for the sticky class:
.stick-to-top {
display: block;
position: sticky;
top: 0;
z-index: 10;
}
Hey this is and old question but for new visitors I think u just need to add this css code to #sticky:
#sticky { position:sticky;top:0; }
and no need for javascript.
sticky toggles between relative and fixed, depending on the scroll position.
and don't forget that, the parent also should not have overflow property
According to this post i asked how to make a scroll method wich shows a element, scrolls to it and hide the element where i came from.
I improved that code, and it works.
But when I try to do this backwards, so from the second screen to the first screen again. Its not working. Its only scrolling to the top of the #content screen...
How does this come?
Here's a jsFiddle:
In order to achieve the desired effect you ll need to change up your markup/css and js logic a bit, as of now you are hiding the top element so once the scroll is done the bottom element's offset top = 0.
First change is to wrap your html in a <div> we ll give that div an id of #container.
Second of all we need to set the container's position to absolute so that we can slide it up and down on button click.
The css :
html,body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow:hidden;
}
#page1 {
height: 100%;
width: 100%;
}
#content {
height: 100%;
width: 100%;
overflow-y:scroll;
}
#exploreBtn {
height: 50px;
width: 50px;
background-color: red;
}
#goBack {
position: fixed;
bottom: 5%;
right: 5%;
height: 50px;
width: 50px;
background-color: purple;
}
#container {
position:absolute;
width:100%;
height:100%;
}
And finally we need to change up the js:
$(document).ready(function () {
$('#exploreBtn').on('click', function () {
showScrollHide('#content', '#page1');
});
$('#goBack').on('click', function () {
showScrollHide('#page1', '#content');
});
});
function showScrollHide(element, hide) {
var _ele = $(element),
_container = $('#container'),
_ele_top = _ele.offset().top;
if(_ele_top < 0)
_ele_top = 0;
console.log(_ele_top);
_ele.fadeIn(500, function () {
_container.stop().animate({
top: - _ele_top
}, 1000);
});
}
We get the desired effect, needs a bit of tweaking but you get the general picture.
Hope i helped.
The fiddle
put this in clck handler of the back to top button:
$('html').scrollTop(0);
Has anyone managed to create / modify jcarousel, bootstrap carousel or tiny carousel to achieve having a partial view on the next and previous images besides the main image on initialise?
*This is for a circular carousel
www.one.org/international/
Found it! I went through each element... adjusted the widths... and set a negative margin.
I will have to calculate the screen width and image widths though before deciding what negative margin to insert... I would imagine... (screenwidth - imagewidth) / 2.
.jcarousel-list {
margin: 0;
overflow: hidden;
padding: 0;
position: relative;
top: 0;
z-index: 1;
}
.jcarousel-container {
margin-left: -258px; /*to be appended*/
position:relative;
}
.jcarousel-clip {
margin: 0;
overflow: hidden;
padding: 0;
position: relative;
z-index: 2;
}
#carousel {
background: url("../img/lines-hatches/cr-hatch-bl.gif") repeat-x scroll 0 100% transparent;
height: 500px;
overflow: hidden;
padding: 20px 0 30px;
width: 100%;
}
==== ADDED: ALWAYS HIGHLIGHT NEXT CONTROL OR IMAGE ====
So that partially hidden images are not selected in controller.
function mycarousel_itemFirstInCallback(carousel, item, idx, state) {
var sel = parseInt($(item).find('img').attr('data-page'));
if(sel == $('.jcarousel-control a').length) {
sel = 1;
} else {
sel += 1;
}
$('.jcarousel-control a').removeClass('selected');
$('.jcarousel-control a:nth-child(' + sel + ')').addClass('selected')
};
function mycarousel_initCallback(carousel) {
jQuery('.jcarousel-control a').bind('click', function() {
var sel = parseInt(jQuery(this).attr('data-page'));
sel -= 1;
carousel.scroll(jQuery.jcarousel.intval(sel));
return false;
});
}
And in the options on init:
initCallback: mycarousel_initCallback,
itemFirstInCallback: mycarousel_itemFirstInCallback
Sure. The trick is to have the viewport be smaller than your visible area, and set overflow to hidden.
In this particular instance, we used some CSS gradients to have the partial items be faded out too.
I set the <li>s here to 155px each:
li {
height: 115px;
padding: 0 0 0 20px;
width: 155px;
And then the clip region to something not a multiple of 155px, in this case 700px. The trick is then to set really fat margins on both sides! This will let your extra items bleed over the edge.
.jcarousel-clip {
height: 115px;
margin: 0 120px;
overflow: hidden;
width: 700px;