Dynamically create and position button: center/bottom

Hi,

I’m trying to dynamically create a basic button (to launch an action onclick) on a page that has a centered 640X640 canvas. The page is set up as 750X750. The button would need tobe at center bottom below the canvas (can be 20 px below, for example).

So far, using the following, I can get it to work OK. But done by “trial and error.” Not sure as beginner what would be the correct way to accomplish this, since need to also place additional buttons dynamically on this and other similar pages.

Any help appreciated.

//HTML
<button name="start" type="button" onclick="starter()"
style="background-color:white;">
start</button>

//CSS
canvas{
    border:1px solid black;
	position: absolute;
  	top: 50%;
  	left: 50%;
  	margin-left: -320px;
  	margin-top: -320px;
}
button{
   	position:absolute; 
   	margin-left:47%;   
   	width:150px;
   	bottom:280px;
}

Thank you for your help.

Kind Regards,

writer1

You really want the button and the canvas element to move together as the screen size moves, so I would wrap the canvas and the button in a container div set to position: relative. You can center the element horizontally with with auto margins and perhaps setting it to display: table, and center it vertically like you did before, with a top setting and negative top margin. Then the button can be centered under it. You don’t really need to set a position on it at all, but if you do, it will at least be positioned in relation to the container, rather than to the browser window.

Hi Ralph,

Thank you for these suggestions. A little challenging for a beginner. But, I can do some more reading online, see how to make a container that can hold the canvas and button. (Yes, they do need to move together.)

Maybe something like this? (Would need to fix some of the parameters as well?)

<div id="container">
<div id="canvas"></div>
<div id="button"></div>
#canvas{
    border:1px solid black;
	position:relative;
        display:table;  	
        top: 50%;
  	left: 50%;
  	margin-left:auto;
  	margin-top: -320px;
}
#button{
   position:absolute; 
   margin-left:auto;
   
   width:150px;
   bottom:280px;
}
</div>

Probably some errors in the above (haven’t tried it out yet). Any suggested corrections/additions/changes would be appreciated.

Much thanks.

Best Wishes,

writer1

HI,

For ie8+ you can do it like this:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
html, body {
	height:100%;
	margin:0;
	padding:0;
}
h1 { margin:0 }
.outer {
	display:table;
	width:640px;
	margin:auto;
	height:100%;
	text-align:center;
}
.inner {
	display:table-cell;
	vertical-align:middle;
	width:100%;
	height:100%;
}
.content {
	width:640px;
	height:640px;
	margin:auto;
	position:relative;
	background:blue;
}
.button {
	position:absolute;
	bottom:-50px;
	left:0;
	width:640px;
	height:30px;
	line-height:30px;
	text-align:center;
	background:red;
}
</style>
</head>

<body>
<div class="outer">
		<div class="inner">
				<div class="content">
						<h1>Ie8+</h1>
						<div class="button">Button content would be here</div>
				</div>
		</div>
</div>
</body>
</html>


For ie6+ you can use this method instead.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
html, body {
	height:100%;
	margin:0;
	padding:0;
}
h1 { margin:0 }
.spacer {
	float:left;
	width:100%;
	height:50%;
	margin-top:-320px;
}
.outer {
	width:640px;
	height:640px;
	text-align:center;
	margin:auto;
	position:relative;
	clear:both;
	background:blue;
}
.button {
	position:absolute;
	bottom:-50px;
	left:0;
	width:640px;
	height:30px;
	line-height:30px;
	text-align:center;
	background:red;
}
</style>
</head>

<body>
<div class="spacer"></div>
<div class="outer">
		<h1>Ie6+</h1>
		<div class="button">Button content would be here</div>
</div>
</body>
</html>

You don’t want to use the top:50% and left:50% methods because you lose the content off the left of the viewport and off the top of the viewport at smaller viewport sizes. In my demos above the content always stops at the left and top edges.

Note: This second method is much shorter in code than my first demo but note that the techniques in the first demo (to some degree) will work with variable/unknown width and heights and will still work. The latter example is fine though for known width and heights.

Hi Paul,

Thank you for these suggestions. I should clarify: I am using an eLearning package which allows me to either add HTML or JavaScript code internally (after <BODY> or before </BODY>) and/or by adding a CSS page. So, while a beginner, limited in coding skills, I will need to figure out if I can find the correct place to add/substitute your suggested code (or even if they can be added?). Up to now, I’ve put the button and canvas JavaScript internally and the positioning in the external CSS.

