Centering two buttons into child div of a parent div - javascript

I am using dat.gui.js to have a parameters menu with Three.js. I would like to put this menu on the top-right of main window. Moreover, I would like to add 2 buttons at the bottom of this menu which have to be centered horizontally and relatively to the parent div.
Here's an example in JS Fiddle.
As you can see, into HTML, I have the following structure for child and parent div:
<div id="webgl">
<div id="global-ui">
<div id="gui">
</div>
<div id="buttons">
<button type="button" id="startButtonId" class="btn btn-primary" tabindex="13">Start Animation</button>
<button type="button" id="resetButtonId" class="btn btn-default" tabindex="14">Reset</button>
</div>
</div>
</div>
with the CSS for #gui:
gui.domElement.id = 'gui';
which corresponds to:
#global-ui {position: relative;}
#gui {position: absolute; top: 0; right: 0;}
#buttons {position: absolute; top: 200px;}
#global-ui div represents the parent div of #gui div and #buttons div.
With this css, I get the following image:
and I would like to get this:
As you can see on the first image, there are 2 issues : first, the DAT.GUI is not located strictly on the right and top even with CSS "#gui {position: absolute; top: 0; right: 0;}". It seems there is a margin on the right.
Second problem, the two buttons are not centered relatively to DAT.GUI, I tried using "margin: 0 auto;" or with "text-align: center;" but without success. I want to center it relatively to #gui div container and with an automatic way.
How can I solve these two issues?

As for the spacing to the right of the controls, your #gui element has a right margin of 15px, so you can correct this by adding margin-right:0; to the CSS rules for #gui:
#gui {position: absolute; top: 0; right: 0; margin-right:0;}
As for aligning the elements to be centered, I've broken it down here:
Theory
In order to center something like div, the way to do it with CSS is to have the child element use margin-right and margin-left both set to auto, and the parent element needs to be wide enough to fill the area area you want the containers to be centered inside.
Solution
The width of the container (in this case #buttons) is only as wide as the buttons inside it make it, so there's not enough width for the buttons to be able to be centered if you were to simply do this:
#button {
margin-left: auto;
margin-right: auto;
}
Therefore, the width #buttons container has to be increased so that it is as wide as you need it to be, in this case, to be as wide as the #gui element, but doing just that still doesn't let the buttons be centered because there are two of them, so you need a wrapper element inside which creates space inside for the buttons to center within. This looks like this in the DOM:
<div id="buttons-wrapper">
<div id="buttons">
<button type="button" id="startButtonId" class="btn btn-primary" tabindex="13">Start Animation</button>
<button type="button" id="resetButtonId" class="btn btn-default" tabindex="14">Reset</button>
</div>
</div>
And then #buttons-wrapper needs to be set to the width of #gui (the target width of the space which the buttons should be centered), and #buttons needs to be set to a width which is equal to the sum of the child containers #startButtonId and #resetButtonId, and then margin-right and margin-left can finally be applied to #buttons and it will work as expected.
To set the width dynamically, you've got to use JavaScript and measure the widths of the containers you need:
document.getElementById('buttons-wrapper').style.width = gui.width + 'px';
target_width = 5; // a couple pixels extra
target_width = target_width + document.getElementById('startButtonId').offsetWidth;
target_width = target_width + document.getElementById('resetButtonId').offsetWidth;
document.getElementById('buttons').style.width = target_width + 'px';
I've put the complete solution for your specific case into this fiddle: http://jsfiddle.net/bnbst5sc/4/
Generic Solution
Here it is outside the context of your solution, as a general case:
#outer-wrapper {
position: absolute;
top: 100px;
left: 150px;
width: 300px;
padding: 10px 0;
background-color: #ff0000;
}
#inner-wrapper {
margin-left: auto;
margin-right: auto;
width: 175px;
padding: 10px 0;
background-color: #00ff00;
}
button {
display: inline-block;
float: left;
}
#btn1 {
background-color: #f0f000;
width: 100px;
}
#btn2 {
background-color: #00f0f0;
width: 75px;
}
<div id="outer-wrapper">
<!-- #outer-wrapper, has an arbitrary width -->
<div id="inner-wrapper">
<!-- #inner-wrapper, as wide as the sum of the widths of #btn1 and #btn2 and has margin-left and margin-right set to auto-->
<button id="btn1">Button 1</button>
<button id="btn2">Button 2</button>
</div>
</div>

Related

Containers overlapping when size of window is small

