Iframe 100% height inside body with padding - html

I have an iframe in my HTML document and I'm having a bit of trouble.
I also have a URL bar (fixed position element) at the top of the page that should stay with the user as they scroll. That works fine. I'd like the iframe to fill the remaining space but not be covered up by the URL bar.
This is what I'm talking about. http://s75582.gridserver.com/Ls
How can I fix this so that the URL bar doesn't cover up part of the page? When I try setting padding in the body, it just creates an extra, annoying scroll bar.

Whilst you can't say ‘height: 100% minus some pixels’ in CSS, you can make the iframe 100% high, then push its top down using padding. Then you can take advantage of the CSS3 box-sizing property to make the padding get subtracted from the height.
This:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html><head>
<title>test</title>
<style type="text/css">
html, body { margin: 0; padding: 0; height: 100%; }
#bar { height: 32px; background: red; }
iframe {
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
border: none; padding-top: 32px;
box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;
}
</style>
</head><body>
<iframe src="http://www.google.com/"></iframe>
<div id="bar">foo</div>
<body></html>
Works on IE8, Moz, Op, Saf, Chrome. You'd have to carry on using a JavaScript fallback to make the extra scrollbar disappear for browsers that don't support box-sizing though (in particular IE up to 7).

It can be done without any Javascript, works in IE7
CSS:
body {
overflow-y: hidden;
}
#imagepgframe {
width: 100%;
height: 100%;
position: absolute;
}
#wrap {
width: 100%;
position: absolute;
top: 100px;
left: 0;
bottom: 0;
}
HTML:
<div id="wrap">
<iframe id="imagepgframe" frameBorder="0" src="http://en.wikipedia.org/wiki/Internet_Explorer_7"></iframe>
</div>

