Making divs as high as possible without ther overlapping - javascript

I want to have something like this:
One main "wrapper" div that will have a few divs that are inline.
I can make this, but I don't know how to make the wrapper get as much space as possible, but without getting the scroll bar. And after that I would need to make those 4 inner divs as high as possible
Can I even achieve this with just CSS or would I need a bit of JS?

Flex is best for this here is codepen for you
codepen
.top{
width:100%;
height: 30px;
background-color: #00cdcd;
}
.container {
display: flex;
background-color: teal;
}
.child{
flex: 1;
border: 1px solid black;
}

You can achieve it in many ways only with css:
1st solution:
.wrapper {
display: flex;
}
.child {
flex: 1;
}
2nd solution:
.wrapper {
display: table;
}
.child {
display: table-cell;
}

You can dinamically size your div with JS:
window.onresize = function () {
var w = window.innerWidth;
var h = window.innerHeight;
document.getElementById('wrapper').style.height = w + 'px';
document.getElementById('wrapper').style.width = h + 'px';
}
so, you can have a precise control for each element in the DOM

Related

Dynamically flexible width & number items with flex

I have a set of tags, that I want to show in the client. However, sometimes you might have too many tags and you want to show only one row of tags maximized to your body's width without setting a fixed number of columns or item width, and adding a show more button at the end of the tag list with the same style as a tag.
I have achieved this using Javascript in my Angular project by doing the following:
Find out the width of your tags container dynamically, with ViewChild on my content container:
let contentWidth = this.contentContainer.nativeElement.clientWidth;
Calculate the text width of the see more button and use it to calculate the new content width minus see more button width:
Calculating text function does the following:
const canvas = document.createElement('canvas'); // create a canvas
const context = canvas.getContext('2d'); // get the context
context.font = '12px avertastd-bold'; // set up your font and size
And calculate the text width:
const seeMoreButtonWidth = context.measureText(seeMoreButtonText).width;
Create a new array variable 'previewTags' which will hold the tags that are visible when the tags body is in collapsed state, and fill in as many tags as you can by calculating each tag's width with it's content text you receive from the API by checking if the next tag + its padding (static value) fits into the width.
(Not runnable here)
for (const tag of this.data.tags) {
const width = context.measureText(tag).width;
if (contentWidth - (width + this.tagsPadding) > 0) {
previewTags.push({text: tag});
contentWidth -= (width + this.tagsPadding);
} else {
break;
}
}
Push the see more button at the end of previewTags list:
previewTags.push({text: seeMoreButtonText, isButton: true});
And it looks like this in the html:
<ng-container *ngFor="let tag of previewTags">
<div class="tag" [ngClass]="{'see-more-button': tag.isButton}">{{tag.text}}</div>
</ng-container>
Output:
Resize:
As you see, now the tags are flexiable (this code does not include the show more functionality).
After giving you this background and understanding of what I am doing, I would love to ask if this is possible to achieve with css or less JavaScript intervation?
Something like this could be a pure css solution if your tags have a constant height. I just let the flex-list wrap around and then don't show the overlap.
.content_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: rows;
}
.tag_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: rows;
flex-wrap: wrap;
width: 80%;
height: 32px;
overflow: hidden;
}
.tag_wrapper div {
width:100px;
height:30px;
border: 1px solid black;
}
button {
flex-grow: 4;
}
<div class="content_wrapper">
<div class=tag_wrapper>
<div>Tag1</div>
<div>Tag2</div>
<div>Tag3</div>
<div>Tag4</div>
<div>Tag5</div>
<div>Tag6</div>
<div>Tag7</div>
<div>Tag8</div>
<div>Tag9</div>
</div>
<button>See more</button>
You could probably make the "See more" button solution more elegant, to not have as much white space but I'll leave that to you :)
Here is some javascript to remove the see-more button if it's not needed.
(OBS) this only works if all the tags are the exact same width and have the same margin. I did this to avoid looping through all values and checking their width individually.
(I know the list is in the wrong order, I made it like that to get the see-more button fit in well without having to tinker a bunch.
function getWidthWithMargin(elem) {
var style = elem.currentStyle || window.getComputedStyle(elem)
margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight)
return(elem.getBoundingClientRect().width + margin)
}
function handleWindowSizeChange() {
let tags = document.getElementsByClassName("tag");
if(tags.length != 0)
{
let tag_width = getWidthWithMargin(tags[0]);
if(tags[0].parentElement.getBoundingClientRect().width/tag_width > tags.length) {
document.getElementById("see-more-button").style.display = "none";
}
else{
document.getElementById("see-more-button").style.display = "block";
}
}
}
window.onload = handleWindowSizeChange;
window.onresize = handleWindowSizeChange;
.content_wrapper {
}
.tag_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: row-reverse;
flex-wrap: wrap;
width: 100%;
height: 32px;
overflow: hidden;
}
.tag_wrapper div {
min-width:100px;
height:30px;
border: 1px solid black;
margin: 10px;
}
.tag_wrapper button {
height:30px;
flex-grow: 50;
}
<div class="content_wrapper">
<div class=tag_wrapper>
<button id="see-more-button">See more</button>
<div class="tag">Tag1</div>
<div class="tag">Tag2</div>
<div class="tag">Tag3</div>
<div class="tag">Tag4</div>
<div class="tag">Tag5</div>
<div class="tag">Tag6</div>
<div class="tag">Tag7</div>
<div class="tag">Tag8</div>
</div>