When the window size is small(or while using it on some small screen phones) the buttons are overlapping the heading. Here's the code:
<style>
body {
font-family: Arial, Helvetica, sans-serif;
}
.x2 {
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
text-align: center
}
<body>
<div style="background-color: #E9ECEF">
<br><br>
<center>
<h1>Survey Management System</h1>
<center>
</div>
<div class="x2">
<p><button Class="btn btn-warning" onclick="document.location = 'user/registration.html'">Register</button></p>
<p><button Class="btn btn-warning" onclick="document.location = 'user/Login1.html'">Login</button></p>
<p><button Class="btn btn-warning" onclick="document.location = 'admin/alogin.html'">Admin Login</button></p>
</div>
I am a beginner and any help regarding this will be highly appreciated. Any other suggestion that you find helpful are also welcomed.
The problem is absolute positioning. If you use absolute positioning, you break the links of your div from your page (if no relative positioning exists in parent).
position: absolute It looks the first element which has a relative position on parent level and it adjusts its position accordingly to the relative element. If no relative element exists in the parent tags, it adjusts its position accordingly to the page.
Try to give a
position: relative;
to your x2 and try again. If you want to center things, you must give the top position like
top: calc(50% + "height of header");

Margin issue with jquery load()

I am loading html page inside a div with jquery. It does work fine.
var loginBtn = $("#loginBtn");
var loginPage = $("#login");
var submitBtn = $("#submitBtn");
var submitPage = $("#submit");
var checkBtn = $("#checkBtn");
var checkPage = $("#check");
loginPage.load( "login.html" );
submitPage.load( "submitPoints.html" );
checkPage.load( "checkPoints.html" );
body {
margin: 0 !important;
padding: 0 !important;
background-color: white;
}
#mainFrame {
width: 100%;
height: 300px;
background-color:cadetblue;
padding-top: 0;
margin-top: 0px;
position: relative;
}
<div id="mainFrame">
<div id="login"></div>
<div id="check"></div>
<div id="submit"></div>
</div>
My issue is that if the loaded html has no content, the margin between the parent document body (white) and the top of the loaded html (green) is none (that's what I want, it's ok).
However as soon as I add content to the loaded html, a gap is generated at the top of the page :\
I thought it was all about setting some line-height prop in the css but it seems helpless.
Any ideas what I am doing wrong ?
What you are seeing is the top margin of the first piece of content overflowing its container (also known more commonly as margin collapsing):
body {
background:yellow;
}
#container {
background:green;
height:300px;
}
<div id="container">
<h1>I have a top margin of 1em by default that is overflowing into the body.</h1>
</div>
If you give your container element a padding of that same amount, the margin space of the body won't be used and the element will be pushed down in the green area.
body {
background:yellow;
}
#container {
background:green;
height:300px;
padding:1em;
}
<div id="container">
<h1>I have a top margin of 1em by default that is now contained within my parent.</h1>
</div>
Or, you could set the top margin of the first piece of content to zero:
body {
background:yellow;
}
#container {
background:green;
height:300px;
}
#container > h1:first-child { margin-top:0; }
<div id="container">
<h1>My top margin has been set to zero.</h1>
</div>
Finally, you could set the overflow of the content area to auto but (although this seems to be the popular answer), I don't prefer this approach as you run the risk of unintended fitting of the content as the content changes and/or the container size changes. You give up a bit of sizing control:
body {
background:yellow;
}
#container {
background:green;
height:300px;
overflow:auto;
}
<div id="container">
<h1>The content area has had its overflow set to auto.</h1>
</div>
When you load new content it gets rendered in the document and those new elements might have properties. In this case, most probably the Login has a margin value. Another option is that it has a class or some selector that is being picked up by a CSS file which appends the margin to it.
Easiet way would be to right-click on the Login element, choose inspect, and analyze the style of the element with web-dev / style.
If you want to keep the margin on the inner content, you should set an overflow. Look what happens when we remove the overflow: auto line from .content > div (try clicking the box after running the code sample below).
This is because of margin collapsing. The margin on the inner content is combined with the margin on the outer element and applied on the outer element, i.e. two margins of the two elements are collapsed into a single margin.
document.querySelector('.content').addEventListener('click', (e) => {
e.target.classList.toggle('overflow');
});
html,
body {
margin: 0;
padding: 0;
}
.outer {
width: 200px;
background: red;
}
.content > div {
width: 100%;
height: 300px;
background: cadetblue;
cursor: pointer;
}
.content > div.overflow {
overflow: auto;
}
.test {
margin: 10px;
display: block;
}
<div class="outer">
<div class="content">
<div><span class="test">Test</span></div>
</div>
</div>