To build on top of bobince's answer:
Erik Arvidsson came up with a way to (kinda, sorta) add box-sizing support to IE6/IE7. However, his solution doesn't support units other than px. Like you, I needed a percentage height, so I added support for percents.
Once you've downloaded and unzipped the zip file, open boxsizing.htc and replace the following border/padding functions:
/* border width getters */
function getBorderWidth(el, sSide) {
if (el.currentStyle["border" + sSide + "Style"] == "none")
return 0;
var n = parseInt(el.currentStyle["border" + sSide + "Width"]);
return n || 0;
}
function getBorderLeftWidth() { return getBorderWidth((arguments.length > 0 ? arguments[0] : element), "Left"); }
function getBorderRightWidth() { return getBorderWidth((arguments.length > 0 ? arguments[0] : element), "Right"); }
function getBorderTopWidth() { return getBorderWidth((arguments.length > 0 ? arguments[0] : element), "Top"); }
function getBorderBottomWidth() { return getBorderWidth((arguments.length > 0 ? arguments[0] : element), "Bottom"); }
/* end border width getters */
/* padding getters */
function getPadding(el, sSide) {
var n = parseInt(el.currentStyle["padding" + sSide]);
return n || 0;
}
function getPaddingLeft() { return getPadding((arguments.length > 0 ? arguments[0] : element), "Left"); }
function getPaddingRight() { return getPadding((arguments.length > 0 ? arguments[0] : element), "Right"); }
function getPaddingTop() { return getPadding((arguments.length > 0 ? arguments[0] : element), "Top"); }
function getPaddingBottom() { return getPadding((arguments.length > 0 ? arguments[0] : element), "Bottom"); }
/* end padding getters */
Then replace updateBorderBoxWidth and updateBorderBoxHeight with the following:
function updateBorderBoxWidth() {
element.runtimeStyle.width = "";
if (getDocumentBoxSizing() == getBoxSizing())
return;
var csw = element.currentStyle.width;
var w = null;
if (csw != "auto" && csw.indexOf("px") != -1) {
w = parseInt(csw);
} else if (csw != "auto" && csw.indexOf("%") != -1) {
var origDisplay = element.runtimeStyle.display;
element.runtimeStyle.display = "none";
w = Math.max(0, (parseInt(element.parentNode.clientWidth) - (
getBorderLeftWidth(element.parentNode)
+ getPaddingLeft(element.parentNode)
+ getPaddingRight(element.parentNode)
+ getBorderRightWidth(element.parentNode)
)) * (parseInt(csw) / 100));
element.runtimeStyle.display = origDisplay;
}
if (w !== null) {
if (getBoxSizing() == "border-box") {
setBorderBoxWidth(w);
} else {
setContentBoxWidth(w);
}
}
}
function updateBorderBoxHeight() {
element.runtimeStyle.height = "";
if (getDocumentBoxSizing() == getBoxSizing())
return;
var csh = element.currentStyle.height;
var h = null;
if (csh != "auto" && csh.indexOf("px") != -1) {
h = parseInt(csh);
} else if (csh != "auto" && csh.indexOf("%") != -1) {
var origDisplay = element.runtimeStyle.display;
element.runtimeStyle.display = "none";
h = Math.max(0, (parseInt(element.parentNode.clientHeight) - (
getBorderTopWidth(element.parentNode)
+ getPaddingTop(element.parentNode)
+ getPaddingBottom(element.parentNode)
+ getBorderBottomWidth(element.parentNode)
)) * (parseInt(csh) / 100));
element.runtimeStyle.display = origDisplay;
}
if (h !== null) {
if (getBoxSizing() == "border-box") {
setBorderBoxHeight(h);
} else {
setContentBoxHeight(h);
}
}
}
Then just use the file as you would otherwise:
.border-box {
behavior: url("boxsizing.htc");
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
Here's a pretty thorough test I put together while developing my modifications:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>box-sizing: border-box;</title>
<style type="text/css">
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background: yellow;
}
body {
padding-top: 50px;
padding-bottom: 50px;
}
p {
margin: 0;
}
#header, #footer {
height: 50px;
position: absolute;
width: 100%;
overflow: hidden;
}
#header {
background: red;
top: 0;
}
#footer {
background: blue;
bottom: 0;
}
#content {
width: 100%;
height: 100%;
border: none;
margin: 0;
padding: 0;
background: black;
color: white;
overflow: auto;
position: relative;
padding-top: 40px;
padding-bottom: 40px;
}
#nested-header, #nested-footer {
position: absolute;
height: 40px;
width: 100%;
background: #CCC;
}
#nested-header {
top: 0;
}
#nested-footer {
bottom: 0;
}
#nested-content-wrap {
height: 100%;
}
#nested-floater {
height: 100%;
float: left;
width: 100px;
}
#nested-content {
height: 100%;
background: green;
color: black;
overflow: auto;
position: relative;
}
#inner-nest {
height: 100%;
position: relative;
}
#inner-head {
height: 30px;
width: 100%;
background: #AAA;
position: absolute;
top: 0;
}
#inner-content {
padding-top: 30px;
height: 100%;
overflow: auto;
}
.border-box {
behavior: url("boxsizing.htc");
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.content-box {
behavior: url("boxsizing.htc");
box-sizing: content-box;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
}
legend {
color: black;
}
form {
margin: 1em 0;
}
.wrap {
height: 100px;
background: #000;
overflow: hidden;
}
.test {
width: 100px;
height: 100%;
background: #AAA;
border-color: #EEE;
padding-left: 20px;
padding-top: 20px;
padding-bottom: 5px;
float: left;
}
.fill {
width: 100%;
height: 100%;
background: #CCC;
}
.gauge {
width: 99px;
background: white;
border-right: 1px solid green;
height: 100%;
float: left;
}
.notes {
background: #8FC561;
}
.clear {
clear: both;
}
/* 120px x 120px square; this will create a black 20px frame on the inside */
.boxtest-wrapper {
width: 100px;
height: 100px;
float: left;
background: black;
color: white;
margin: 1em;
padding: 20px;
}
#boxtest-4-container {
width: 100%;
height: 100%;
}
.boxtest {
width: 100%;
height: 100%;
background: white;
color: black;
border: 5px solid green;
overflow: hidden;
}
</style>
<script type="text/javascript">
function addBorderBox() {
var wrap1 = document.getElementById("wrap-1");
var wrap2 = document.getElementById("wrap-2");
var borderBox = document.createElement("div");
borderBox.className = "test border-box";
var borderBoxFill = document.createElement("div");
borderBoxFill.className = "fill";
var borderBoxContent = document.createTextNode("Generated border box fill");
borderBoxFill.appendChild(borderBoxContent);
borderBox.appendChild(borderBoxFill);
var gauge = document.createElement("div");
gauge.className = "gauge";
var gaugeText1 = "width: 100px";
var gaugeText2 = "height: 100%";
var gaugeText3 = "bottom should be visible";
gauge.appendChild(document.createTextNode(gaugeText1));
gauge.appendChild(document.createElement("br"));
gauge.appendChild(document.createTextNode(gaugeText2));
gauge.appendChild(document.createElement("br"));
gauge.appendChild(document.createTextNode(gaugeText3));
wrap1.appendChild(borderBox);
wrap2.appendChild(gauge);
}
</script>
</head>
<body id="body" class="border-box">
<div id="header">
<p>Header - 50px;</p>
</div>
<div id="content" class="border-box">
<div id="nested-header">
<p>Nested Header - 40px;</p>
</div>
<div id="nested-content-wrap">
<div id="nested-floater">
<p>Float - 100px;</p>
<ul>
<li>This element should never scroll.</li>
</ul>
</div>
<div id="nested-content">
<div id="inner-nest">
<div id="inner-head">
<p>Inner Head - 30px;</p>
</div>
<div id="inner-content" class="border-box">
<div style="float: right; ">
<p>The fourth square should look just like the other three:</p>
<div id="boxtest-wrapper-1" class="boxtest-wrapper">
<div id="boxtest-1" class="boxtest border-box"></div>
</div>
<div id="boxtest-wrapper-2" class="boxtest-wrapper">
<div id="boxtest-2" class="boxtest border-box"></div>
</div>
<br class="clear" />
<div id="boxtest-wrapper-3" class="boxtest-wrapper">
<div id="boxtest-3" class="boxtest border-box"></div>
</div>
<div id="boxtest-wrapper-4" class="boxtest-wrapper">
<div id="boxtest-4-container">
<!-- boxtest-4-container isn't special in any way. it just has width and height set to 100%. -->
<div id="boxtest-4" class="boxtest border-box"></div>
</div>
</div>
</div>
<p>Inner Content - fluid</p>
<ul>
<li>The top of the scrollbar should be covered by the “Inner Head” element.</li>
<li>The bottom of the scrollbar should be visible without having to scroll “Inner Head” out of view.</li>
</ul>
<p>Document Compat Mode:
<strong id="compatMode">
<script type="text/javascript">
var compatMode = document.compatMode;
if (compatMode != "CSS1Compat") {
document.getElementById("compatMode").style.color = "red";
}
document.write(compatMode);
</script>
</strong>
</p><br />
<div class="notes">
<h2>Notes</h2>
<ul>
<li>In IE6 and IE7 (and possibly IE8; untested), you'll notice a slight shift of contents that have <code>box-sizing</code> set to <code>border-box</code>. This is the amount of time it takes for box-sizing.htc to finish downloading.</li>
<li>This workaround is not live. Anything that causes a reflow or repaint will not currently trigger an update to widths and heights of <code>border-box</code> elements.</li>
<li>See http://webfx.eae.net/dhtml/boxsizing/boxsizing.html for the original solution to the IE6/IE7 <code>border-box</code> problem. box-sizing.htc has been modified to allow for percentage widths and heights.</li>
<li>To see what this example should look like without the use of box-sizing.htc, view it in Firefox or IE8.</li>
</ul>
</div>
<br class="clear" />
<form>
<fieldset>
<legend>DOM Update Test</legend>
<input type="button" value="Click to add border-box" onclick="addBorderBox(); " />
</fieldset>
</form>
<div id="wrap-1" class="wrap">
<div class="test content-box" id="content-box-1" style="border-width: 5px; border-style: solid;">
<div class="fill">Content box fill</div>
</div>
<div class="test content-box" id="content-box-2" style="border-width: 5px; border-style: solid; padding: 5px;">
<div class="fill">Content box fill</div>
</div>
<div class="test border-box" id="border-box-1" style="border-width: 5px; border-style: solid;">
<div class="fill">Border box fill</div>
</div>
<div class="test border-box" id="border-box-2" style="border-width: 5px; border-style: solid; padding: 5px;">
<div class="fill">Border box fill</div>
</div>
<div class="test" id="default-box-1" style="border-width: 5px; border-style: solid;">
<div class="fill">Default box fill</div>
</div>
<div class="test" id="default-box-2" style="border-width: 5px; border-style: solid; padding: 5px;">
<div class="fill">Default box fill</div>
</div>
</div>
<div id="wrap-2" class="wrap">
<!-- subtract 1 from width for 1px right border -->
<div class="gauge" style="width: 129px;">width: 130px<br />height: 100%<br />bottom should be cut off</div>
<div class="gauge" style="width: 119px;">width: 120px<br />height: 100%<br />bottom should be cut off</div>
<div class="gauge">width: 100px<br />height: 100%<br />bottom should be visible</div>
<div class="gauge">width: 100px<br />height: 100%<br />bottom should be visible</div>
<div class="gauge" style="width: 129px;">width: 130px<br />height: 100%<br />bottom should be cut off</div>
<div class="gauge" style="width: 119px;">width: 120px<br />height: 100%<br />bottom should be cut off</div>
</div>
<br class="clear" />
<script type="text/javascript">
var lipsum = "<p>Lorem ipsum dolor sit amet.</p>";
for (var i = 0; i < 100; i++) {
document.write(lipsum);
}
</script>
</div>
</div>
</div>
</div>
<div id="nested-footer">
<p>Nested Footer - 40px;</p>
</div>
</div>
<div id="footer">
<p>Footer - 50px;</p>
</div>
</body>
</html>

