I am quite new to HTML and am not very fluent in HMTL terminology (English as well :). I am trying to create presentation slide (something like Powerpoint in MS Office). The functionality should be:
Everything (text, pictures, etc.) inside the slide must stay in position, size and ratio relative to the slide while the slide resizes.
The slide has 4:3 resolution.
The slide should be realized by <div> element.
The slide stays in the middle of the screen.
No inline styles should have to be used inside the slide.
Plain Javascript, css and HTML must be used.
So far I have managed to devise this:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
<title>
Image Resize Test
</title>
<style type="text/css">
*
{
margin: 0;
}
body
{
background-color: black;
width: 100%;
height: 100%;
}
#wrapper
{
font-size:100%;
background-color: white;
display: block;
position: absolute;
left: 50%;
}
#content
{
font-family:"Times New Roman";
font-size:80%;
}
h1 {font-size:2.5em;}
h2 {font-size:1.875em;}
p {font-size:0.875em;}
</style>
<script>
window.onload = function()
{
window.onresize();
}
window.onresize = function()
{
var width = window.innerWidth;
var height = window.innerHeight;
if (width / 4 > height / 3)
{
width = height / 3 * 4;
}
else
{
height = width / 4 * 3;
}
var wrapper = document.getElementById("wrapper");
wrapper.style.height = height + "px";
wrapper.style.width = width + "px";
wrapper.style.marginLeft = (-width/2) + "px";
wrapper.style.fontSize = (height) + "%";
}
</script>
</head>
<body>
<div id="wrapper">
<div id="content">
<H1>
aaaa
</H1>
<H2>
bbbb
</H2>
<p>cccc</p>
text
</div>
</body>
</html>
Is this a good solution to my problem or are there simpler/more efficient/more robust or more "pro" ways to do this?
Could it be solved without the Javascript? Atleast partially.
Is there a way to easily specify x/y offset relative to the side for any element within the slide (perhaps as attribute)?
How to apply styles for elements that would be variably deep within the slide element tree?
Help on any of the things I ask would be appreciated.
this is basically same as yours but without explicitly setting margin in javascript. so remove that part and make margin: 0 auto; at wrapper.
http://jsfiddle.net/btevfik/VuqJX/
it seems like you can keep the aspect ratio with only css and html but as far as i can tell this only works when you resize width of the window. when you change height it wont work.
Maintain the aspect ratio of a div with CSS
Related
Requirements:
The HTML: The iframe HAS to be inside of a containing div. See code down below.
The CSS: The container should be able to have ANY valid width and height using the vw and vh viewport units. Se code down below.
Yes, the width and height HAS to be in vw and vh.
The static video preview image should NEVER be cropped.
The static video preview image should NOT have any black bars above and below (letterboxing).
The static video preview image should NOT have any black bars to the left or to the right (pillarboxing).
The static video preview image should use as much space estate as possible inside the div that contains it.
The static video preview image should ALWAYS keep its aspect ratio of 16:9.
Scrollbars should NEVER appear.
The static video preview image should be centered vertically as well as horizontally inside the div that contains it.
Responsive Web Design.
When resizing the browser or viewport all of the above requirements should be fulfilled.
HTML:
<div class="container">
<iframe></iframe>
</div>
CSS:
.container {
width:90vw;
height:50vh;
}
Same solution, but no extra markup for keeping the ratio.
JsFiddle with same comments totally not needed.
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">
<title>Fully Container Centred Iframe</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style>
.container {
display:table-cell; /* (specs: omitted table parts, the browser will insert mandatory elements in the dom tree) */
position:relative;
padding:; /* optional, margins ignored */
width:100vw; /* any value */
height:1vh; /* will expand by the :before element */
overflow:hidden; /* hide eventual black bars */
background:tan; /* bg-colors just for demo testing */
vertical-align:middle;
text-align:center;
}
.container:before {
display:block;
padding-top:56%; /* keeps the 16/9 ratio for the AP */
height:0;
background:red;
content:"\a0";
}
.container iframe {
position:absolute; /* to be ratio consistent */
top:-.5%;
left:-.5%; /* overflow eventual black bars */
border:0;
width:101%; /* grow some to avoid thinner black bars */
height:101%;
overflow:hidden; /* for html5 browsers the html attribute is depreciated */
background:gold;
}
</style>
</head><body>
<div class="container">
<iframe scrolling="no" src=""></iframe>
</div>
</body></html>
Using JavaScript, you can listen for the resize event, which fires whenever the browser's window changes shape. Then, with some simple algebra you can calculate the dimensions of the iframe based on the dimensions of the container. Here is a demo that shows all of the requirements.
"use strict";
var container = document.querySelector('.container');
var frame = container.querySelector('iframe');
function resizeVideo() {
frame.width = frame.height = 0;
var width = container.offsetWidth;
var height = container.offsetHeight;
if (height * (16 / 9) <= width) {
frame.height = height;
frame.width = height * (16 / 9);
} else {
frame.width = width;
frame.height = width * (9 / 16);
}
}
window.addEventListener('load', resizeVideo);
window.addEventListener('resize', resizeVideo);
.container {
width: 90vw;
height: 50vh;
display: table-cell;
text-align: center;
vertical-align: middle;
}
<div class="container">
<iframe src="https://www.youtube.com/embed/BKhZvubRYy8" frameborder="0" allowfullscreen></iframe>
</div>
if you want Responsive use
.container, iframe {
width:100%;
height:auto;
}
.container {
width:90vw;
height:50vh;
}
.container iframe {
width: 100%;
height: 100%;
}
Seems to work quite nicely in this fiddle https://jsfiddle.net/1q10L7hj/
why don't you just use the calc method to get the aspect ratio width you are wanting?
HTML
<div class="container">
<iframe src="" frameborder="0"></iframe>
</div>
SCSS
<style>
$width = 80vw;
.container {
width: $width;
height: calc(($width/16) * 9);
position: relative;
}
iframe {
position: absolute;
width: 100%;
height: 100%;
top: 50%;
left: 50%;
-webkit-transform: translate(+50%, -50%);
transform: translate(+50%, -50%);
}
</style>
then you can change the width of it anywhere and apply whatever positioning you want on the container div and the iframe with follow suit
I think the table-cell display could solve this. Just apply it on the container so the iframe is the content
According to specs the browser will insert dummy elements where it needs to render the cell correctly and fully centre and to contain its content and if it need, grow with it.
The requirements: I think some of them is beyond the scope of your question, they will also depend on what is loaded in the iframe, out of control of this container document. My suggested code is simple, but I believe it meets all requirements possible for the iframe parent and still be crossbrowser friendly.
The forbidden black bars and the mandatory aspect ratio could still be at fault in the loaded document. If you can't control whats loaded, the last option might be the "srcdoc" and "seamless" attributes, but that would exclude e.g. all IE versions.
JsFiddle with some comments totally not needed. Hope the edit below solves the case.
Anyway, I had fun! Thanks! :)
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">
<title>Fully Container Centred Iframe</title>
<meta name="generator" content="PSPad editor, www.pspad.com">
<style>
.container {
display:table-cell;
padding:;
width:100vw;
height:20vh;
background:tan;
vertical-align:middle;
text-align:center;
}
.container .ratio{
display:inline-block;
position:relative;
padding-bottom:56%;
width:100%;
height:0;
overflow:hidden;
vertical-align:middle;
}
.container iframe {
position:absolute;
top:-1%;
left:-1%;
border:0;
width:102%;
height:102%;
overflow:hidden;
vertical-align:middle;
}
</style>
</head><body>
<div class="container">
<div class="ratio">
<iframe scrolling="no" src=""></iframe>
</div>
</div>
</body></html>
I have gotten the result you wanted, I however had to add an extra div as the parent of the .container class. This JSFiddle should work for users on chrome (Windows desktop version) however when I tried to use the same fiddle on Edge and IE11 I found that it would create the undesired letter-box effect due to the image cover zooming too far out.
HTML
<div id="wrapper">
<div class="container">
<iframe scrolling="no" src="https://www.youtube.com/embed/YL9RetC0ook" frameborder="0" allowfullscreen>
</iframe>
</div>
</div>
CSS
body {
margin: 0;
}
#wrapper {
width: 90vw;
height: 50vh;
}
.container,iframe {
width: 100%;
height: 100%;
}
I am not sure if this works for Firefox, so perhaps if you have Firefox you can try it on my JSFiddle. However for Chrome (at the very least) this should be the solution you where looking for as stated by the requirements you listed.
I would recommend using a JavaScript window.resize listener to solve this kind of an issue. Cannot write code today cause I have a pretty tight schedule, but I'll try writing an algo:
On window resize, compute window width (wW) and window height (wH);
Determine container width (cW) as per wW (say cW = wW-10 to get almost all the width available - you can omit the -10 if you want);
Determine container height (cH) as per cW computed above: cH = cW * 9 / 16;
Now, if cH > wH (i.e. the container is not fitting into the screen vertically because it is too wide), we should revise cW as per available window height. In this case, cH = wH-10 (to get almost all the vertical space available - again, you can omit the -10 if you want) and then cW = wH * 16 / 9;
You should have a valid cW and cH now to make you container fit into the window without going out of the screen and you can apply it to the container.
To center the container to the screen, use position: absolute, left: 50%; top: 50%; in your CSS. When you update the cW and cH, also update margin-left: -(cW/2); margin-top: -(cH/2);
This is the concept - you can improvise as per your needs. I hope it helps.
(I'm a refugee from the Flex/Actionscript world and am trying to make the switch to html5/css3/JS. If this question is a duplicate or too dumb, let me know and I will delete it)
The Exercise: make an "app" with a "clickable" image background which creates new elements on a click event (and not using canvas);
I've got a functioning result – it just adds an empty colored div on click – but it seems like I am working way too hard – concatenating and converting to strings, reaching into the css style, etc. I'm also not clear how I would go about:
adding some Javascript behaviors to the newly created elements (so that it would be possible, for example, to drag these elements). I tried adding an eventListener to the newly created element but the blockClicked function never gets called;
trapping clicks on newly created elements so they don't pass through to the background, causing new items to get stacked on top of each other
creating an instance of something more complex than an empty div - like an html "component" – with an image, label, etc. without having to build an html string in JS.
Is there a better or cleaner way to do this sort of thing? I've been looking at various JS frameworks but didn't want to jump into something abstract before I understood some of the basics (and the problems these frameworks solve).
JS
"use strict";
var counter = 0;
var levelImg;
var eventContainer;
function setupBackground() {
eventContainer = document.getElementById("event-container");
levelImg = document.getElementById("levelImage");
levelImg.addEventListener("click", addEventItem);
};
function blockClicked(event){
console.log("blockClicked");
}
function addEventItem(event) {
console.log("create one");
var rectArray = levelImg.getClientRects();
var rect = rectArray[0];
var w = 40;
var h = 80;
// define x/y relative to edge of background image
// and offset position so div appears centered at mouse click
var xPos = (event.pageX - rect.left) - (w/2);
var yPos = (event.pageY - rect.top) -(h/2);
var divTmp = document.createElement("div");
divTmp.className = "levelEvent";
divTmp.id = "event" + counter++;
divTmp.addEventListener("click", blockClicked, false);
divTmp.style.width = w + 'px';
divTmp.style.height = h + 'px';
divTmp.style.left = xPos + 'px';
divTmp.style.top = yPos + 'px';
eventContainer.appendChild(divTmp);
}
CSS
.levelEvent {
position: absolute;
border: 1px solid green;
background-color: palegreen;
display:block;
width: 100px;
height: 100px;
max-width: 120;
max-height: 120;
}
#content-container{
position: relative;
border: 1px solid red;
max-width: 1024px;
margin: 0 auto;
}
#event-container{
position: absolute;
left: 0;
top: 0;
border: 4px solid blue;
width: 100%;
height: 100%;
margin: 0 auto;
pointer-events:none;
}
HTML
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>B</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body onload="setupBackground()">
<script src="js/clickToAdd.js"></script>
<div id="content-container">
<img id="levelImage" src="images/image3.png" width="100%" />
<div id="event-container">
</div>
</div>
</body>
</html>
You're definitely not doing it wrong, although I found 2 issues:
max-width: 120 is ignored because px is missing
I bet that the following part of your code is intended to work differently. I think, when you scroll down, the green rectangles should still appear under the cursor when clicking: (I tried it out in this jsfiddle)
var xPos = event.pageX - rect.left;
var yPos = event.pageY - rect.top;
My suggestion:
var xPos = event.pageX;
var yPos = event.pageY;
I have a div, an image(arrow.gif), another image(Untitled-1.jpg), two textboxes and a button.
I want to move the arrow.gif within a scrollable div with an image inside.
But i'm having a trouble creating the div into a scrollable one (making the Untitled-1.jpg fill the div) and moving the arrow.gif based on the Untitled-1.jpg's coordinates. Can anyone help me with this? Any help/assistance will be greatly appreciated .
<!DOCTYPE html>
<html>
<head>
<title>Move to Click Position</title>
<style type="text/css">
body {
background-color: #FFF;
margin: 30px;
margin-top: 10px;
}
#contentContainer {
border: 5px black solid;
background-color: #F2F2F2;
cursor: pointer;
background-image:url('Untitled-1.jpg');
background-repeat: no-repeat;
background-size: fixed;
width:1030px;
height:912px
}
#thing {
position: relative;
left: 50px;
top: 50px;
height: 68px;
width: 41px;
transition: left .5s ease-in, top .5s ease-in;
z-index: 10000;
}
</style>
</head>
<body>
<div id="contentContainer">
<img id="thing" src="arrow.gif" >
</div>
<form method="post" action="">
<input type="button" value="submit" name="submit" onclick="getClickPosition()">
<input type="text" id="valuex" name="valuex">
<input type="text" id="valuey" name="valuey">
</form>
<script src="prefixes.min.js"></script>
<script>
function getClickPosition() {
var theThing = document.querySelector("#thing");
var container = document.querySelector("#contentContainer");
var x1 = document.getElementById('valuex').value;
var y1 = document.getElementById('valuey').value;
var parentPosition = getPosition(x1.currentTarget);
var parentPosition = getPosition(y1.currentTarget);
var xPosition = x1 - parentPosition.x - (theThing.clientWidth / 2);
var yPosition = y1- parentPosition.y - (theThing.clientHeight / 2);
theThing.style.left = xPosition + "px";
theThing.style.top = yPosition + "px";
}
function getPosition(element) {
var xPosition = 0;
var yPosition = 0;
while (element) {
xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
</script>
</body>
</html>
First things I'm noticing is that you have:
background-size: fixed;
Fixed isn't an option for the background-size property.
You also have:
height:912px
Which is missing a semicolon, and will break your stylesheet further on.
1) Full-size background
If you want your 'Untitled-1.jpg' image to fill the frame you could set background-size to either cover or contain.
2) Scrollable div
In order to change your div into a scrollable one you can do so as follows:
#div{
width:1030px;
height:912px;
overflow: auto;
}
Overflow auto will add horizontal and vertical scrollbars to the div in the event that it extends outside its bounds. Or can use scroll if you want scrollbars to always be visible on the div.
You could also use overflow-x and overflow-y to specify which orientation you want scrollbars to appear.
3) Moving the thing
You're on the right track setting the position of the thing, there's a bit of fiddly stuff involved though to get it all functioning. See my Fiddle.
Demo
I've modified your code a fair bit, but in this fiddle you can change the position of the thing within the scrollable div, using the coordinate boxes.
https://jsfiddle.net/8y0qhdwx/
I'm not sure where you are heading with this, but it would be worth looking into the HTML5 canvas element, as it's built to handle the positioning of objects within it.
Hope this helps.
I am trying to create a simple slide show of an image that is set up in and background div. I dont have problem with creating the slideshow code but i have problem with positioning the image that should change according to the the width of others monitors resolution.
In the image bellow i described were i want to place the image. The image should be placed in the red div.
Here is the image that i want to put in the red div to be like a background. The resolution is (1900px x 500px)
Here is a model what i managed to do. I tried in java script code to declared a global variable sw which I assigned the window.innerWidth (sw=window.innerWidth), after in CSS using jquery selecting the red div $('#rotator') and assigned the sw ($('#rotator').css('width', sw)), but the result wasn't what I need to obtain. I obtained the image that was cropped from the right according to the screen resolution.
If someone know how to solve this question i will be greatful!
Here is my CODES:
HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="jquery-2.1.0.js"></script>
<script type="text/javascript" src="function.js"></script>
<script src="jquery.easing.1.3.js"></script>
</head>
<body >
<div id="rotator"></div>
<div class='slider'></div>
</body>
</html>
CSS
body{
margin: 0px;
margin-left: 0px;
}
.slider{
width: 940px;
height: 360px;
background-color: #FFDF00;
margin: 0 auto;
position: absolute;
left: 15%;
top: 20px;
}
#rotator {
position: relative;
height: 500px;
}
.puzzle {
width: 100px;
height: 100px;
background-position: -100px 0px;
float: left;
}
And JavaScript that also contain the function of slideshow effect (that is working).
$(document).ready(init)
sw=window.innerWidth;
if (sw % 100 == 0) {
sw=window.innerWidth
}
else{
sw=Math.floor(sw/100)*100
}
//counter of slider
current_slide=0;
image_list=new Array
(
"img/1.jpg",
"img/2.jpg",
"img/3.jpg",
"img/4.jpg",
"img/5.jpg"
);
function init ()
{
$('#rotator').css('width', sw)
change(image_list[current_slide]);
//start timer
setInterval( "change(image_list[current_slide])" ,2500);
}
function change(bg_image){
// this function creats cells inside <div id = 'rotator'>
rot = $('#rotator'); //constructor
rot.empty();
for(y = 1; y<=5; y++)
{
for(x = 1; x<=sw/100; x++)
{
rot.append('<div class = "puzzle p-' + x + '-' + y + ' "></div>');
//select the <div> using his class and setting up the cells coordinates
$('.p-' + x + '-' + y).css('background-position', (-(x-1)*100) + 'px ' + (- (y-1)*100) + 'px').css('background-image','url('+bg_image+')');
$('.p-' + x + '-' + y).css('opacity', 0).delay(parseInt(Math.random()*1000)).animate({opacity: 1}, {duration: 1000})
}
}
current_slide++;
if(current_slide >= image_list.length)current_slide=0
}
Thank you for your time and consideration!
You either have to put the image into a container div who's width is dynamic to the size of the page and set width of the image inside it to 100%, or use the CSS attribute background-size: cover; (which is only compatible with newer browsers).
Images set as the background image for a div will simply fill their container and be clipped by that container as it shrinks past the dimensions of the background image unless background-size: cover; is used. To gain the same effect in older browsers, the aforementioned 100% trick is used.
Cross-browser style:
http://jsfiddle.net/2D5Vw/
New(ish)-School:
http://jsfiddle.net/HLf2Q/
I have centered (position: absolute; left: 50%; margin: -50px;) 100px width div (container).
It has absolutely positioned child div with overflow: hidden, its size is 100x2000 px (such height is for test purposes, as described below).
There is an image in child div, it is absolutely positioned.
The image is 3100x100 px, it contains frames of animation.
I am animating this image by changing its style.left from 0 to -1100px, step is 100px.
Everything is fine, but I encounter weird issue when body width is not even.
It can happen if there is scrollbar and the scrollbar has odd width (it happens for me on Chrome/Win32 for example).
In this case image visually shifts by 1 pixel horizontally as soon as animated image goes through screen edge (for 1920x1080 it happens roughly at 9-10 frame of animation).
I can't find workaround for this behavior.
Working example reproducing the problem can be found here
Child div height is set to 2000px to make sure scrollbar is visible.
If your scrollbar has even width, you can reproduce the problem by resizing your browser window to odd width.
That happens because of the browsers rounding engines. Webkit apparently has some problems with 50% on even and odd widths.
One way to overcome the issue - re-position the .outer element based on window width
document.getElementById( 'outer' ).style.left = Math.floor( window.innerWidth / 2 ) + 'px';
DEMO
You need to change .inner img position to relative and update your javascript. I made changes for you, so here is your solved code:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style>
body {
background-color: #000000;
}
.outer {
position: absolute;
left: 50%;
margin-left: -50px;
}
.inner {
position: absolute;
width: 100px;
height: 2000px;
overflow: hidden;
}
.inner img {
position: relative;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
<img src="http://lorgame.ru/test.png" id="img">
</div>
</div>
<script language="JavaScript">
var framesCount = 30;
var framesCurrent = 0;
var framesMoveLeft = true;
var img = document.getElementById('img');
var interval = setInterval(function() {
if(framesMoveLeft == true){
framesCurrent++;
img.style.left = (img.offsetLeft - 100) + 'px';
if(framesCurrent == framesCount) framesMoveLeft = false;
} else { // Move right
framesCurrent--;
img.style.left = (img.offsetLeft + 100) + 'px';
if(framesCurrent == 0) framesMoveLeft = true;
}
}, 100);
</script>
</body>
</html>
To me this seems like a bug in Chrome. When percentages are defined in integers, they behave rather unexpectedly. Try to define the position as a decimal instead:
.outer {
position: absolute;
left: 49.99999%;
margin-left: -50px;
}
I tested this on the fiddle and it seems to do the trick.