I'm in the midst of making a lightbox style pop-up for a mailing list sign up, but I want the pop-up to position to the center of the visible page, not just the center of the whole document; if the user scrolls to the bottom of the page and clicks to sign up, I want it to appear in the center of the screen.
I'm assuming jQuery/JS will be the best way to go for this; here's my current CSS code which works fairly well but the div needs to be pushed down into the visible space dynamically for smaller screens.
.my-div{
width:960px;
height:540px;
position:absolute;
top:50%;
left:50%;
margin-left:-480px;
margin-top:-270px;
z-index:60;
display:none;
}
You were close! It can be done with CSS alone:
Use position: fixed instead of position: absolute.
Fixed refers to the viewport, while absolute refers to the document. Read all about it!
var w = $(window).width();
var h = $(window).height();
var d = document.getElementById('my-div');
var divW = $(d).width();
var divH = $(d).height();
d.style.position="absolute";
d.style.top = (h/2)-(divH/2)+"px";
d.style.left = (w/2)-(divW/2)+"px";
I know this will not solve the question but it is good reference and a starting point: How to position a div in the center of browser window
Position Div Exactly at the center of the screen
<!DOCTYPE html>
<html >
<head>
<style type="text/css">
.exactCenter {
width:200px;
height:200px;
position: fixed;
background-color: #00FF00;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -100px;
}
</style>
</head>
<body>
<div class="exactCenter"> </div>
</body>
</html>
JSFiddle here
and here
with jQuery:
var left = ($(window).width() - $(.my-div).width()) / 2;
var top = ($(window).height() - $(.my-div).height()) / 2;
$('.my-div').position({top: top + 'px', left: left + 'px});
Although the accepted answer is best, if you can't set the divs position to fixed, then you can use this pure JavaScript solution.
var myElement = document.getElementById('my-div'),
pageWidth = window.innerWidth,
pageHeight = window.innerHeight,
myElementWidth = myElement.offsetWidth,
myElementHeight = myElement.offsetHeight;
myElement.style.top = (pageHeight / 2) - (myElementHeight / 2) + "px";
myElement.style.left = (pageWidth / 2) - (myElementWidth / 2) + "px";
JSFiddle
Or a more condensed version:
var w = window,
elem = document.getElementById('my-div');
elem.style.top = (w.innerHeight/2) - (elem.offsetHeight/2) + 'px';
elem.style.left = (w.innerWidth/2) - (elem.offsetWidth/2) + 'px';
This answer is a vanilla JavaScript version from Lahiru Ashan's answer.
Related
I would like my logo to scroll up and down vertically based on the scroll position on the website.
In exactly the same way a default scroll bar indicates your position on the site, I would like my logo to do the same. When you are at the top of the website page, the logo sits at the top, and when you are at the bottom it will sit at the bottom of the page in a vertical bar on the left hand side of the web page.
I have no idea how to approach this, I have looked at a few plugins but none offer the positioning based on the content and I can't find any other Stack Overflow results that are what I am looking for, though I may not be phrasing the question correctly.
My setup is
.logo-scroll {
position: fixed;
border: 2px solid white;
top: 30px;
left: 30px;
height: calc(100vh - 60px);
width: 75px;
}
.scroll-text {
height: auto;
}
.logo-scroll .scroll-text img {
padding: 0 6px 0 17px;
}
and my html
<div class="logo-scroll">
<div class="scroll-text">
<a href="/home">
<img src="logo.svg"/>
</a>
</div>
</div>
Any help would be greatly appreciated
** Edit - to complicate things, I have a 30px border which is not to be included in the page height. So an offset of 30px on the top and bottom.
The size of the margin/border will need to change responsively at break points - 1 maybe 2, before I will hide it. Essentially the height of the scroll bar will always need to match the height of either the page with margins subtracted or the height of the :before element.
Alternatively if I can set offsets, I can reuse the JS and adjust based on screen size. Like media queries for JS?
You can see the web page here - which is still very under construction https://www.sheree-new.shereewalker.com/
You could give something like this a try.
window.addEventListener('scroll', e => {
const logo = document.querySelector('.scroll-text');
const logoHeight = logo.clientHeight;
const viewHeight = window.innerHeight;
const maxLogoOffset = viewHeight - logoHeight;
const scrollFraction = getElementScrollFraction(document.querySelector('body'));
logo.style.top = maxLogoOffset*scrollFraction;
});
function getElementScrollFraction(elem){
return elem.scrollTop / (elem.scrollHeight - elem.clientHeight);
}
You'll also need to add position:fixed; to the .scroll-text css.
Here is a working example: https://jsbin.com/yuholihece/edit?html,css,js,console,output
Here is my solution.
Edited:
const docHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
const logo = document.querySelector('.scroll-text');
const logoHeight = logo.offsetHeight;
// to get the pseudoelement's '#page::before' top we use getComputedStyle method
const barTopMargin = parseInt(getComputedStyle(document.querySelector('#page'), '::before').top);
let viewportHeight, barHeight, maxScrollDist, currentScrollPos, scrollFraction;
logo.style.top = barTopMargin + 'px';
window.addEventListener('load', update);
window.addEventListener('resize', setSizes);
document.addEventListener('scroll', update);
setSizes();
function update() {
currentScrollPos = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
scrollFraction = currentScrollPos / (docHeight - viewportHeight);
logo.style.top = barTopMargin + (scrollFraction * maxScrollDist) + 'px';
}
function setSizes() {
viewportHeight = window.innerHeight;
// to get the pseudoelement's '#page::before' height we use getComputedStyle method
barHeight = parseInt(getComputedStyle(document.querySelector('#page'), '::before').height);
maxScrollDist = barHeight - logoHeight;
update();
}
And if I understand correctly, you want #page::before element to have like margins on its top, left, bottom and right. If so, then I think it would be better to use this styling rules:
#page::before {
content: "";
position: fixed;
top: 30px;
bottom: 30px;
left: 30px;
right: 30px;
...
}
When you use position: fixed property (or position: absolute), you can stretch the element's width and height as you want by just setting top - bottom and left - right properties at the same time.
P. S.: And also there is no sense in using display: inline-block, because position: fixed (and position: absolute) automatically sets display to block :)
Hopefully, this helps you!
Is there any way to get the current position of an element relative to the window,
not document
offset get the current position of an element relative to the document
To calculate where the element is positioned relative to the top edge of the viewport, you can use a combination of:
getClientBoundingRect() (to determine the position of the element within the document); and
window.scrollY (to determine the vertical scroll position of the window).
Then, simply subtract the second value from the first:
var button = document.getElementsByTagName('button')[0];
var div = document.getElementsByTagName('div')[0];
var divRect = div.getBoundingClientRect();
function alertCurrentPosition() {
var windowVerticalScroll = window.scrollY;
window.alert('The top of the red square is ' + (divRect.top - windowVerticalScroll) + ' pixels below the top of the viewport');
}
button.addEventListener('click', alertCurrentPosition, false);
body {
height: 1200px;
}
button {
position: fixed;
top: 6px;
left: 6px;
}
div {
position: absolute;
top: 300px;
left: 50%;
width: 100px;
height: 100px;
background-color: rgb(255,0,0);
}
<button>Scroll the Viewport and Click Me</button>
<div></div>
See this fiddle.
I think you'll get the answer.
Here is the
[1]: http://jsfiddle.net/mk4q332q/
This code worked with me well
var offset = $("selector").offset();
var posY = offset.top - $(window).scrollTop();
var posX = offset.left - $(window).scrollLeft();
I got the answer from here stackoverflow.com/a/13930064/5695475
I have a div, an image(arrow.gif), another image(Untitled-1.jpg), two textboxes and a button.
I want to move the arrow.gif within a scrollable div with an image inside.
But i'm having a trouble creating the div into a scrollable one (making the Untitled-1.jpg fill the div) and moving the arrow.gif based on the Untitled-1.jpg's coordinates. Can anyone help me with this? Any help/assistance will be greatly appreciated .
<!DOCTYPE html>
<html>
<head>
<title>Move to Click Position</title>
<style type="text/css">
body {
background-color: #FFF;
margin: 30px;
margin-top: 10px;
}
#contentContainer {
border: 5px black solid;
background-color: #F2F2F2;
cursor: pointer;
background-image:url('Untitled-1.jpg');
background-repeat: no-repeat;
background-size: fixed;
width:1030px;
height:912px
}
#thing {
position: relative;
left: 50px;
top: 50px;
height: 68px;
width: 41px;
transition: left .5s ease-in, top .5s ease-in;
z-index: 10000;
}
</style>
</head>
<body>
<div id="contentContainer">
<img id="thing" src="arrow.gif" >
</div>
<form method="post" action="">
<input type="button" value="submit" name="submit" onclick="getClickPosition()">
<input type="text" id="valuex" name="valuex">
<input type="text" id="valuey" name="valuey">
</form>
<script src="prefixes.min.js"></script>
<script>
function getClickPosition() {
var theThing = document.querySelector("#thing");
var container = document.querySelector("#contentContainer");
var x1 = document.getElementById('valuex').value;
var y1 = document.getElementById('valuey').value;
var parentPosition = getPosition(x1.currentTarget);
var parentPosition = getPosition(y1.currentTarget);
var xPosition = x1 - parentPosition.x - (theThing.clientWidth / 2);
var yPosition = y1- parentPosition.y - (theThing.clientHeight / 2);
theThing.style.left = xPosition + "px";
theThing.style.top = yPosition + "px";
}
function getPosition(element) {
var xPosition = 0;
var yPosition = 0;
while (element) {
xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
</script>
</body>
</html>
First things I'm noticing is that you have:
background-size: fixed;
Fixed isn't an option for the background-size property.
You also have:
height:912px
Which is missing a semicolon, and will break your stylesheet further on.
1) Full-size background
If you want your 'Untitled-1.jpg' image to fill the frame you could set background-size to either cover or contain.
2) Scrollable div
In order to change your div into a scrollable one you can do so as follows:
#div{
width:1030px;
height:912px;
overflow: auto;
}
Overflow auto will add horizontal and vertical scrollbars to the div in the event that it extends outside its bounds. Or can use scroll if you want scrollbars to always be visible on the div.
You could also use overflow-x and overflow-y to specify which orientation you want scrollbars to appear.
3) Moving the thing
You're on the right track setting the position of the thing, there's a bit of fiddly stuff involved though to get it all functioning. See my Fiddle.
Demo
I've modified your code a fair bit, but in this fiddle you can change the position of the thing within the scrollable div, using the coordinate boxes.
https://jsfiddle.net/8y0qhdwx/
I'm not sure where you are heading with this, but it would be worth looking into the HTML5 canvas element, as it's built to handle the positioning of objects within it.
Hope this helps.
I have 2 images, one of them has a Mask area. And the other image can be seen through the Masked area of the above image. I want to centre the second image within the Mask area of the first image.
Currently I'm do scale the image to mach with the mask area using below function (It has 3 lines of code that I tried to with alignment - didnt work though),
function scaleimage(img){
img.style.height = 'auto';
img.style.width = 'auto';
//Getting the image hight and width
var imgW = img.clientWidth;
var imgH = img.clientHeight;
//Getting the mask hight and width
var maskH = data.result.mask.maskhight;
var maskW = data.result.mask.maskwidth;
var scaleH = maskH / imgH;
var scaleW = maskW / imgW;
// Scaling
if (scaleH < scaleW) {
img.style.height = maskH + "px";
img.style.width = Math.round(imgW * scaleH) + "px";
} else {
img.style.width = maskW + "px";
img.style.height = Math.round(imgH * scaleW) + "px";
}
//Align image - commented below code since it didnt work
/*img.style.top = Math.round((mask1H - imgH) / 2) + 'px';
img.style.left = '50%';
img.style.marginLeft = Math.round(imgW/2) + 'px'; */
}
Current and Expected result as an Illustration. IMAGE 1 has a Mask area that can see through, and IMAGE 2 is behind IMAGE 1, but align its top left to the Mask Area's Top left. What I want is, IMAGE 2 centre = Mask Area Centre
I tried few things and didn't get any of them quite right, any feedback would be really helpful
If I understand correctly from your code. You want to resize image to fix into your mask. I have write a demo using your function here. Because I dont know your real HTML, I use my own code with a predefined value of maskW and maskH.
Another thing to note: you should set the position property of the image style to another value than the default static value if you want to layout it manually. In the demo, I set the position value of img element to absolute.
There is a css solution for this if you'd like to try:
Html:
<div>
<img class="image" src="http://dummyimage.com/300x200/0000ff/ffffff&text=image" alt="image">
</div>
Css:
div {
width: 150px;
height: 100px;
margin: 50px auto 0;
position: relative;
background: url(http://dummyimage.com/150x100/000/fff&text=mask) no-repeat center center;
}
.image {
width: 80%;
top: 50%;
left: 50%;
position: absolute;
margin: -27% 0 0 -40%;
}
Fiddle
I see at least two approaches here:
use negative left margin of second image
<img id="img"/><img id="mask"/>
<script>
mask.style.marginLeft = (imgW + maskW) / -2;
mask.style.marginTop = (imgH - maskH) / 2;
</script>
show images as background of two divs (one embeds another). Set their width and height same values (of bigger image) and use center alignment of inner background. But then, if you're getting images by AJAX, you should retrieve also sizes of the images.
<div id="img">
<div id="mask"></div>
</div>
<style>
#img {
background-position: top left;
background-repeat: no-repeat;
}
#mask {
width: inherit;
height: inherit;
background-position: center center;
background-repeat: no-repeat;
}
</style>
<script>
var imgDiv = document.getElementsById('img'),
maskDiv = document.getElementById('mask');
imgDiv.style.width = imgW + 'px'; // from AJAX
imgDiv.style.height = imgH + 'px';
imgDiv.style.backgroundImage = "url('img.jpg')"';
maskDiv.style.backgroundImage = "url('mask.jpg')";
</script>
This is juts an idea and should work with fixes
Hi please take a look at my site, below is the code snippet in question i have to center my images since ive never had any luck with the css-html methods. The problem is because its set to wait for document.ready() sometimes it will place all my images to the right. Ive tried window.load() but the images center offscreen at smaller window sizes. It was also suggested i try
<div style="
background: url('Assets/image.png') center center no-repeat;
width: 100%;
height: 500px;
">
</div>
but this causes it to lose responsiveness. Ive searched around and i cant find a solution, i just need my images (and the one form) to stay centered and for the images to scale down with the window size.
site: http://bit.ly/11nAQJK
<script type="text/javascript"> //Centering Script
$(document).ready(function () {
updateContainer();
$(window).resize(function() {
updateContainer();
});
});
function updateContainer() {
(function ($) {
$.fn.vAlign = function() {
return this.each(function(i){
var h = $(this).height();
var oh = $(this).outerHeight();
var mt = (h + (oh - h)) / 2;
$(this).css("margin-top", "-" + mt + "px");
$(this).css("top", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);
(function ($) {
$.fn.hAlign = function() {
return this.each(function(i){
var w = $(this).width();
var ow = $(this).outerWidth();
var ml = (w + (ow - w)) / 2;
$(this).css("margin-left", "-" + ml + "px");
$(this).css("left", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);
Remove that whole script. Place this in your CSS.
img{
display: block;
margin: 0 auto;
}
just do
<style>
a{
display:block;
text-align:center;
}
</style>
<a href="Assets/OrderSheet.xls">
<img src="Assets/OrderSheet.png" class="image">
</a>
no need for repositioning
fiddle
No need for js, CSS alone is fine. Set your image to display block, set a width and Max width plus margin auto.
img {
display: block;
width: 300px;
max-width: 100%;
margin: 0 auto;
}
If you won't accept the method suggested by others, I would suggest using em's. Best to use them everywhere, but you could just apply them to your images.
Then use media queries to scale up/down all elements with values specified in em's, by changing the base font-size for different screen sizes.
center a responsive sized element
/* element/id/class */
/* margin is 100 - width / 2 */
img {
width:34%;
margin: 0 33%;
}