If by covering up part of the page, you mean the page displayed in the iframe, one thought might be to add a top margin to your iframe, using the margin-top: property in CSS. This would eliminate the scroll bar given that you properly constrained the height of the iframe.

Android Kotlin Answer
For example, I am using padding for iFrame of WebView in this way:
val url = "www.stackoverflow.com"
val iframeExample = "<html><body style=\"margin: 0; padding: 0\"><iframe width=\"100%\" src=\"$url\" frameborder=\"0\" allowfullscreen></iframe></body></html>"
webView.loadData(iframeExample, "text/html", "utf-8")

Related

Memory Game Cards Not Rotating Properly

I have been learning how to create a memory game and thought I was following the instructions carefully but I have run into a snag. In my html, I have a div for the card and two child divs to style the front and back of the card.
<div class="container">
<div id="memory_board">
<div class="card">
<div id="back0" class="cardFace cardFaceBack"></div>
<div id="front0" class="cardFace cardFaceFront" class="card"></div>
</div>
</div>
</div>
The number of cards for the memory game will vary.
When I run the code, they are stacked on top of each other meaning when you click on one card, the back flips over as expected but the front flips over underneath its original position. Here is my codepen. How can I adjust me code so that it looks like the card flips over properly?
=============== Edit ===================
Quick question, when I include a link to codepen, do I still have include all of the code?
The css for this game is:
* {
margin:0;
padding:0;
box-sizing:border-box;
}
div.container {
display: flex;
justify-content: center;
align-items: center;
vertical-align: middle;
}
div#memory_board{
background:#CCC;
border:#999 1px solid;
display: inline-block;
padding: 10px;
perspective: 1000px;
}
.card {
width:100px;
height:133px;
display: inline-block;
margin:0px;
padding:10px;
transition: transform 1s;
transform-style: preserve-3d;
transform-origin: center right;
cursor: pointer;
position: relative;
}
.card.is-flipped {
transform: translateX(-100%) rotateY(-180deg);
}
.cardFace {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.cardFaceFront {
position: inherit;
background: whitesmoke;
color: black;
font-weight: bold;
font-size: 40px;
border:#000 1px solid;
text-align:center;
vertical-align: middle;
transform: rotateY(180deg);
}
.cardFaceBack {
background: url("https://images.cdn2.stockunlimited.net/preview1300/playing-cards-
background_1608080.jpg"); no-repeat;
background-size: cover;
position: relative;
border:#000 1px solid;
}
In addition, the javascript for this program is:
var memory_array = ['A','A','B','B'];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
const memory_board = document.getElementById('memory_board');
let getRndInteger = (min, max) => Math.floor(Math.random() * (max - min) ) + min
// the following function randomly shuffles elements in an array using the Fisher-Yates (aka Knuth) shuffle
let shuffle = array => {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
function initiateCard () {
let card = document.querySelectorAll('.card');
card.forEach( card => card.addEventListener ( 'click', () => {
card.classList.toggle('is-flipped');
}));
}
function newBoard() {
let memoryArray = shuffle (memory_array);
for (let i = 0; i <= memoryArray.length - 1; i++) {
document.getElementById("front" + i).innerText = memory_array[i];
}
}
$( document ).ready(function() {
newBoard ();
initiateCard ();
});
When the game starts, the memory_array shuffles propery and each element is distributed to the cards. However, when you turn a card,
I thought I had followed the instructions but I do not understand why, when turned, the front face is below where the back was. What adjustments do I have to make, after turning the card, so the front of the card in the same place as the back of the card, not below it.
an animation or a gif will be of help to as what you want to achieve, from your comment in your code I could see you are trying to replicate this, but the way you structure your code doesn't seem to be as this
https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Okay, so a couple of things. I couldn't get your js to work. Getting this error "Uncaught TypeError: Cannot set properties of null (setting 'innerText')".
And with your CSS you need to position the front and back with position: absolute; otherwise, they affect each other. The back was pushing the front down the page.
And if you set transform-origin: center center; you don't need to do the additional transform: translateY(-100%);
var memory_array = ['A', 'A', 'B', 'B'];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
const memory_board = document.getElementById('memory_board');
let getRndInteger = (min, max) => Math.floor(Math.random() * (max - min)) + min
// the following function randomly shuffles elements in an array using the Fisher-Yates (aka Knuth) shuffle
let shuffle = array => {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
function initiateCard() {
let card = document.querySelectorAll('.card');
card.forEach(card => card.addEventListener('click', () => {
card.classList.toggle('is-flipped');
}));
}
function newBoard() {
let memoryArray = shuffle(memory_array);
for (let i = 0; i <= memoryArray.length - 1; i++) {
document.getElementById("front" + i).innerText = memory_array[i];
}
}
$(document).ready(function () {
newBoard();
initiateCard();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
div.container {
display: flex;
justify-content: center;
align-items: center;
vertical-align: middle;
}
div#memory_board {
background: #CCC;
border: #999 1px solid;
display: inline-block;
padding: 10px;
perspective: 1000px;
}
.card {
width: 100px;
height: 133px;
display: inline-block;
margin: 0px;
/* padding: 10px; */
transition: transform 1s;
transform-style: preserve-3d;
cursor: pointer;
position: relative;
transform-origin: center center;
}
.card.is-flipped {
transform: rotateY(180deg);
}
.cardFace {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.cardFaceFront {
position: absolute;
background: whitesmoke;
color: black;
font-weight: bold;
font-size: 40px;
border: #000 1px solid;
text-align: center;
vertical-align: middle;
transform: rotateY(180deg);
}
.cardFaceBack {
background: url("https://images.cdn2.stockunlimited.net/preview1300/playing-cards-background_1608080.jpg") no-repeat;
background-size: cover;
position: absolute;
border: #000 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="container">
<div id="memory_board">
<div class="card is-flipped">
<div id="back0" class="cardFace cardFaceBack"></div>
<div id="front0" class="cardFace cardFaceFront" class="card"></div>
</div>
<div class="card">
<div id="back0" class="cardFace cardFaceBack"></div>
<div id="front0" class="cardFace cardFaceFront" class="card"></div>
</div>
<div class="card">
<div id="back0" class="cardFace cardFaceBack"></div>
<div id="front0" class="cardFace cardFaceFront" class="card"></div>
</div>
<div class="card">
<div id="back0" class="cardFace cardFaceBack"></div>
<div id="front0" class="cardFace cardFaceFront" class="card"></div>
</div>
</div>
</div>

HTML `dialog` element: scroll content independently of background

I am trying to use the dialog element.
When the dialog/modal is closed, the body should be scrollable.
When the dialog/modal is open, if it has large contents, the dialog/modal should be scrollable.
However, when the dialog/modal is open, I don't want scroll to apply to both the dialog/modal and the body background, which is what it seems to do by default.
Example: https://output.jsbin.com/mutudop/3.
How can I make scroll apply only to the dialog/modal contents, when the dialog/modal is open?
Note: I am only interested in solutions using the native dialog element.
So I tried it as well and came up with this:
(function() {
var openBtn = document.querySelector("button#open");
var myDialog = document.querySelector("dialog");
openBtn.addEventListener('click', function() {
if (typeof myDialog.showModal === "function") {
myDialog.showModal();
document.querySelector("body").classList.add("overflow-hidden");
} else {
alert("Dialog API not supported by browser");
}
});
})();
* {
box-sizing: border-box;
}
.wrapper {
height: 10000px;
}
dialog {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
border: 0;
z-index: 100;
background: transparent;
overflow-y: auto;
}
dialog>div {
width: 50%;
height: 500px;
background: white;
border: 3px solid black;
margin: 0 auto;
margin-top: 50px;
}
.overflow-hidden {
overflow: hidden;
}
<div class="wrapper">
<dialog>
<div>
<form method="dialog">
<button onclick='document.body.classList.remove("overflow-hidden");' value="cancel">Cancel</button>
</form>
</div>
</dialog>
<button id="open">Open Dialog</button>
<h4>You can scroll the body now but not when the dialog is opened.</h4>
</div>
You might have noticed that I added two lines of JS to hide/show the overflow of the body and you will probably need them as you can't target the body with pure CSS if you want to check if the dialog is opened or not.
If you don't want them you can remove them and it just works fine. However, you will have two scroll bars on the right side. This is how it looks without the JS:
(function() {
var openBtn = document.querySelector("button#open");
var myDialog = document.querySelector("dialog");
openBtn.addEventListener('click', function() {
if (typeof myDialog.showModal === "function") {
myDialog.showModal();
} else {
alert("Dialog API not supported by browser");
}
});
})();
* {
box-sizing: border-box;
}
.wrapper {
height: 10000px;
}
dialog {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
border: 0;
z-index: 100;
background: transparent;
overflow-y: auto;
}
dialog>div {
width: 50%;
height: 500px;
background: white;
border: 3px solid black;
margin: 0 auto;
margin-top: 50px;
}
.overflow-hidden {
overflow: hidden;
}
<div class="wrapper">
<dialog>
<div>
<form method="dialog">
<button value="cancel">Cancel</button>
</form>
</div>
</dialog>
<button id="open">Open Dialog</button>
</div>
If you need any explanation let me know but I believe the code should be self-explanatory.
This answer takes the escape key into account. I add a keydown event listener to document.documentElement rather than the actual dialog elements. This is because when a dialog has a keydown event listener, it doesn't always fire. For example, if a dialog is open and a button inside of it has focus and you push the escape key, the keydown event listener will fire. But let's suppose that the dialog has some text in it and you highlight the text and then push the escape key. In this scenario, the keydown event listener will not fire.
const activeModals = [];
function openModal(dialogSelector) {
const dialog = document.querySelector(dialogSelector);
dialog.showModal();
activeModals.push(dialog);
document.body.classList.add('overflow-hidden');
}
function closeActiveModal() {
const activeModal = activeModals.pop();
activeModal.close();
if (activeModals.length === 0) {
document.body.classList.remove('overflow-hidden');
}
}
document.documentElement.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && activeModals.length) {
e.preventDefault();
closeActiveModal();
}
});
document.querySelectorAll('[data-toggle="modal"]').forEach((button) => {
button.addEventListener('click', () => {
openModal(button.getAttribute('data-target'));
});
});
document.querySelectorAll('[data-dismiss="modal"]').forEach((button) => {
button.addEventListener('click', closeActiveModal);
});
let fillerHtml = '';
for (let i = 1; i <= 100; i++) {
fillerHtml += `<p>${i}</p>`;
}
document.querySelectorAll('.filler').forEach((div) => {
div.innerHTML = fillerHtml;
});
.overflow-hidden {
overflow: hidden;
}
p {
font-size: 20px;
}
<button data-toggle="modal" data-target="#dialog1">Open Dialog 1</button>
<dialog id="dialog1">
<h1>Dialog 1</h1>
<button data-dismiss="modal">Close Dialog 1</button>
<button data-toggle="modal" data-target="#dialog2">Open Dialog 2</button>
<div class="filler"></div>
</dialog>
<dialog id="dialog2">
<h1>Dialog 2</h1>
<button data-dismiss="modal">Close Dialog 2</button>
</dialog>
<div class="filler"></div>
Update
I created another example where your main content is not scrolled with your modal if it is larger than your main content. You can set position to fixed on your container to achieve this.
(function() {
var openBtn = document.getElementById('open-dialog');
var myDialog = document.getElementById('my-dialog');
openBtn.addEventListener('click', function() {
if (typeof myDialog.showModal === "function") {
myDialog.showModal();
} else {
alert("Dialog API not supported by browser");
}
});
})();
#container {
height: 100vh;
width: 100vw;
position: fixed;
top: 0;
left: 0;
background: #ccc;
}
#my-dialog {
margin-top: 1rem;
margin-bottom: 3rem;
top: 3rem;
width: 50%;
overflow-y: auto;
}
#my-dialog__content {
display: flex;
flex-direction: column;
height: 200vh;
}
menu {
width: 100%;
padding: 0;
margin: 0 auto;
}
#cancel-button {
width: 100%
}
<div id="container">
<dialog id="my-dialog">
<div id="my-dialog__content">
<form method="dialog">
<menu>
<button id="cancel-button" value="cancel">Cancel</button>
</menu>
</form>
</div>
</dialog>
<menu>
<button id="open-dialog">Open Dialog</button>
</menu>
</div>
Original answer
You can set a max-height on your dialog and style the contents of your dialog accordingly. See example below.
(function() {
var openBtn = document.getElementById('open-dialog');
var myDialog = document.getElementById('my-dialog');
openBtn.addEventListener('click', function() {
if (typeof myDialog.showModal === "function") {
myDialog.showModal();
} else {
alert("Dialog API not supported by browser");
}
});
})();
#my-dialog {
width: 50%;
max-height: 50vh;
overflow-y: auto;
}
#my-dialog__content {
display: flex;
flex-direction: column;
height: 150vh;
}
menu {
width: 100%;
padding: 0;
margin: 0 auto;
}
#cancel-button {
width: 100%
}
<div id="container">
<dialog id="my-dialog">
<div id="my-dialog__content">
<form method="dialog">
<menu>
<button id="cancel-button" value="cancel">Cancel</button>
</menu>
</form>
</div>
</dialog>
<menu>
<button id="open-dialog">Open Dialog</button>
</menu>
</div>
Simple solution is : Once the mnodel is displayed make a one more DIV as overlay which covers full screen, in that place css { pointer-events:none} and model will be placed on top of that. user can not click on body content other than model data.
I have created sample: http://jsfiddle.net/z3sgvnox/
<body id="content-body">
<div id="container">
<dialog id="my-dialog">
<div id="my-dialog__content">
<form method="dialog">
<menu>
<button id="cancel-button" value="cancel">Cancel</button>
</menu>
</form>
</div>
</dialog>
<menu>
<button id="open-dialog">Open Dialog</button>
</menu>
</div>
</body>
CSS
#container {
height: 100vh;
width: 100vw;
position: fixed;
top: 0;
left: 0;
background: #ccc;
}
#my-dialog {
margin-top: 1rem;
margin-bottom: 3rem;
width: 50%;
overflow-y: auto;
max-height: 80%;
}
.hideScroll{
overflow:hidden;
pointer-events:none;
}
#my-dialog__content {
display: flex;
flex-direction: column;
height: 200vh;
}
menu {
width: 100%;
padding: 0;
margin: 0 auto;
}
#cancel-button {
width: 100%
}
JS:
(function() {
var openBtn = document.getElementById('open-dialog');
var myDialog = document.getElementById('my-dialog');
var bodyData = document.getElementById('content-body');
openBtn.addEventListener('click', function() {
if (typeof myDialog.showModal === "function") {
myDialog.showModal();
bodyData.classList.add("hideScroll");
} else {
alert("Dialog API not supported by browser");
}
});
})();

