I am attempting to create a horizontal scroll of a ul populated by an ajax call to an xml document. As constituted, the content will scroll but the list items are stacked rather than side by side. Research suggests that I can achieve the desired result with some simple css. However, I have been unable to successfully make this happen...
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Content-Script-Type" content="text/javascript">
<meta name="Content-Style-Type" content="text/css">
<link href="css/wneRSS.css" rel="stylesheet">
<script src="js/jquery.min.js"></script>
</head>
<body>
<div id="rss">
<div class="list"><ul class="feeder"></ul></div>
</div>
</body>
<script>
$(document).ready(function(){
$.ajax({
type: "GET",
url: "XMLSource",
dataType: "xml",
success: function(xml){
$(xml).find('row').each(function(){
var sfirst = $(this).find('First').text();
var slast = $(this).find('Last').text();
var scity = $(this).find('PermanentCity').text();
var sstate = $(this).find('PermanentRegion').text();
$("<li></li>").html(sfirst + " " + slast + " - " + scity + ", " + sstate).appendTo("#rss ul");
});
},
error: function() {
alert("An error occurred while processing XML file.");
}
});
});
</script>
</html>
CSS:
body {
margin: 0;
padding: 0;
background-color: #373737;
color: white;
font-family: sans-serif;
overflow: hidden;
}
#rss {
width: 1920px;
height: 82px;
margin:0px;
}
.list ul {
padding: 0;
margin: 0;
border: 0;
float: left;
display: inline;
width: auto;
}
.list ul li {
float: left;
margin: 0;
padding: 0;
border: 0;
display: inline;
}
.feeder {
font-size: 40px;
line-height: 82px;
-moz-transform:translateX(100%);
-webkit-transform:translateX(100%);
transform:translateX(100%);
animation: scroller 60s linear infinite;
}
#keyframes scroller {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
Added width=auto to the container solved the problem.
Your container may not be wide enough to accommodate your list items. You need to nest the unordered list elements in a container wide enough that they do not break.
I have a few controls that I am attempting to encapsulate on my webpage. I have tried a few different methods on encapsulating my controls and they have not succeeded. I tried using a div and this did not work too well and I have also tried this post:
Create a group box around certain controls on a web form using CSS
What is happening is that a box is being created but it is at the top of my webpage instead of around the controls.
I would like to create a grey box similar to the ones found on this webpage:
https://img.labnol.org/di/trigger1.png
Below, I am attaching a copy of the CSS and HTML code that I am using in order to create my form. The form is a simple file upload form that I tweaked from an example. I am using this on my own, personal website.
Here is the HTML:
<!DOCTYPE html>
<html>
<head>
<script>
/* Script written by Adam Khoury # DevelopPHP.com */
/* Video Tutorial: http://www.youtube.com/watch?v=EraNFJiY0Eg */
function _(el){
return document.getElementById(el);
}
function uploadFile(){
var file = _("file1").files[0];
// alert(file.name+" | "+file.size+" | "+file.type);
var formdata = new FormData();
formdata.append("file1", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "file_upload_parser.php");
ajax.send(formdata);
}
function progressHandler(event){
//_("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
var percent = (event.loaded / event.total) * 100;
_("progressBar").value = Math.round(percent);
_("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
_("status").innerHTML = event.target.responseText;
_("progressBar").value = 0;
document.getElementById('p1').innerHTML = "Drag your file here or click in this area.";
}
function errorHandler(event){
_("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
_("status").innerHTML = "Upload Aborted";
}
function changeText()
{
document.getElementById('p1').innerHTML = "1 file selected";
}
</script>
<link rel="stylesheet" href="test.css">
</head>
<body>
<h2>Upload</h2>
<fieldset>
<legend>Group 1</legend>
<form id="upload_form" enctype="multipart/form-data" method="post">
<input type="file" name="file1" id="file1"><br>
<p id="p1">Drag your file here or click in this area.</p>
<input type="button" value="Upload File" onclick="uploadFile()">
<progress id="progressBar" value="0" max="100" style="width:508px; margin-left: -4px; margin-top: 10px;"></progress>
<h3 id="status"></h3>
<p id="loaded_n_total"></p>
</form>
</fieldset>
<script>
// self executing function here
(function() {
document.getElementById('upload_form')[0].onchange = changeText;
})();
</script>
</body>
</html>
Here is the CSS (which is referred to in the html as test.css):
body{
background: rgba(0,0,0,0.0);
}
form{
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -250px;
width: 500px;
height: 200px;
border: 4px dashed #0D0D0D;
}
form p{
width: 100%;
height: 100%;
text-align: center;
line-height: 140px;
color: #0D0D0D;
font-family: Arial;
}
h2{
text-align: center;
}
form input[type="file"]{
position: absolute;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
outline: none;
opacity: 0;
}
form input[type="button"]{
margin: 0;
color: #fff;
background: #16a085;
border: none;
width: 508px;
height: 35px;
margin-top: -20px;
margin-left: -4px;
border-radius: 4px;
border-bottom: 4px solid #117A60;
transition: all .2s ease;
outline: none;
}
form input[type="button"]:hover{
background: #149174;
color: #0C5645;
}
form input[type="button"]:active{
border:0;
}
form progressBar{
text-align: center;
}
Coming back to the HTML, the fieldset tags are placed around the controls that I am attempting to encapsulate. I left them there so that anyone can see the main issue that I am running into.
I apologize but I am very new to web programming. Any help will be greatly appreciated, thank you.
Note: how the box is created doesn't really matter to me. I would expect that the box is created in HTML and then I can style it using CSS.
The structure of your HTML is fine, but the position: absolute properties in your CSS are clashing with the fieldset.
Since <fieldset> is wrapping all your controls, I would suggeset giving it a fixed width and height and position your child elements based on that, i.e. use width: 100% for your children and give all of them the same margin so they align nicely. Also make sure you either edit your #progressBar style in the markup.
Here's a snippet with the changes I just mentioned:
body {
background: rgba(0, 0, 0, 0.0);
}
fieldset {
width: 508px;
height: 270px;
/* fixed width and height*/
margin: 13vh auto;
}
#p1 {
border: 4px dashed #0D0D0D;
/* modified the actual text box instead of the entire form */
width: 508px;
height: 140px;
line-height: 140px;
margin-top: 0px;
}
form p {
text-align: center;
color: #0D0D0D;
font-family: Arial;
}
h2 {
text-align: center;
}
form input[type="file"] {
position: absolute;
margin: 0;
outline: none;
width: 508px;
height: 140px;
margin: 22px 4px;
opacity: 1;
background-color: orange;
/* Last two properties are a visual representation. Delete background-color and set opacity to 0 */
}
form input[type="button"] {
margin: 0;
color: #fff;
background: #16a085;
border: none;
width: 100%;
/* width relative to parent fieldset */
height: 35px;
margin-top: -20px;
border-radius: 4px;
border-bottom: 4px solid #117A60;
transition: all .2s ease;
outline: none;
}
form input[type="button"]:hover {
background: #149174;
color: #0C5645;
}
form input[type="button"]:active {
border: 0;
}
form progressBar {
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<script>
/* Script written by Adam Khoury # DevelopPHP.com */
/* Video Tutorial: http://www.youtube.com/watch?v=EraNFJiY0Eg */
function _(el) {
return document.getElementById(el);
}
function uploadFile() {
var file = _("file1").files[0];
// alert(file.name+" | "+file.size+" | "+file.type);
var formdata = new FormData();
formdata.append("file1", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "file_upload_parser.php");
ajax.send(formdata);
}
function progressHandler(event) {
//_("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
var percent = (event.loaded / event.total) * 100;
_("progressBar").value = Math.round(percent);
_("status").innerHTML = Math.round(percent) + "% uploaded... please wait";
}
function completeHandler(event) {
_("status").innerHTML = event.target.responseText;
_("progressBar").value = 0;
document.getElementById('p1').innerHTML = "Drag your file here or click in this area.";
}
function errorHandler(event) {
_("status").innerHTML = "Upload Failed";
}
function abortHandler(event) {
_("status").innerHTML = "Upload Aborted";
}
function changeText() {
document.getElementById('p1').innerHTML = "1 file selected";
}
</script>
<link rel="stylesheet" href="test.css">
</head>
<body>
<h2>Upload</h2>
<fieldset>
<legend>Group 1</legend>
<form id="upload_form" enctype="multipart/form-data" method="post">
<input type="file" name="file1" id="file1"><br>
<p id="p1">Drag your file here or click in this area.</p>
<input type="button" value="Upload File" onclick="uploadFile()">
<!-- changed progressBar style -->
<progress id="progressBar" value="0" max="100" style="width:100%; margin-top: 10px;"></progress>
<h3 id="status"></h3>
<p id="loaded_n_total"></p>
</form>
</fieldset>
<script>
// self executing function here
(function() {
document.getElementById('upload_form')[0].onchange = changeText;
})();
</script>
</body>
</html>
Hope it helps!
I've created a basic CSS Grid and had everything positioned where I wanted it. When I run my JS (appends info from an API call to a div), the div's dimension push beyond the borders of the viewport. Is there a way to prevent the overall body element from changing and just have the div dynamically increase height?
pics: https://imgur.com/a/wJAcW
I've tried so many different things and can't seem to figure this out. My fallback will be to just overwrite the div rather than append to it. Code is below.
//Set initial latitute and longitude variables, to be used later
var lat = 0;
var long = 0;
//Google Geocode API to find the latitude and longitude of the txtAddress
$("#submit").on("click", function() {
var userInput = $("#txtAddress").val();
//trim the user input to the form needed for the api
var userSearchTerm = userInput.split(' ').join('+');
//call the google geocode api
var queryURLGeocode = "https://maps.googleapis.com/maps/api/geocode/json?address=" + userSearchTerm + "&key=AIzaSyCSAYHZn9fz13c3bsl_RcS13HJu8wDJXCU"
$.ajax({
url: queryURLGeocode,
method: "GET"
})
.done(function(response) {
//Set latitude and longitude from the returned object
lat = response.results[0].geometry.location.lat;
//limit decimal points to 4 (xx.xxxx) - form needed for hiking api
lat = lat.toFixed(4);
long = response.results[0].geometry.location.lng;
long = long.toFixed(4);
//Call the hiking project api
var queryURL = "https://www.hikingproject.com/data/get-trails?lat=" + lat + "&lon=" + long + "&maxDistance=10&key=200206461-4fa8ac1aa85295888ce833cca1b5929f"
$.ajax({
url: queryURL,
method: "GET"
})
.done(function(response) {
// loop through the response trails and add info to the site
for (i = 0; i < response.trails.length; i++) {
var contentDivTitle = $("<div> class='newTrailTitle'");
var contentDivMain = $("<div> class='newTrailDescription'");
contentDivTitle.text("Name: " + response.trails[i].name + " Location: " + response.trails[i].location);
contentDivMain.text("Summary: " + response.trails[i].summary);
$("#search-results").append(contentDivTitle);
$("#search-results").append(contentDivMain);
}
});
});
});
html,
body {
background-color: black;
margin: 10px;
}
h1,
h3 {
color: white;
text-align: center;
padding: 5px;
line-height: 1px;
}
h1 {
/* automatically changes lowercase to uppercase text; */
text-transform: uppercase;
}
sub {
color: white;
text-align: center;
line-height: 1px;
font-size: 15px;
font-weight: lighter;
}
.container {
display: grid;
grid-template-columns: auto;
grid-template-rows: 800px 500px 200px 50px 100px;
grid-gap: 3px;
}
.container>div {
display: flex;
justify-content: center;
align-items: center;
font-size: 1em;
}
.container>div:nth-child(1n) {
background-color: black;
}
.container>div:nth-child(2n) {
background-color: blue;
}
.container>div:nth-child(3n) {
background-color: red;
}
.container>div:nth-child(4n) {
background-color: yellow;
}
.container>div:nth-child(5n) {
background-color: green;
}
label {
color: white;
}
#main {
background-image: url("assets/images/etienne-bosiger-367964.jpg");
background-size: cover;
background-repeat: no-repeat;
}
#au,
#cr {
display: block;
margin: auto;
}
#groupPic {
padding: 10px;
}
<html>
<head>
<link rel="stylesheet" href="test.css">
</head>
<body>
<div class="container">
<div id="main">
<div id="title">
<h1>kairns<sub>®</sub></h1>
<h3>"find your trail"</h3>
<div class="search-div">
<label for="txtAddress">Enter Address: </label>
<input type="text" name="txtAddress" id="txtAddress">
<button type="button" id="submit">Search</button>
</div>
</div>
</div>
<div class="search-results" id="search-results">2</div>
<div>
<p id="au">About Us</p>
<img id="groupPic" src="http://via.placeholder.com/150x150" alt="placeholder image">
<p id="cr">Copyright 2018.</p>
</div>
<div>4</div>
<div>
<p>Powered by
Google Maps,
Open Weather Map, and Hiking Project
</p>
</div>
</div>
<!-- JAVASCRIPT -->
<!-- jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- custom javaScript -->
<script type='text/javascript' src='assets/javascript/logic.js'></script>
</body>
</html>
All in-flow children of the #search-results element will align vertically if you apply:
#search-results {
display: flex;
flex-direction: column;
}
I have spent literally hours on this, I cannot get this button centered when the screen width entered xs mode, it started to position itself based off of the left side. I've tried looking in the bootstrap and cant find any clear indication as to why this happens.
Here is my code, mainly the third main div block with btn-posit class inside and the media queries 461-767px. Thanks
https://codepen.io/fullmetal7777/pen/RgKagp
<div class="container">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-8 col-xs-10 text-center btn-posit">
<button class="btn btn-primary twit-btn"><i class="fa fa-twitter-square fa-2x" aria-hidden="true"><span id="twit-Text">Tweet it</span></i></button>
<button class="btn btn-default quote-btn"><div id="whole-text">Get Quote</div></button>
</div>
</div>
This will get you close to what you want.
The issues:
The column with the buttons in had a class of col-xs-10 which should be col-xs-12 if you want the buttons to be centered.
The twitter button still had margin right on it for the xs size, which was pushing it to the left, preventing it from centering.
https://codepen.io/anon/pen/xrdPVb
If you just want the menus centered, you don't need to use the col-* classes to wrap them. Remove those and apply .text-center (which you already have), then remove all of the media queries you were using to offset the margin and try to center that column. But then I think you have some display issues from using transform: translateX(-1); so I just reversed the image and removed that transform line. The less work the browser has to do, the better, so if you can change the image, I'd just do that.
$(document).ready(function(){
var quotes = {
Mario: ["So long-a-Bowser!", "Nighty nighty. Ah spaghetti. Ah, ravioli. Ahh, mama mia.", "You know what they say: all toasters toast toast."],
Luigi: ["Let's-a go...", "Oh yeah! Who's number one now?! Luigi!", "Now, THIS is where the real action is"],
Bowser: ["Im HUUUUGE! Even scarier up close, huh?", "GAH HA HA HA! There's no WAY you're ready for a round against ME. Keep practicing, pip-squeak!"],
Peach: ['Oh, did I win?', "Go Peachy, Go Peachy, Go Peachy! Yay! Woohoo!"],
Yoshi: ['Yoshi!'],
Fox: ["This is Fox, returning to base!", "Better luck next time, Falco!"],
Falcon: ["Falcon Kick!", 'Blue Falcon!', 'Show me your moves!'],
Marth: ["Konkaiwa bokuno kachidane! (It's my victory this time!)", "Kyoumo ikinobiru kotoga dekita. (Even today I was able to survive.)",
"Bokuwa makeru wake niwa ikenainda! (There's no way I can lose!)"],
Pit: ["Three Sacred Treasures!", "It's game over for you!", "That all you got?"],
Link: ["....."],
Ike: ["Great... AETHER!", "I fight for my friends.", "You'll get no sympathy from me."],
Lucario: ["Behold, the power of Aura!", "The Aura is with me!", "Max Aura!"],
'Wii Fit Trainer': ["High energy, move that body!", "Salute the sun!", "Work hard to tone that tummy."],
Sheik: ['I\'ve been waiting for you, Hero of Time...', 'The flow of time is always cruel.'],
Ganandorf: ['Hero? ...I\'ve outlived more "heroes" than you can possibly imagine.', 'Behold! The power of the Demon King!',
'I am Ganondorf, the Demon King. Don\'t take that title lightly.'],
Mac: ["Let 'em have it, Mac!", "Way to go, Mac! You're the champ, baby!", "Nice moves, Mac. I can barely keep my eyes on you, son."],
Palutena: ["You shall be purified.", "No one can hide from the light.", "Celestial Fireworks!"],
Robin: ["The key to victory lies within.", "I'm always three steps ahead.", "It seems our fates are joined."],
Shulk: ["Now it's Shulk time!", "I can change the future!", "The future is ours to decide!"],
Sonic: ["That was almost too easy!", "Let's do that again some time!"],
Falco: ["Personally, I prefer the air!", "You aren't worth the trouble."],
Wario: ["Wa-Wa-Wa!", "Time for victory parade."],
'Toon Link': ["....."],
Lucina: ["The future is not written!", "Time to change fate!"]
}
var nameArr = ['Mario', 'Luigi', 'Bowser', 'Peach', 'Yoshi', 'Lucina', 'bowser jr', 'Wario', 'game and watch', 'donkeyk', 'diddyk', 'Link', 'Zelda',
'Sheik', 'Ganandorf', 'Toon Link', 'samus', 'zero suite samus', 'Pit', 'Palutena', 'Marth', 'Ike', 'Robin', 'kirby', 'king deedeedee', 'meta knight',
'Mac', 'placeholder', 'Fox', 'Falco', 'pikachu', 'charizard', 'Lucario', 'jigglypuff', 'Greninja', 'duck hunt', 'Rob', 'ness', 'Falcon', 'villager',
'olimar', 'Wii Fit Trainer', 'dr mario', 'dark pit', 'Lucina', 'Shulk', 'pacman', 'Megaman', 'Sonic'];
var imgurID = '0RQtP';
var key = "cfb3f86a62ab07c";
function randomFxn(){
$.ajax({
type: 'GET',
url: 'https://api.imgur.com/3/album/' + imgurID + '/images',
headers: {'Authorization': 'Client-ID '+ key},
}).done(function(data) {
showZones(data)
});
}
var lastNum = '70';
function showZones(jsonData){
var name = '';
do{
var nameNum = Math.floor(Math.random()*(Object.keys(quotes).length));
// var nameNum = 70;
console.log(nameNum);
} while (nameNum == lastNum)
console.log(lastNum);
lastNum = nameNum;
console.log(lastNum);
name = Object.keys(quotes)[nameNum];
var quoteArrLength = quotes[name].length;
var randQuoteNum = Math.floor(Math.random()*quoteArrLength)
var randQuote = '\"' + quotes[name][randQuoteNum] + '\"';
var indexMult = (nameArr.indexOf(name)*8);
var addToIndex = Math.floor(Math.random()*8);
var url = jsonData.data[(indexMult)+addToIndex].link;
var imgCss = 'url(' + url + ')';
var isReverse = Math.floor(Math.random()*2);
$('h3').text('-' + name);
$('h2').text('Hero? ...I\'ve outlived more "heroes" than you can possibly imagine.');
$('.bg').fadeOut(500, function() {
if(isReverse==1){
$(this).css({'background-image': imgCss, 'transform': 'scaleX(1)'}).fadeIn(700);
}
else{
$(this).css({'background-image': imgCss, 'transform': 'scaleX(-1)'}).fadeIn(700);
}
});
}
var num = 0;
$('.quote-btn').click(function(){
if (num == 0){
num++;
randomFxn();
setTimeout(function(){
num = 0;
}, 1200);
}
});
});
body, html{
height: 100%;
}
.bg,
.quote-btn {
background-repeat: no-repeat;
background-size: cover;
}
.bg{
background-image: url("http://i.imgur.com/sxwO4y3.jpg");
height: 100%;
background-size: 70% 100%;
}
.jumbotron{
margin-left: 16.66666667%;
margin-top: -78vh;
background-color: rgba(100, 100, 100, 0.4);
border-style: solid;
border-color: rgba(0, 0, 0, 0);
}
h2, h3{
color: white;
opacity: 1;
font-weight: 900;
}
h2{
margin-top: -3vh;
margin-left: -1.7vw;
}
h3{
float: right;
}
.quote-btn {
border-color: #5e1111 #5e1111 hsl(0, 69%, 17%);
background-image: url("http://www.wtfgamersonly.com/wp-content/uploads/2015/06/Super-Smash-Bros.-img.2.jpg");
background-position: 50% 60%;
height: 45px;
width: 140px;
}
.twit-btn{
height: 45px;
width: 140px;
margin-right: 35px;
}
#whole-text{
font-weight: 800;
color: #BC1818;
font-size: 22px;
}
.btn.quote-btn:focus,
.btn.quote-btn:active:focus,
.btn.quote-btn.active:focus,
.btn.quote-btn.focus,
.btn.quote-btn:active.focus,
.btn.quote-btn.active.focus,
.btn.twit-btn:focus,
.btn.twit-btn:active:focus,
.btn.twit-btn.active:focus,
.btn.twit-btn.focus,
.btn.twit-btn:active.focus,
.btn.twit-btn.active.focus{
outline-color: none;
outline-style: none;
border-color: #5e1111 #5e1111 hsl(0, 69%, 17%);
}
.btn.quote-btn:hover{
border-style: none;
}
.btn.quote-btn:active{
background-image: url("http://www.wtfgamersonly.com/wp-content/uploads/2015/06/Super-Smash-Bros.-img.2.jpg");
opacity: .8;
}
#media only screen and (max-height: 568px){
.jumbotron{
margin-top:-89vh;
}
}
#media only screen and (min-height: 569px){
.jumbotron{
margin-top:-80vh;
}
.btn-posit {
margin-top: -42vh;
}
}
#media only screen and (min-width: 0px) and (max-width: 1199px){
.bg{
background-size: cover;
background-position: center;
}
}
/*medium*/
#media only screen and (min-width: 992px) and (max-width: 1199px) {
.jumbotron{
margin-left: 8.33333333%;
}
}
/*small*/
#media only screen and (min-width: 768px) and (max-width: 991px){
.jumbotron{
margin-left: 4.15%;
}
}
/*xs*/
#media only screen and (min-width: 461px) and (max-width: 767px){
.jumbotron{
margin-left: 8.33333333%;
}
.btn-posit{
width: auto;
}
}
#media only screen and (min-width: 0px) and (max-width: 460px) {
h2{
font-size: 22px;
}
h3{
font-size: 18px;
}
.btn-posit{
/*padding-left: 78px; */
margin-left: 1%;
}
.jumbotron{
margin-left: 8%;
}
.twit-btn{
margin-right: 55px;
width: auto;
}
#twit-text{
display: none;
}
}
/*#media only screen and (min-width: 0px) and (max-width: 422px) {
h2{
font-size: 22px;
}
h3{
font-size: 18px;
}
.twit-btn{
width: auto;
margin-right: 10px;
}
.btn-posit{
padding-left: 15%;
}
#twit-text{
display: none;
}
}*/
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://use.fontawesome.com/5ad62430a6.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<html>
<head>
<title>AwesomeDesigns Random Quote Generator</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="bg"></div>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 col-sm-11 col-xs-10 jumbotron">
<h2>"Andrews Random Quote Generator. "</h2>
<h3>-Andrew Hickman</h3>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="text-center btn-posit">
<button class="btn btn-primary twit-btn"><i class="fa fa-twitter-square fa-2x" aria-hidden="true"><span id="twit-Text">Tweet it</span></i></button>
<button class="btn btn-default quote-btn"><div id="whole-text">Get Quote</div></button>
</div>
</div>
</div>
</html>
adding text-center class seemed to be the fix!
Update: Can't see to get things working in Firefox : (
How can I display custom video controls when the in fullscreen mode in modern browsers?
They disappear as soon as I go fullscreen. I'd like them to be available, and then I'll write some JavaScript to hide them on inactivity and show them once someone wiggles their mouse around.
HTML:
<video#video src="vid.mp4" preload poster="/images/poster.jpg">
<iframe src="https://youtube.com/embed/id" frameborder="0" allowfullscreen>
</video>
JS:
var bigPlayButton = document.getElementById('big-play-button')
var video = document.getElementById('video')
var playPauseButton = document.getElementById('play-pause')
var fullscreen = document.getElementById('fullscreen')
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen()
} else {
if (document.exitFullscreen) {
document.exitFullscreen()
}
}
}
fullscreen.addEventListener('click', function (event) {
if (!video.classList.contains('fullscreen')) {
video.requestFullscreen()
} else {
document.exitFullscreen()
}
}, false)
// Detect FullScreen changes and adjust button
document.addEventListener('fullscreenchange', function (event) {
if (document.fullscreenElement) {
fullscreen.children[0].src = '/images/nofullscreen.svg'
video.classList.add('fullscreen')
} else {
fullscreen.children[0].src = '/images/fullscreen.svg'
video.classList.remove('fullscreen')
}
}, false)
CSS
video::-webkit-media-controls {
display: none !important;
}
#custom-video-controls {
z-index: 2147483648;
}
I'm using this polyfill: https://github.com/neovov/Fullscreen-API-Polyfill
Edit
The significant change was targeting the parent tag: .vidFrame for fullscreen instead of the <video> tag as per Kaido's comment.
HTML5 video's controls need special handling if you want to override them. I'm assuming you want to do that since the controls already have the full screen feature built in the controls. This demo implements:
classList for toggling the button#fullScreen states of .on and .off and button#playPause states of .play and .pause.
:fullscreen pseudo-class to insure .vidBar is on the bottom when in full screen mode.
Shadow DOM CSS Styles that are needed to override the native player's controls.
Fullscreen API vendor specific methods to enter and exit full screen mode of course.
There's no volume slider, mute button, or scrubber, just the full screen button (button#fullScreen) and play button (button#playPause). If you want them, ask another question.
Details are commented in source.
It looks as if the Snippet isn't fully functional, so here's a functional Plunker. If that version cannot be reached, then review the embedded Plunker and click the full view button:
Demo
Note: SO sandbox has changed so this demo is not fully functional go to the links mentioned previously or copy and paste the demo on a text editor.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Full Screen Video Toggle</title>
<style>
.vidFrame { position: relative; top: 10%; width: 320px; height: auto; min-height: 180px; outline: 1px dashed red; }
.vidBar { position: absolute; bottom: 0; right: 0; left: 0; height: 40px; width: 99%; }
#fullScreen { position: absolute; bottom: 0; right: 0; width: 36px; height: 36px; outline: none; border: 1px solid transparent; border-radius: 6px; display: block; cursor: pointer; }
#fullScreen:hover { border: 1px groove #0ef; }
.on, .off { background: url('https://i.imgur.com/0FTwh6M.png') no-repeat; width: 36px; height: 36px; }
.off { background-position: 0 0 }
.on { background-position: -1px -50px }
#playPause { position: absolute; bottom: 0; left: 0; width: 36px; height: 36px; background: none; font-size: 36px; color: #0ff; line-height: 1; border: 1px solid transparent; display: block; cursor: pointer; outline: none; }
#playPause.play:before { content: '\25b6'; }
#playPause.pause:before { content: '\275a\275a'; }
.vid { position: absolute; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: auto; display: block; z-index: 1; outline: 1px dotted blue; }
/*
Fullscreen Pseudo-class:
https://developer.mozilla.org/en-US/docs/Web/CSS/:fullscreen
*/
.vidBar:-moz-full-screen { position: fixed; }
.vidBar:-webkit-full-screen { position: fixed; }
.vidBar:-ms-fullscreen { position: fixed; }
.vidBar:fullscreen { position: fixed; }
/*
Special Shadow DOM Settings to Override Default Controls:
https://css-tricks.com/custom-controls-in-html5-video-full-screen/
*/
video::-webkit-media-controls-enclosure { display:none !important; }
.vidBar { z-index: 2147483648; }
</style>
</head>
<body>
<figure class="vidFrame">
<video id="vid1" class="vid" src="http://techslides.com/demos/sample-videos/small.mp4"></video>
<figcaption class="vidBar">
<button id='playPause' class="play" title="Play/Pause Video"></button>
<button id='fullScreen' class="on" title="Enter/Exit Full Screen"></button>
</figcaption>
</figure>
<script>
/*
Toggle Button with classList:
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
*/
var fullBtn = document.getElementById('fullScreen');
var playBtn = document.getElementById('playPause');
playBtn.addEventListener('click', function(event) {
var player = document.getElementById('vid1');
if(player.paused) {
playBtn.classList.remove('play');
playBtn.classList.add('pause');
player.play();
} else {
playBtn.classList.add('play');
playBtn.classList.remove('pause');
player.pause();
}
}, false);
fullBtn.addEventListener('click', function(event) {
var tgtEle = document.querySelector('.vidFrame');
var onOrOff = fullBtn.classList.contains('on');
if (onOrOff) {
enterFS(tgtEle);
fullBtn.classList.remove('on');
fullBtn.classList.add('off');
} else {
exitFS();
fullBtn.classList.add('on');
fullBtn.classList.remove('off');
}
}, false);
/*
Fullscreen API:
https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API
*/
function enterFS(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
}
}
function exitFS() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
</script>
</body>
</html>
Use the Fullscreen API on the container element, not on the video
As #Kaiido says in the comments:
You have to call the enterFS method on the container element, not on
the video one.
So the answer is to use the Fullscreen API on the container element rather than the <video> element. This enables providing custom controls in that container which is now all in fullscreen.
For reference, that is the existing enterFS() function from the question:
function enterFS(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
}
}
I posted this answer because I had to read the page three times to figure out what was going on here.
There is great information in #zer00ne's answer that is relevant to others with similar issues, but it doesn't directly answer #Costa's original problem, which was previously only answered in a comment.