How to automatically push scroll-bar when new item was added

Please check out this fiddle. If you add items to the #scroll div, the scroll-bar is fixed - it just stays at the "beginning". What I want to achieve is to move scroll-bar automatically when a new item is being appended to the parent. Is it possible to do this via magic of CSS? :)) Or only JS gonna solve it?
Code:
HTML
<div id="scroll">
<div class="addElement">FIRST</div>
<div class="addElement"></div>
<div class="addElement">LAST</div>
</div>
<button id="add">ADD NEW ELEMENT</button>
CSS
#scroll {
overflow: auto;
overflow-y: hidden;
width: 200px;
height: 150px;
background: red;
position: relative;
display: flex;
align-items: center;
}
.addElement {
margin: 5px;
height: 60px;
width: 55px;
background: green;
flex: 0 0 auto;
}
JS
var scroll = $('#scroll');
var addButton = $('#add');
var item = 1;
addButton.click(function() {
scroll.append(`<div class="addElement">ITEM ${item}</div>`);
item++;
});
Thank you for any suggestion!
I've updated your fiddle to demonstrate a jQuery method of doing this:
https://jsfiddle.net/93gz3u1L/11/
I just added the following using scrollLeft (You can remove the animation if needed):
addButton.click(function() {
scroll.append(`<div class="addElement">ITEM ${item}</div>`);
item++;
scroll.animate({
scrollLeft: scroll.get()[0].scrollWidth
});
});
You can use the css Direction property, setted to rtf! (right to left)
#scroll {
...
direction: rtl;
}
but you will need to prepend the elem instead of append it to the parent.
https://jsfiddle.net/k6Lhv3u6/1/

Setting a length (height or width) for one element minus the variable length of another, i.e. calc(x - y), where y is unknown