HTML element wont stay positioned at bottom

So I have a chat UI that is a box where messages go, and at the bottom of the box of messages is a text input element. It works fine at the beginning, but once enough messages appear then the text input element scrolls up, along with the messages, and will not stay positioned at the bottom. How can I do this? Any useful thoughts would be appreciated.
<html>
<body>
<div id="chatui">
<div id="chatmsgs"></div>
<input type="text" id="chatbox">
</div>
</body>
</html>
Here is my CSS:
#chatui {
z-index:3;
position:absolute;
bottom:5px;
width: 380px;
height: 150px;
border: 3px solid #8AC007;
margin-left:5px;
overflow:auto;
}
#chatbox {bottom:3px;position:absolute;width:378px;}
#chatmsgs {position:absolute;}
Here is my Javascript:
This just says when you press "Enter" on your keyboard to display the text you typed into the "chatmsgs" div.
$(window).keydown(function(e){
if (e.keyCode == 13) {
if (document.activeElement.id == 'chatbox') {
var msg = document.getElementById('chatbox').value;
document.getElementById('chatbox').value = '';
var ms = '<p>'+msg+'</p>';
$('#chatmsgs').append(ms);
}
}
});
Check out this fiddle to see what I am talking about:
https://jsfiddle.net/ev3uymw6/
You have to add overflow:auto and appropriate height to the chatmsgs div, so that it doesn't grow beyond the size of chatui and make it scroll alltogether.
$(window).keydown(function(e) {
if (e.keyCode == 13) {
if (document.activeElement.id == 'chatbox') {
var msg = document.getElementById('chatbox').value;
document.getElementById('chatbox').value = '';
var ms = '<p>' + msg + '</p>';
$('#chatmsgs').append(ms);
}
}
});
#chatui {
z-index: 3;
position: absolute;
bottom: 5px;
width: 380px;
height: 150px;
border: 3px solid #8AC007;
margin-left: 5px;
}
#chatbox {
bottom: 3px;
position: absolute;
width: 378px;
}
#chatmsgs {
position: absolute;
height: 130px;
overflow: auto;
width: 378px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="chatui">
<div id="chatmsgs">
</div>
<input type="text" id="chatbox">
</div>
</body>