I’ll experiment with the scripts you suggested, see if I can figure out how to substitute them. Currently, the above code (in the first posting) is working) and I’ve been trying to modify it so I can use it more broadly for additional elements.

My own parallel experimenting/modifying, before receiving you reply, looked like this in the CSS (doubt if it will work):

<div id="container">
<div id="canvas"></div>
<div id="button"></div>
#container{	
	position:relative;
  	top: 50%;
  	left: 50%;
  	margin-left:auto;
  	margin-top: -320px;
}
#canvas{
 	border:1px solid black;   
}
#button{ 
    width:150px;
}
</div>

You only need the code between the body tags of the example I gave you just like you have done with your own code. If you have inserted your own divs then you can just as easy insert the ones in my example :slight_smile:

Yes, don’t use the absolute position method in your example above because the layout will go out of the viewport at less than 640px witdh/height and be unreachable.

OK, I am trying it (IE8+ version). So far, The container is appearing, but on screen left, whereas I need it centered.

I also am using a canvas element which has a JS for animation. It needs to be centered inside the equally centered (in window) container. Can the container include the canvas element in it?

Let me see what I can do.

Just put your canvas element inside .content and it should work.

Do you have a link to a live version?

Wish I could export a viable sample. Just this morning updated with a slightly new version of the eLearning package, and my export which I would have uploaded is not running correctly. But my preview mode is working, so I can still view on my desktop, just can’t yet upload a working version. Apologies.

As to including canvas in content. Not sure how to accomplish this. When I tried the following, got a blank screen:

.content.canvas {
	width:640px;
	height:640px;
	margin:auto;
	position:relative;
	background:white;
}

I meant:


<div class="content>
  <div id="canvas">

 </div>
</div>