I know we can use calc when lengths are defined:
flex-basis: calc(33.33% - 60px);
left: calc(50% - 25px);
height: calc(100em/5);
But what if a length is variable?
height: calc(100% - <<header with variable height>>);
OR
width: calc(100% - 50px - <<box with variable width>>);
Is there a standard way to do this in CSS?
I know the overall task is possible with flexbox and tables, but I'm wondering if CSS offers a simpler method. Flexbox, tables and simple Javascript are acceptable alternatives.
height demo
width demo
You can use CSS tables:
.wrapper {
display: table;
width: 100%;
margin: 15px 0;
}
.horizontal.wrapper > div {
display: table-cell;
white-space: nowrap; /* Prevent line wrapping */
border: 1px solid;
}
.left { width: 100px } /* Minimum width of 100px */
.center { width: 0; } /* Width given by contents */
.vertical.wrapper { height: 200px; }
.vertical.wrapper > div {
display: table-row;
}
.vertical.wrapper > div > span {
display: table-cell;
border: 1px solid;
}
.top { height: 100px; } /* Minimum heigth of 100px */
.middle { height: 0; } /* Height given by content */
.bottom { height: 100%; } /* As tall as possible */
<div class="horizontal wrapper">
<div class="left">100px wide</div>
<div class="center">Auto width, given by contents</div>
<div class="right">Remaining space</div>
</div>
<div class="vertical wrapper">
<div class="top"><span>100px tall</span></div>
<div class="middle"><span>Auto height, given by contents</span></div>
<div class="bottom"><span>Remaining space</span></div>
</div>
The horizontal case can also be achieved with floats:
#wrapper, .right { overflow: hidden; } /* Establish BFC */
#wrapper > div { border: 1px solid; }
.left, .middle { float: left; }
.left { width: 100px }
<div id="wrapper">
<div class="left">100px</div>
<div class="middle">Auto width, given by contents</div>
<div class="right">Remaining space</div>
</div>
Flexbox can do that.
Support is IE10 and up.
JSfiddle Demo
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
#container {
height: 100%;
display: flex;
flex-direction: column;
}
#top {
background-color: lightgreen;
}
#bottom {
background-color: lightblue;
flex: 1;
}
<div id="container">
<div id="top">green box variable height</div>
<div id="bottom">blue box no longer overflows browser window</div>
</div>
I'm looking for something simple and portable. In the same way a CSS
property can be easily applied across documents, I'm looking for
something similar in terms of ease-of-application for this function.
... isolated fix is preferred.
Horizontal:
This can be achieved using CSS only. As you do not prefer a flex layout solution, the next best bet would be a table layout.
A simple CSS snippet which you could drop into your project (and be done with) would look like this:
div.flexh {
display: table; box-sizing: border-box; padding: 0; margin: 0;
}
div.flexh > div {
display: table-cell; width: auto;
box-sizing: border-box; vertical-align: middle;
}
div.flexh > div:first-child {
/* Override your custom styling below */
min-width: 75px; width: 75px; max-width: 75px;
}
div.flexh > div:last-child { width: 100%; }
You can then add your site-specific styling to this base CSS as per site requirements. Like, nowrap etc.
Two apparent advantages of this solution are:
You do not need to change your markup and also do not need to decorate all children with classes. Just apply the class flexh to your parent div and that would be it.
Minimal Markup Required:
<div class="flexh">
<div>...</div>
<div>...</div>
<div>...</div>
</div>
You are not limited to just three columns. You could have as many columns as need be. The first one will have fixed width, the last one will be flexible, and all the columns in-between would get content-based widths.
Demo Fiddle: http://jsfiddle.net/abhitalks/qqq4mq23/
Demo Snippet:
div.flexh {
display: table; box-sizing: border-box; padding: 0; margin: 0;
/* Override your custom styling below */
width: 80%; border: 2px solid black;
border-right: 2px dashed black;
font-size: 1em;
}
div.flexh > div {
display: table-cell; width: auto;
box-sizing: border-box; vertical-align: middle;
/* Override your custom styling below */
background-color: lightgreen; border: 1px solid #ddd;
padding: 15px 5px;
}
div.flexh > div:first-child {
/* Override your custom styling below */
min-width: 75px; width: 75px; max-width: 75px;
background-color: orange;
}
div.flexh > div:last-child {
width: 100%;
/* Override your custom styling below */
background: skyblue;
}
<div class="flexh">
<div>75px Fixed Width</div>
<div>Variable Content Width</div>
<div>Flexible Remaining Width</div>
</div>
<hr/>
<div class="flexh">
<div>75px Fixed Width</div>
<div><img src='//placehold.it/128x48/66c' /></div>
<div>Flexible Remaining Width</div>
</div>
<hr/>
<div class="flexh">
<div>75px Fixed Width</div>
<div>Variable TextWidth</div>
<div>
<img src='//placehold.it/128x48/66c' />
<p>Variable ContentWidth</p>
</div>
<div>Flexible Remaining Width</div>
</div>
Vertical:
This is a bit tricky to achieve without flex layout. A table layout would not work here mainly because, the table-row would not keep a fixed height as required by your use-case. The height on a table-row or table-cell is only an indicative of the minimum height required. If the space is constrained, or the content exceeds the available space, then the cell or row will increase its height depending on the content.
As per the specs here: http://www.w3.org/TR/CSS21/tables.html#height-layout
The height of a 'table-row' element's box is calculated once the user
agent has all the cells in the row available: it is the maximum of the
row's computed 'height', the computed 'height' of each cell in the
row, and the minimum height (MIN) required by the cells...
...the height of a cell box is the minimum height required by the
content
This effect can be seen here: http://jsfiddle.net/abhitalks/6eropud3/
(Resize the window pane and you will see that the first row will increase in height as the content cannot be fit into the specified height, hence defeating the purpose)
Therefore, you can restrict the height indirectly either using inner markup like a div element, or let go of the table-layout and calculate the height for the flexible one. In your use-case, you prefer not to change the markup, hence I am not proposing an inner markup.
The best-bet here would be to use the time-tested model of plain block-level divs with the height of the flexible one to be calculated. As you have already discovered that it is not possible with CSS, you will need a small JavaScript snippet to do that for you.
A simple JavaScript snippet (no jQuery) which you could wrap in a window.load and drop into your project (and be done with) would look like this:
var flexv = document.querySelectorAll('div.flexv');
/* iterate the instances on your page */
[].forEach.call(flexv, function(div) {
var children = [].slice.call(div.children), // get all children
flexChild = children.splice(-1, 1), // get the last child
usedHeight = 0, totalHeight = div.offsetHeight;
children.forEach(function(elem) {
usedHeight += elem.offsetHeight; // aggregate the height
});
/* assign the calculated height on the last child */
flexChild[0].style.height = (totalHeight - usedHeight) + 'px';
});
The CSS snippet is more or less like the horizontal one, sans table layout, which also you could just drop into your project and just add the additional site-specific styling. Minimal markup required remains the same.
Demo Fiddle 2: http://jsfiddle.net/abhitalks/Ltcuxdwf/
Demo Snippet:
document.addEventListener("load", flexit);
function flexit(e) {
var flexv = document.querySelectorAll('div.flexv');
[].forEach.call(flexv, function(div) {
var children = [].slice.call(div.children),
flexChild = children.splice(-1, 1),
usedHeight = 0, totalHeight = div.offsetHeight;
children.forEach(function(elem) {
usedHeight += elem.offsetHeight;
});
flexChild[0].style.height = (totalHeight - usedHeight) + 'px';
});
}
div.flexv {
display: inline-table; box-sizing: border-box; padding: 0; margin: 0;
overflow: hidden;
/* Override your custom styling below */
height: 320px; width: 20%; border: 1px solid black; font-size: 1em;
margin: 8px;
}
div.flexv > div {
display: block; height: auto; box-sizing: border-box;
overflow: hidden;
/* Override your custom styling below */
background-color: lightgreen; border: 1px solid #ddd;
padding: 5px 15px;
}
div.flexv > div:first-child {
/* Override your custom styling below */
min-height: 36px; height: 36px; max-height: 36px;
background-color: orange;
}
div.flexv > div:last-child {
height: 100%;
/* Override your custom styling below */
background: skyblue;
}
<div class="flexv">
<div>36px Fixed Height</div>
<div>Variable Content Height</div>
<div>Flexible Remaining Height</div>
</div>
<div class="flexv">
<div>36px Fixed Height</div>
<div><img src='//placehold.it/64x72/66c' /></div>
<div>Flexible Remaining Height</div>
</div>
<div class="flexv">
<div>36px Fixed Height</div>
<div>Variable Text Height</div>
<div>
<img src='//placehold.it/72x48/66c' />
<p>Variable Content Height</p>
</div>
<div>Flexible Remaining Height</div>
</div>
Note: As pointed out by #LGSon, the display: inline-table used for the demo does not play well with Firefox. This is only for a demo and should be replaced by either block or inline-block as per your use-case.
Updated
As I commented earlier, and besides flex, this is also solvable using display: table and here is a fiddle demo I made showing that.
If a fixed top also were required for the vertical demo, here is an update of my original display:table version: fiddle demo
Sometimes I haven't been able (or didn't want) to use either flex nor tables, and I have, on and off, looked into making use of css calc() and css attr().
Both come short though, as calc() can only use +-*/ and attr() can only return a string value, which can't be computed by calc().
My suggestion, using plain javascript, is based on that these 2 methods, at some point, might be extended so we can make better use of them.
This is how I would like see them work;
width: calc(100% - attr(this.style.left))
but as they don't, and I can't add it to my css either as it wouldn't validate properly (might even break the parsing, who knows) I added a variant as an attribute on the element instead, with some quirks to make it easier to compute.
And in this case (the 2 demos) it looks like this:
//height
<div id="bottom" data-calcattr="top,height,calc(100% - toppx)">...</div>
//width
<div class="box right" data-calcattr="left,width,calc(100% - leftpx)">...</div>
Together with below script, which by no means is fully developed/tested on all property combinations, it does adjust the div's size.
In short, when runned, it take the attribute, split it into an array, take the first item value as from which property to read, the second to which property to set and the third to which the read value gets inserted/replaced and assigned to the property to be set (hmmm, still working on a better way to express this, but hopefully the script is clear enough with whats going on).
Here is a fiddle showing both the height and width demo, integrated, making use of the same script.
function calcattr() {
var els = document.querySelectorAll('[data-calcattr]');
for (i = 0; i < els.length; i++) {
var what = els[i].getAttribute('data-calcattr');
if (what) {
what = what.split(',');
var rect = els[i].getBoundingClientRect();
var parentrect = els[i].parentNode.getBoundingClientRect();
var brd = window.getComputedStyle(els[i].parentNode,null).getPropertyValue('border-' + what[0] + '-width');
what[2] = what[2].replace(what[0],parseInt(rect[what[0]]-parentrect[what[0]]) - parseInt(brd));
els[i].setAttribute("style", what[1] + ":" + what[2]);
}
}
}
IN CSS
Although I've never tried it, I believe that this would work:
.top {
height:13px;
}
.main {
height:calc(100% - var(height));
}
http://www.creativebloq.com/netmag/why-you-need-use-css-variables-91412904
IN SASS
$top_height: 50px
.main {
height: calc(100% - $top_height)
}
Sass Variable in CSS calc() function
In both cases on container css you should put:
#container {
overflow: hidden;
}
But, it will hide the information that overflows the container. I think that is the point, since you put white-space: nowrap; it means that you don't want to change the height, so you have to hide the text that can't fits the container.