WinJS.BackButton sizes

I have this html tag which reffers to the backButton provided by the WinJS library:
<button data-win-control="WinJS.UI.BackButton"></button>
I want to change its size. How can I do that? I tried using CSS by adding the ID "backButton" and font-size OR width/height properties, like this:
#backButton {
font-size: small;
}
#backButton {
height: 30px;
width: 30px;
}
EDIT: Code added and a picture of what happens when changing the values of width/height of the button.
// For an introduction to the Page Control template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232511
(function () {
"use strict";
WinJS.UI.Pages.define("/pages/anime/anime.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
// TODO: Initialize the page here.
this.renderAnimeInfo(Identifier.file);
},
unload: function () {
// TODO: Respond to navigations away from this page.
},
updateLayout: function (element) {
/// <param name="element" domElement="true" />
// TODO: Respond to changes in layout.
},
renderAnimeInfo: function (id) {
// Path for the anime data.
var path = "data/animes.json";
// Retrieve the .json.
WinJS.xhr({ url: path }).then(
function (response) {
var json = JSON.parse(response.responseText);
for (var i = 0; i < json.length; i++) {
if (json[i].file == id) {
var animeData = json[i];
break;
}
}
},
function (error) {},
function (progress) {}
);
},
});
})();
.right {
float: right;
}
.left {
float: left;
}
.active {
background-color: blue;
}
#animeDetails {
background: red;
height: 100%;
width: 300px;
float: left;
}
#animeInfo {
display: -ms-grid;
height: 100%;
width: calc(100% - 300px);
float: right;
}
#navbar {
-ms-grid-row: 1;
padding: 20px 25px;
}
#navbar .right button {
margin-right: 4px;
}
#navbar input {
width: 150px;
}
#details {
-ms-grid-row: 2;
padding: 0 25px;
text-align: justify;
white-space: pre-line;
}
#details h3 {
width: 100%;
padding: 5px 0;
border-bottom: 1px solid #bebebe;
margin-bottom: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>anime</title>
<link href="anime.css" rel="stylesheet" />
<script src="anime.js"></script>
</head>
<body>
<div id="animeDetails"></div>
<div id="animeInfo">
<div id="navbar">
<div class="left">
<button class="left" data-win-control="WinJS.UI.BackButton"></button>
<h3>Back</h3>
</div>
<div class="right">
<button type="button" class="active">Details</button>
<button type="button">Episodes</button>
<button type="button">Characters</button>
<button type="button">Staff</button>
<input type="search" placeholder="Search" />
</div>
</div>
<div id="details">
<div id="synopsis">
<h3>Synopsis</h3>
<span>
</span>
</div>
</div>
</div>
</body>
When using the width/height properties, what happens is that the button does resize to the specified value, but the icon inside (which is not a background) doesn't. http://i.imgur.com/lMqmL0G.png
Possibly you have to set display: inline-block to button because the width of an element with display: inline (the default for buttons) is exactly the same as its content because it only takes up the space needed to display its contents so try with:
With id selector
#backButton {
height: 30px;
width: 30px;
display: inline-block;
}
<button id="backButton" data-win-control="WinJS.UI.BackButton"></button>
With style inline
<button data-win-control="WinJS.UI.BackButton" style="width: 30px; height: 30px; display: inline-block"></button>
Try to set the styles to child element .win-back
#backButton .win-back{
/*---styles---*/
}
You haven't given your button an ID. The CSS does not know what tag to link to.
<button id="backButton" data-win-control="WinJS.UI.BackButton"></button>
edit: you may find the following reference useful CSS Selectors