There was no need to change the css (assuming #canvas was 640x640).

Hi Paul,

Thank you for your continued help. I can’t get that code to work.

Maybe I can downgrade the eLearning package, export last working version (with my code-see above-not the new code). Then provide a link.

writer1

After checking further, the problem is not with the upgraded eLearning package. While I had previewed what I thought was a working version, apparently the code would not successfully work when exported. So, at this point, I have a basic animation that runs when the page is entered, that centers with the help of some CSS, but no easy way to add a button (to use to start it). Because of the CSS (see first entry above, just the canvas element), if I add a button separate from both the canvas and that new button being placed in a centered (in window) container, the button is difficult to position at a few px below the bottom center of the canvas.

//CSS

canvas{
    border:1px solid black;
	position: absolute;
  	top: 50%;
  	left: 50%;
  	margin-left: -320px;
  	margin-top: -320px;
}

The link to see the animation minus any buttons is: http://elearningprojects.com/dvn/index.html

Not sure what to try?

Much thanks.

writer1

Hi,

You lost me :slight_smile:

I don’t understand what that page is and what all those scripts are for and why the code is a mixture of very old and very new code wrapped in a page without doctype that will struggle to work anywhere. If you don’t have a doctyoe then all versions of ie9 and under behave like ie5 and 99% of your css will go un-noticed.

I’ve isolated the canvas script an inserted into a working example. Just run the following code to see it all works as I said it would above.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
body{background:#000}
html, body {
	height:100%;
	margin:0;
	padding:0;
}
h1 { margin:0 }
.spacer {
	float:left;
	width:100%;
	height:50%;
	margin-top:-320px;
}
.outer {
	width:640px;
	height:640px;
	text-align:center;
	margin:auto;
	position:relative;
	clear:both;
	background:blue;
}
.button {
	position:absolute;
	bottom:-50px;
	left:0;
	width:640px;
	height:30px;
	line-height:30px;
	text-align:center;
	background:red;
}
</style>
</head>

<body>
<div class="spacer"></div>
<div class="outer">
		<canvas width="640" height="640"></canvas>
		<div class="button">Button content would be here</div>
</div>
<script>
(function () {    'use strict';
    var canvas;
    var ldc;
    var gg1;
    var rdc;
    var px = [];
    var timer;
    var itsNoisy;
    function randomInt(range) {        return Math.random() * range | 0;
    }
    function flipSomePixels(howMany) {        var area = px.width * px.height,
            i,
            j,
            pxidx;
        for (i = 0; i < howMany; i += 1) {            pxidx = randomInt(area);
            for (j = 0; j < 3; j += 1) {                px.data[pxidx * 4 + j] = !px.data[pxidx * 4 + j] ? 255 : 0;
            }
        }
    }
 
    function onTick() {        flipSomePixels(gg1.width * 2);
        rdc.putImageData(px, 0, 0);
        drawAtScale(gg1, canvas);
    }
    function manageNoise() {        if(itsNoisy) {            clearInterval(timer);
        } else {            timer = setInterval(onTick, 50);
        }
        itsNoisy = !itsNoisy;
    }
    function initNoise() {        var width = gg1.width,
            height = gg1.height,
            i,
            val;
        for (i = 0; i < width * height; i += 1) {            val = randomInt(2) ? 255 : 0;
            rdc.fillStyle = "rgb(" + val + ", " + val + ", " + val + ")";
            rdc.fillRect(i % width, (i / height | 0), 1, 1);
        }
        px = rdc.getImageData(0, 0, gg1.width, gg1.height);
    }
    function init() {        gg1 = document.createElement('canvas');
        gg1.width = 80;
        gg1.height = 80;
        rdc = gg1.getContext("2d");
        canvas = document.querySelector("canvas");
        ldc = canvas.getContext("2d");
        itsNoisy = true;
        canvas.onclick = manageNoise;
        initNoise();
        timer = setInterval(onTick, 50);
    }
function drawAtScale() {        var width = gg1.width,
            height = gg1.height,
            xScale = canvas.width / width,
            yScale = canvas.height / height,
            i,
            pixelDataSize = width * height;
        for (i = 0; i < pixelDataSize; i += 1) {            ldc.fillStyle = "rgb(" + px.data[i * 4] + ", " + px.data[i * 4 + 1] + ", " + px.data[i * 4 + 2] + ")";
            ldc.fillRect((i % width) * xScale, (i / height | 0) * yScale, xScale, yScale);
        }
    }
    init();}());
</script>
</body>
</html>


Now your problem is to make the html look like mine but I’m afraid I can’t help with that as I don’t understand the methods you are using to create that page.:slight_smile:

Thank you once again, Paul.

BTW: not half as confused as me. :smiley:

Yes, when I place this into a Dreamweaver CS6 new HTML page, live preview: perfect. My problem is identified in your last sentence, about trying to get it into the eLearning package. For whatever reason, when I paste the same code into the code window, I get a different result. The red window and blue button are there. So, is a large white area above them, with a bunch of letters. So, I’ll have to go back to the proverbial “drawing boards” try to figure out the rules for adding more complex code. If all I add is the animation between <SCRIPT></SCRIPT> tags, it runs OK. CSS centers it. But without buttons to control the start, maybe pause/resume, plus a help button to summon some help info, won’t be a useful eLearning lesson and exercise.

I’ll keep at it. The canvas element plus JS is a very interesting and potentially useful item, able to run in many browsers.

Best Wishes,

writer1

lol :slight_smile:

At least you know that if you can get the html in the right order you will have some code that works.

I’m afraid I know nothing of the package you are using and I can guess that it is not a simple task. Obviously some CMSs only allow limited access to their packages in a controlled fashion so it may not be possible to add unlimited html.

Let us know if you find a solution.

Hi Paul,

The good news is that I learned a lot. The package BTW is excellent.

I’ll try some more. Maybe removing some extraneous tags that duplicate what is already added by the package could help get this running.

Again, thank you very much for your help.

Kind Regards,

writer1

I kept trying to get the code to work inside the eLearning lesson. While it previews OK (animation runs) from within the eLearning package preview feature, when I export and either view the export on the desktop or upload it to view, it will not run the animation.

I wonder if it would help if I separated the CSS out to an external CSS file (if I can figure out what CSS and how to separate it), and then include/call this external CSS file from the export. (The eLearning package does allow calling external CSS files. It may be less “forgiving” when CSS items are included within the internal scripting page ?) Worth a try to separate the CSS items to an external CSS file, leave the JavaScript and div tagged items inside.

Will try Tuesday. (:

writer1