Is this an efficient way of reordering HTML with jQuery?

The script below checks the browser width and moves some divs around if it detects the css element text-align:center on a dom element. This css element is dependent on a media query for 980px. The code works without a hitch but I feel like maybe there was a simpler way of doing this. I am aware this probably could have been accomplished in CSS through floats but felt like this would be a cleaner way of doing it. Any advice regarding how to make this code more efficient would be greatly appreciated.
$(document).ready(function(){
function moveDiv(){
var $window = $(window);
var windowsize = $window.width();
if (windowsize < 980) {
if ($(".interiortitle h1").css("text-align") == "center"){
$( ".interiorpage .et_pb_column_1_4").insertAfter(".interiorpage .et_pb_column_3_4");
}
}
else if (windowsize > 980) {
$( ".interiorpage .et_pb_column_1_4").insertBefore(".interiorpage .et_pb_column_3_4");
}
}
moveDiv();
$(window).resize(moveDiv);
});
You could try this out:
Check if your window size has changed and apply a new class for your div:
var changeposdiv= $('.changeposdiv');
var $window = $(window);
var windowsize = $window.width();
if (windowsize > 980) {
changeposdiv.addClass('more980');
}
Your HTML example
<div class="interiordiv">
ABC
</div>
<div class="changeposdiv">
Change it
</div>
And CSS will move elements in user's screen
.changeposdiv, .interiordiv {
float: left
}
.more980 {
float: right;
}
Does it help you?
Are you looking for something like this? As you change the width of the page, the red and green columns swap sides.
HTML
<html>
<body>
<div class="interiorpage">
<div class="et_pb_column_1_4"></div>
<div class="et_pb_column_3_4"></div>
</div>
</body>
</html>
CSS
.interiorpage{
height: 200px;
border: 1px solid black;
display: flex;
display: -webkit-flex;
flex-direction: row;
-webkit-flex-direction: row;
}
div[class^=et_pb_column_]{
width: 50%;
height:100%;
}
.et_pb_column_1_4{
background: #fcc;
order: 2;
-webkit-order: 2;
}
.et_pb_column_3_4{
background: #cfc;
order: 1;
-webkit-order: 1;
}
#media all and (max-width: 500px) {
.et_pb_column_1_4{
order: 1;
-webkit-order: 1;
}
.et_pb_column_3_4{
order: 2;
-webkit-order: 2;
}
}