How to position a div above another div?

My code is:
HTML:
<section>
<div id="banner">
<div class="container">
<p class="para">hello world</p>
</div>
<div class="container banner-bottom">
<div class="card card-primary text-center z-depth-2 contact-main-text">
<div class="card-block">
<p class="white-text">Please fill out the form below and ESC
staff will be in contact with you shortly.</p>
</div>
</div>
</div>
</div>
</section>
CSS:
.para{
color:white;
background: red;
padding:70px;
text-align:center;}
.white-text{
background:green;
padding:20px;}
Output is: Bootply
And i want:
Could anyone help me with that?
You can set negative top margin to overlay the second div, see the live example:
<div class="container banner-bottom" style="margin-top:-5%;padding:2%">
http://www.bootply.com/MorC45NB4V
PS: I have used inline css just to show, avoid inline css.
My solution uses jQuery and some calculations. My calculation works even if you move the elements around the document. I also used CSS for the margins you wanted.
jQuery
//location of bottom of the red container
var bottomOfContainer = $('#onTopOfMe').offset().top + $('#onTopOfMe').height();
//gets the bottom 4th of the red container
var placement = bottomOfContainer - ($('#onTopOfMe').height() / 4);
//setter of top for green container
$('#placeMe').offset({"top": placement});
CSS
p.white-text{
margin-left:5%;
margin-right:5%;
}
Output
bootply
1) In case you want your lower banner to have a full width:
You could add position: relative; to the lower banner and position it adding a bottom value and use margin to create the same visual effect asked in the question.
.banner-bottom {
position: relative;
bottom: 45px;
margin: 0 40px;
}
2) In case you don't need to have a banner with full width and just center it, then no need to use margins. Remember to set one parent as position: relative;:
#banner { position:relative;}
.banner-bottom {
position: absolute;
top:75%;
right:0;
bottom:auto;
left:0;
}
CODEPEN
http://codepen.io/alexincarnati/pen/PWOPjY
Here's my solution for this.
Basically just make the position of the card block "relative", position the "top" position accordingly, then set the margin to "auto" to center it.
.card-block {
position: relative;
top: -50px;
margin: auto;
width: 80%;
}
A bit of position could help you, here's a rough version that will hopefully get you thinking what you need to do:
#banner { position:relative;}
.banner-bottom { position: absolute; top:75%;right:0;bottom:auto;left:0; }
Heres a forked bootply: http://www.bootply.com/Imuh4wUj50

Automatically resizing div

