I'm trying to center a div horizontally and verticlaly without knowing the height/width. I've achieved it within jquery but am struggling to convert it to pure js as I don't want dependancy.. any ideas?
<script>
$(document).ready(mt);
$(window).resize(mt);
function mt(){
var contentLocked = $('.lockerPopup').outerHeight();
marginTop = ( $(document).height() - contentLocked ) / 2;
$('.lockerPopup').css({'top': marginTop});}
</script>
Use .offsetWidth and .offsetHeight to get the dimensions of your element and window.innerWidth and window.innerHeight for the dimensions of the window. The rest of the logic is pretty straight forward to center it using .style.top and .style.left.
See http://codepen.io/anon/pen/JYjqWZ
Alternatively, if you want to center multiple things or you don't need it to be positioned absolutely, I would suggest looking into flexbox or use
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
in your CSS to stay away from JS entirely.
you can center by using left 50%; top 50% and -webkit-transform: translate(-50%,50%); (obviously add all of the other versions of webkit transform for cross-browser compatibility.
This will always center the div no matter what its width/height and parent container size.
You don't need javascript for that,
you can do it only using CSS: http://jsfiddle.net/leojavier/gjah19y7/
<div class="container">
<div class="element"><p>test</p></div>
</div>
CSS
html,body{
height:100%;
width:100%;
}
.container {
display:table;
height:100%;
width:100%;
background:#CCC;
}
.element {
display:table-cell;
vertical-align:middle;
text-align:center;
width:100px;
height:100px;
color:#222;
}
Related
Here is my jQuery - I will explain what I want to do:
I've added 100vw to my section:before selector, but the problem is that the horizontal scroll has appeared (because 100vw adds scroll width to 100vw).
I figured that the way to get around the horizontal scroll issue is to apply $(window).width() to my section:before selector, this way my 100vw won't calculate the scrollbar in.
This is how I fiddle it should be done (but I don't know yet how to achieve this):
select :before element in jQuery
set :before width style to $(window).width()
horizontal scroll is gone.
Any ideas how to do it?
CSS:
section {
width:500px;
height:100vh;
margin:0 auto;
background: #222226;
}
section:before {
content: 'this is my before';
position: absolute;
width: 100vw;
z-index:-1;
background: #ccc;
top:0;
bottom:0;
right:0;
left: calc(-50vw + 50%);
}
jQuery (I know it is wrong because :before is not part of DOM model but his is the idea):
$(document).ready(function() {
var window = $(document).width();
$('section:before').css("width", window);
});
Not really sure why you're doing what you're doing but... set the overflow-x property to hidden;
overflow-x: hidden;
It also might be worth it to set margin and padding to 0 in your :before element;
I need to position a header to be fixed within the containing parent so that it follows when scrolling. The problem is that
position:fixed
fixes the position to the browser, not the parent. What this is resulting in is that when I have a container that has a horizontal scroll for overflow in the width (the content is wider than the container), my fixed header does not have the overflow-scroll as the content of the table does.
See this fiddle demo
So the goal here is to fix the position of the header, but fixed relative to it's parent container. In this fiddle, you can see that I've commented out a block of css:
.container{
/*-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);*/
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
transform: none;
}
If you replace the current css block (with transform set to none) with the one with translateZ, the header will get positioned within it's parent container, but is no longer fixed.
Anyone know how to solve this? Preferred solution would be CSS/HTML only and avoid JS but if nothing else, then JS is of course what I need to go with!
CSS can't do this by itself.
Position: fixed works in relation to the viewport, not it's containing element.
I've seen an attempt to solve this problem using the CSS3 transform property, but (as you noted in your comment to my first answer) it doesn't seem to work.
I understand you can't use any client-side library but that's the only solution available to my knowledge. For you and others who may one day need this, here's a solution that works. It employs a bit of jQuery:
Positioning an element inside another element with the positioned element fixed along the x and y axes (i.e. position fixed horizontally and vertically).
http://jsfiddle.net/8086p69z/8/
HTML
<div class="moving-article">
<div class="container">
<header class="fixed-header">FIXED HEADER</header>
<ul>
<li>SCROLL</li>
<li>SCROLL</li>
<li>SCROLL</li>
</ul>
</div>
</div>
CSS (relevant section)
.moving-article {
height: 150px;
width: 75%;
overflow-x: scroll;
}
.fixed-header {
background: rgba(0,0,0,0.5);
width: 50%;
text-align: center;
line-height: 40px;
position: absolute;
top: 0;
left: 0;
}
.container{
width: 1000px;
}
jQuery
var leftOffset = parseInt($(".fixed-header").css('left'));
$(window).scroll(function(){
$('.fixed-header').css({
'left': $(this).scrollLeft() + leftOffset
});
});
set the header's position to 'absolute', and it's parent container (which you want it to be relative to) to 'relative', and set it to stick to the top of the parent with 'top: 0'
CSS:
.container {
position: relative;
}
.child {
position: absolute;
top: 0;
}
To keep an element fixed within a parent cannot be done with position: fixed because position: fixed takes the element out of the flow and therefore it has no parent. It positions itself relative to the viewport.
To accomplish your goal, while keeping things simple and efficient, you may want to consider Tether, "a client-side library to make absolutely positioned elements attach to elements in the page efficiently".
Hope this helps. Good luck.
I have a styling issue where I'm trying to center a wide image relative to it's container. The problem is that the image's width is unknown so I can't do the left:50%, margin-left:-###px; trick because I don't know what the negative margin value will be.
I also can't use text-align:center; because the the image is wider than it's container.
To make matters more complicated, the container's width is also unknown.
I'd quite like to avoid using JavaScript for this but it feels like a big ask with just CSS.
Anyone know of any magical solution here?
UPDATE:
Required support: IE8+, Chrome, Safari, Firefox, Android.
I have tried a couple of the examples provided by you lovely people which have not worked (they would work in most situations, but not mine).
#Vince - I tried your display block trick which works great when the window is wider than the image but when the window is not wider than the image, it effectively becomes 'left-aligned'.
See fiddle example. I have added another container to simulate a narrow mobile device window. Obviously this won't be a hard-coded width as in the fiddle. Also, the img width will not be hard-coded as in the example but I'm trying to simulate the situation that's presented to me.
http://jsfiddle.net/7n1bhzps/1/
Excuse the hideous colours.
UPDATE 2:
Accepted dfsq's answer. Contrary to above, it does not need to support IE8 because the problem is at mobile resolutions. IE8 is not a mobile browser so the need to support this is not necessary.
Thanks all.
Set the container's min-width to any value you feel necessary. Set the image to display as block and use the margin: 0 auto; trick to center it
HTML:
<div id="contain">
<img src="http://i.imgur.com/xs8vh.jpg"/>
</div>
CSS:
#contain {
min-width: 50px;
}
#contain img {
display: block;
margin: 0 auto;
}
JSFiddle: http://jsfiddle.net/j21a8ubo/
You can make use of CSS transofrm: translateX(-50%) to shift the image of unknown width. This technic allows to center image of any width relative to container.
.wrap {
margin: 0 0 10px 160px;
width: 300px;
height: 75px;
border: 3px red solid;
position: relative;
overflow: hidden;
}
.wrap:hover {
overflow: inherit;
}
.wrap img {
position: absolute;
left: 50%;
-ms-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
<div class="wrap">
<img src="http://lorempixel.com/600/75/food/3" alt="">
</div>
<div class="wrap">
<img src="http://lorempixel.com/100/75/food/4" alt="">
</div>
Check for support http://caniuse.com/#feat=transforms2d
If you set X's CSS to margin:0px auto; it should center it within the parent container.
Sometimes centering doesn't work, but this can also be a browser-related issue.
If you can adjust the HTML, you could put the element to be centered in a cell in a <table> element, with a cell on either side of it. This is how it was done in IE8 and earlier, though it's not recommended now.
If unknown width of object and its container then use
.center-block{
display: table;
margin:0 auto;
float:none;
}
I have a complex HTML application, so unfortunately cannot really provide a code sample. We are trying to get the div (highlighted in red) to fill the remaining vertical space (see image).
The application consists of a header (in black), a sidebar on the left which can be dismissed or resized (note: the horizontal components resize correctly). To the right of the sidebar is another div (mainDiv). mainDiv contains a div at the top for the controls, and a div underneath it for the table of data (highlighted in red).
This table can potentially contain lots of data, so it needs its own scrollbar if the data doesn't fit on the screen.
We just want the table to fill all of the available horizontal and vertical space. We just can't seem to make it work.
We have created a jsfiddle example to demonstrate our layout as best we can. This can be seen here. We just want this div (in jsfiddle the div is called "tablewrap") to take up all of the remaining space.
Code (from jsfiddle) is as follows:
html
<div class="header">Header</div>
<div class="sidebar">This is the sidebar</div>
<div class="tablewrapper">
<div class="tableheader-controls-etc"></div>
<div class="tablewrap">table</div>
</div>
css
.header { height: 50px; background:black; color:white; }
.sidebar { height:100%; position:fixed; width 200px; background:gray; color:white; }
.tablewrapper{ float:right; width:75%; border:1px solid; margin-top:30px; margin-right:30px;}
.tableheader-controls-etc { height:150px; background:blue; color:white; }
.tablewrap { height: 200px; border: 2px solid red; width:100%; overflow:auto;}
If anyone can provide a solution that would be great. We would prefer CSS but can cope with Javascript.
Thanks,
Phil
The trick is to set position: absolute, then adjust the top, bottom, left and right properties as needed. See fiddle and explanation.
.tablewrap {
position: absolute;
top: 240px;
bottom: 0;
left: 150px;
right: 40px;
height: auto;
width: auto;
...
}
You can try this:
.tablewrap { height: 200px; border: 2px solid red; width:100%; overflow:auto; min-height:300px}
(Set the min-height as you want)
Well, it's time to say what you probably don't want to hear hehe: you can't do this with CSS.
You have to use javascript in order to find out two things:
Viewport height
Controls div height
Once you know those two heights, you can set your table height to:
finalHeight = viewport - (controls+header+footer)
If header and footer have also dynamic heights, use javascript to calculate them.
You will also need to recalculate this height on window resize. And of course your layout won't work if javascript is disabled.
I have an element which sits in the upper left hand corner. It is part of a print manager and has some UI on it. Here is the code I am using to ensure that it sits in the same place on scroll.
var printManagerElement = document.getElementById("printManager");
var windowReference = $(window);
window.onscroll = function () {
printManagerElement.style.top = windowReference.scrollTop() + "px";
};
When the scrolling is slow, there is no tearing. But if I scroll my mousewheel as fast as possible once, or grab the scroll bar and quickly move it, then I notice a split second of tearing.
Is the tearing preventable? Is there a way I can speed this code up? Or an alternative to this method?
edit
The div's style looks like this
padding:2px;
margin:2px;
border: 1px solid blue;
background-color:white;
position:absolute;
top:0px;
left:0px;
z-index:10;
All you need here is CSS.
position:fixed; top:0; left:0;
I think you should use CSS instead. In your CSS file, use it as follows:
#printManager {
position: fixed;
top: 10px;
left: 10px;
}
This will place your print manager 10px from the top, and 10px from the left of the browser window's top left corncer