How to keep div in center-height when I resize the browser window?

I am trying to center in height a div, however it does not work when I resize the browser screen.
How to edit this to achieve the adjustable margin-top on resize?
Thank you
<script>
var h = $(window).height();
var parentHeight = h;
var childHeight = $('#a-middle').height();
$('#a-middle').css('margin-top', (parentHeight - childHeight) /2);
</script>
Edit:
The answer should be in js since flexbox won't work on IE-9
you should stick to a CSS solution though, there are several way to achive this
.alignVertical {
position:relative;
display:inline-block;
top:50%;
transform:translateY(-50%);
}
jsfiddle: https://jsfiddle.net/jorjmt70/
or using flexbox
.parent {
display:flex;
height:100vh;
background-color:red;
justify-content:center;
align-items:center;
flex-direction:column;
}
jsfiddle: https://jsfiddle.net/mdh9h876/
if you want to use flex box use autoprefixer to get deeper browsersupport:
https://github.com/postcss/autoprefixer
Although you can easily do this with pure CSS, your bounty stated that you want a JS answer.
If you are interested in a pure CSS answer, see this answer that has multiple different methods on how to center elements vertically/horizontally.
You could simplify your jQuery to the following:
$('#a-middle').css('margin-top', function () {
return ($(window).height() - $(this).height()) / 2
});
Then you could just place this within a resize event listener and chain the .resize() method in order to trigger the event initially when the browser loads.
Example Here
$(window).on('resize', function () {
$('#a-middle').css('margin-top', function () {
return ($(window).height() - $(this).height()) / 2
});
}).resize();
JavaScript equivalent (without jQuery):
Example Here
var verticalCentering = function () {
var el = document.querySelector('#a-middle');
el.style.marginTop = (window.innerHeight - el.offsetHeight) / 2 + 'px';
}
window.addEventListener('resize', verticalCentering);
verticalCentering();
For a div called 'center-me':
$(document).ready(centerDiv);
$(window).resize(centerDiv);
function centerDiv() {
var winHeight = $(document).innerHeight(),
divHeight = $('.center-me').height();
$('.center-me').css('marginTop', (winHeight - divHeight) / 2 );
}
You need to call it when the document is ready, to get it centered in the first place, then on resize-event, to keep it centered.
Here is the fiddle for it: Fiddle
A CSS solution could do the trick for you.
div.center {
height: 100px;
width: 300px;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -150px;
position: absolute;
background-color: red;
}
<div class="center">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
This CSS code work fine in IE8+, Firefox and Chrome.
But you must know the sizes of the DIV that you want to adjust correctly. If the height and width are dynamic, you just have to update the style accordingly with JavaScript. Don't forget to apply the class center in JS on need to your DIV.
Explanations :
margin-top : - height / 2 because top : 50% only centered vertically the top of the DIV.
margin-left : - width / 2 because left : 50% only centered horizontally the left of the DIV.
position : absolute so that the DIV can center over all the page.
This can be achieved using simple CSS with deep browser support back to IE8.
html, body {
height: 100%;
}
.parent {
display: table;
table-layout: fixed;
width: 100%;
height: 100%;
}
.child {
display: table-cell;
vertical-align: middle;
text-align: center;
background: red;
}
<div class="parent">
<div class="child">This is always centered.</div>
</div>
Using table-layout makes it simple: the child can be vertically aligned (top, middle, bottom) and will take up all the available height. You're not resorting to JavaScript, CSS with patchy support or having to hard-code any figures, it should just work.
Depending on the specifics of what you're looking to do, flexbox or - as a last resort - JavaScript might be required, but for most cases display: table-cell is your friend.
That said, if it's acceptable for older browsers to get a different layout, just use #Victor's answer: this is what flexbox is for.
To make a div always stay at the center of the screen, the properties you could use are top and left attributes after setting the position attribute to absolute. However you will need to set these properties dynamically when the browser is resized. This can be done using the JQuery method - resize().
/*css code*/
.div{
position:absolute;
top:100px;
left:50px;
background:black;
}
/*JS Code*/
function keep_div_centered()
{
window_height = $(window).height();
window_width = $(window).width();
obj_height = $('.keepincenter').height();
obj_width = $('.keepincenter').width();
$('.keepincenter').css('top',(window_height/2)-(obj_height/2)).css('left',(window_width/2)-(obj_width/2))
}
keep_div_centered();
$(window).resize(function(){
keep_div_centered();
})
/* HTML Code */
<div class="keepincenter"></div>
Link to the fiddle - http://jsfiddle.net/y0937t06/
$(window).resize(function () {
var h = $(document).height();
var parentHeight = h;
var childHeight = $('#imagegallery').height();
$('#imagegallery').css('margin-top', (parentHeight - childHeight) / 2);
});
For me, this is the holy grail of CSS :)
The most reliable method I found is setting the container element as follows:
display: -webkit-flex;
-webkit-justify-content: center; /* horizontal */
-webkit-align-items: center; /* vertical */
It is simple and has no prerequisites on any other CSS properties.
The fiddle below places content 30px above vertical center:
#container {
width: 500px;
height: 300px;
background-color: red;
display: -webkit-flex;
-webkit-justify-content: center;
-webkit-align-items: center;
}
#content {
background-color: green;
margin-bottom: 30px;
}
<div id="container">
<span id="content">Content</span>
</div>
Handle window_resize event of the current window and try putting above code there.
It should give you expectd functionality.
This approach is very useful when you want to center both vertically and horizontally an absolute position div. It work also on IE8
You need to set the both outer and inner divs as
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin:auto;
margin:auto it's fundamental to center divs in this case.
You could also set the height and width of the .in div and still you would see it centered vertically and centered also when you resize the browser.
* {
margin: 0;
padding: 0;
}
html, body {
position: relative;
height: 100%;
width: 100%;
}
.in, .out {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin:auto;
}
.in {
background-color: red;
height: 50%;
width:50%;
}
.out {
background-color: blue;
}
EXAMPLE 1 JSFIDDLE height, width: in percentages: http://jsfiddle.net/a_incarnati/1o5zzcgh/3/
EXAMPLE 2 - JSFIDDLE fixed height, fixed width
http://jsfiddle.net/a_incarnati/1o5zzcgh/4/
Give display: table-cell; to the parent and align the contents vertically using vertical-align and give the padding to adjust the necessary spacing from top.
.child{
display:table-cell;
vertical-align:top;
padding-top: 50px;
}
This will keep the margin uniform throughout.
use css
first give a height to your element.
#a-middle {
height: 20px;
position: fixed;
top: calc(50% - 10px);
left: 0;
}
or use js
$(function(){
$('#a-middle').each(function(){
var t = $(window).height()/2 - $(this).outerHeight()/2;
$(this).css({top: t + "px"});
});
});
$(window).resize(function(){
$('#a-middle').each(function(){
var t = $(window).height()/2 - $(this).outerHeight()/2;
$(this).css({top: t + "px"});
});
});
The problem with the previous solutions is that you won't be able to center the div, if he's larger than the available vertical size.
If you want your div to take 50% of the page you can use the CSS vertical height based unit:
.mydiv {
height: 50vh;
top: 50%;
left: 50%;
position: fixed;
width: 50vh;
margin-top: -25vh;
margin-left:-25vh;
border: solid black 1px;
}
So your DIV will not only be centered but also maintain its ratio.
Play with margin-left and margin-top of that div, using the width and height of the window and div.
$(function () {
makeDivCenter();
$(window).resize(function () {
makeDivCenter();
});
});
function makeDivCenter() {
var windowWidth = $(window).width();
var divWidth = $(".center").width();
var windowHeight = $(window).height();
var divHeight = $(".center").height();
$(".center").css({
'margin-left': (windowWidth / 2) - (divWidth / 2) + "px",
'margin-top': (windowHeight / 2) - (divHeight / 2) + "px"
});
}
Here is jsfiddle for your reference https://jsfiddle.net/fnuud7g6/

Categories

Resources