This is another of the infinite questions about how to get div sizing to behave, but conversely I haven't been able to find a sufficiently similar question to get my particular case working.
function update() {
$('#container .body-text').bigText({verticalAlign:'top',whiteSpace:'pre'});
}
function doresize(form) {
var container = $('#container')[0];
container.style.height = form.height.value + 'px';
setTimeout(500, update);
}
function dotext(form) {
$('#container .body-text').text(form.text.value);
update();
}
update();
.container {
float: left;
border: solid 1px black;
position: relative;
margin-left: 5px;
width: 20%;
height: 200px;
padding: 2px;
}
.header {
width: 100%;
height: 64px;
background-color: blue;
}
.body {
width: 100%;
height: 100%;
max-height: calc(100% - 64px);
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://rawgithub.com/DanielHoffmann/jquery-bigtext/master/jquery-bigtext.js"></script>
<form name="setup">
<label>Set height: <input type="number" name="height" value="200" /></label>
<button type="button" onclick="doresize(this.form)">Resize</button><br />
<label>Set text: <textarea name="text">Multi-Line
Text</textarea></label>
<button type="button" onclick="dotext(this.form)">Change</button><br />
</form>
<br />
<div id="container" class="container" onload="update()">
<div class="header"></div>
<div class="body"><div class="body-text">Multi-Line
Text</div></div>
</div>
The above snippet shows a fairly basic layout with a container div with a width and height that are controlled by outside forces. (In the real code this is controlled by the browser window resizing, but I've put in a basic form height adjustment here for demonstration purposes.)
What I'm trying to achieve with this is the following:
Both internal divs fill to 100% width of their parent.
The top (blue) div has a fixed height.
The bottom (green) div will use the remaining space in the parent by default.
However, after a bit of existing JS code resizes the font size of the text to best-fit this space (both width and height)...
If the container is tall enough and the text is short enough that there's extra space below, then the green div should vertically shrink to fit its text and both the blue and green divs should then appear vertically centred in the container div.
If the container size or the text changes, repeat the process of fitting the text and recentering.
I know how to do most of the pieces individually, I'm just not sure how to put it all together, and whether step 5 is possible with CSS or whether it requires JS. (I've tried adding the vertical centering with CSS via the absolute-translate-50% trick, which works great at tall container sizes or text that is wider than it is tall, but not the other way around -- the text overflows the green div because the height is not fixed so can't be taken into account by the font sizing script.)
I'm ok with rearranging or inserting additional divs if this is required.
EDIT: the following snippet inspired by Shadi's answer seems to do the trick:
function update() {
var text = $('#container .body-text');
text.parent().parent().css('height', '100%');
text.parent().css('height', '100%');
text.bigText({verticalAlign:'top',whiteSpace:'pre'});
text.parent().css('height', text.height());
text.parent().parent().css('height', text.height() + 64);
}
function doresize(form) {
$('#container').css('height', form.height.value);
update();
}
function dotext(form) {
$('#container .body-text').text(form.text.value);
update();
}
update();
.container {
float: left;
border: solid 1px black;
margin-left: 5px;
width: 20%;
height: 200px;
padding: 2px;
}
.subcontainer {
position: relative;
width: 100%;
height: 100%;
top: 50%;
transform: translateY(-50%);
}
.header {
width: 100%;
height: 64px;
background-color: blue;
}
.body {
width: 100%;
height: 100%;
max-height: calc(100% - 64px);
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://rawgithub.com/DanielHoffmann/jquery-bigtext/master/jquery-bigtext.js"></script>
<form name="setup">
<label>Set height: <input type="number" name="height" value="200" /></label>
<button type="button" onclick="doresize(this.form)">Resize</button><br />
<label>Set text: <textarea name="text">Multi-Line
Text</textarea></label>
<button type="button" onclick="dotext(this.form)">Change</button><br />
</form>
<br />
<div id="container" class="container">
<div class="subcontainer">
<div class="header"></div>
<div class="body"><div class="body-text">Multi-Line
Text</div></div>
</div>
</div>
Try values between 80 and 300 to see it in action.
I have tried this in a code, please would you try it and see if it fits your need, the following code will make the green div fullfil the remining container height, and then after calcuating the text size and width it shrinks to fit the new text height
function update() {
$('#container').css('height', '200px' /*this would be dynamic based on the container height*/);
$('#container .body-text').bigText({ verticalAlign: 'top', whiteSpace: 'pre' });
$('#container').css('height', $('#bodytxt').height() + 64 /*this is the header height - blue div*/);
}
You need also to add an id for your bodytext div:
<div id="bodytxt" class="body-text">Multi-Line Text</div>

Fixed-Position Div Not Animating With JQuery

I am trying to get the div with id="markdown-editor" to slide over when a button is clicked using JQuery's Animate function. markdown-editor contains two divs that have position: fixed. The div with id=header doesn't have any other positioning css (top, bottom, left, etc.), but the other div, where id=footer, has bottom: 0px. When I animate the #markdown-editor div, everything inside #markdown-editor animates correctly except #footer. I know it has something to do with using positioning css, but I'm not sure what to do about it. Below is the pertinent code:
HTML:
<div id="markdown-editor" class="col-xs-12">
<div id="header" class="row">
...
</div>
<div class="row">
...
</div>
<div id="footer" class="row">
...
</div>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
CSS:
#header {
position: fixed;
padding-top: 15px;
z-index: 9001;
}
#footer {
position: fixed;
bottom: 0px;
width: 100%;
margin: auto;
z-index: 9001;
padding: 10px;
}
Javascript:
$("#menu-button").on("click", function(e) {
$("#markdown-editor").animate({left: "20%"}, 500, "swing");
});
You need quotes around the first #menu-button in the Javascript portion.
You forgot quotes around #menu-button
$("#menu-button").on("click", function(e) {
$("#markdown-editor").animate({left: "20%"}, 500, "swing");
});
EDIT
Make sure you're linking to the jQuery library in your head.
Also, try giving #markdown-editor a left value in your css. Also, you need to give it a position. It doesn't matter if the elements inside it have position, the actual element needs a position in order to animate. Has to be fixed, relative, or absolute.
#markdown-editor {
position: relative; // or fixed or absolute
left: 2px;
}

Categories