How to pass parametrs to DIV section

I want to design the dialog in html5. This dialog should accept the freetext and image as parameters. I tried to open dialog as below.. Now I want to pass the parameters so that I can use that dialog everywhere..
<!DOCTYPE html>
<html>
<head>
<style>
#overlay
{
visibility: hidden;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
text-align: center;
z-index: 200;
background-image: url(maskBG.png);
}
#overlay div
{
width: 300px;
margin: 100px auto;
background-color: #fff;
border: 1px solid #400;
padding: 15px;
text-align: center;
}
.close
{
text-decoration: underline;
}
</style>
<script>
function overlay() {
var el = document.getElementById("overlay");
el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible";
}
function overlayTest(arg) {
//alert(arg);
var el = document.getElementById("overlay").click(moveImages('Testing123'));
//alert(arg);
// el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible";
}
function close() {
document.getElementById("overlay").style.visibility = 'hidden';
}
function moveImages(arg) {
alert('in Move Images');
}
</script>
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<p align="center">
<button type="button" onclick="overlay()" id="btnEffluentTreatment">EFFLUENT TREATMENT</button>
<button type="button" onclick="overlayTest('My MyTesting')" id="btnTry">Try1</button>
</p>
<div id="overlay" >
<div>
<p>
<img src="010.png" />
Content/Images whatever we want the user to see goes here.
</p>
<button type="button" onclick="overlay()" id="btnEffluentTreatment">Close</button>
</div>
</div>
</body>
</html>