The following media query isn't working. I want it to only affect devices less than 415px, but it's affecting all of my code, i.e. devices >415px
The Code:
#media only screen and (max-width: 415px) {
.anchor-offset {
height: 80px;
margin-top: -80px;
}
}
At the moment this is applied to all of my HTML elements which have the class .anchor-offset.
Thank you in advance.
If you want that this media queries will be available only in mobile devices, i would use JS to identify the device and load the css queries file. For example, something like this:
const ifIsMobile = { // detect the mobile devices
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (ifIsMobile.Android() || ifIsMobile.BlackBerry() || ifIsMobile.iOS() || ifIsMobile.Opera() || ifIsMobile.Windows());
}};
const loadMobileCss = () => { // add the link tag to load mobilestyles.css
const linke = document.createElement("link");
linke.rel = "stylesheet";
linke.href = "mobilestyles.css";
document.getElementsByTagName("head")[0].appendChild(linke);
}
if (ifIsMobile.any()) loadMobileCss(); // if the device is mobile, load mobilestyles.css with the function loadMobileCss()
You have to put this code in the head of your web to make this work.
You can try to use a container with a fixed size if you would like to use it for coding purposes. personally i would use a mobile environment or flex/responsive coding.
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<body>
<div style="width: 415px"class="w3-container w3-red">
<p>This is a container with max output of 415px. this size can not be exeeded.</p>
</div>
</body>
</html>
Related
I'm detecting device orientation using window.matchMedia. The following code works as intended - every orientation change is logged to console with correct value:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Test App</title>
</head>
<body>
<script type="application/javascript">
let isIframe= () => {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
let onOrientationChange = () => {
const isLandscape = window.matchMedia("(orientation: landscape)").matches;
console.log("Event: " + (isIframe() ? "Iframe " : "") + "landscape:" + isLandscape);
}
let mediaQueryList = window.matchMedia("(orientation: landscape)");
console.log("Onload: " + (isIframe() ? "Iframe " : "") + "landscape:" + mediaQueryList.matches);
mediaQueryList.addListener(onOrientationChange);
</script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">Hello World in Iframe</div>
</body>
</html>
But when I run that page in iframe, callback registered using addListener is not fired. In iframe, I only get singular log line - Onload: Iframe landscape:true, regardless of the device orientation.
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">Hello World</div>
<iframe id="game" src="iframeContent.html" frameborder="0" style="width: 960px; height: 600px;"></iframe>
</body>
I'm using addListener instead of addEventListener, because the second one function is not working on all Safari versions.
Tested on Safari 14 and on Dev Tools of Chrome and Firefox.
My question is - why addListener callback is not invoked in iframe.
Thank you.
If the iframe does not get it's size to change because it has fixed width and height, thus resize related events cannot be triggered inside it including MediaQueryList events regarding orientation.
You can do two things to get this working; you can make your iFrame width and height to be 100%, or you can let the media query detection code inside the main window and pass the orientation state using postMessage when it triggers a change event.
1) Changing iFrame size to 100% so it resizes when landscape/portrait orientation event triggers
In the main page, make the body full height and the iframe full width/height (using CSS).
body {
height: 100vh;
margin: 0;
}
iframe {
width: 100%;
height: 100%;
}
Live example that you can test: https://zikro.gr/dbg/so/65704468/
2) Media query detection on the main page and use postMessage to send a message to iFrame when orientation event triggers
index.html:
<iframe src="iframe.html"></iframe>
<script>
let iframe = document.querySelector('iframe');
let onOrientationChange = () => {
iframe.contentWindow.postMessage({
isLandscape: window.matchMedia("(orientation: landscape)").matches
}, '*');
}
iframe.addEventListener('load', onOrientationChange);
const mediaQueryList = window.matchMedia("(orientation: landscape)");
mediaQueryList.addListener(onOrientationChange);
</script>
iframe.html:
<script>
window.addEventListener("message", (event) => {
if (event.data.isLandscape) {
console.log('iFrame Landscape');
} else {
console.log('iFrame Portrait');
}
});
</script>
Live example that you can test: https://zikro.gr/dbg/so/65704468/pm/
I'm trying to combine Js Lazy load with responsive images breakpoints.
The algorithmic concept is to find image width values that offer a significant reduction in file size. Images are analyzed to find the best breakpoints on an image by image basis, rather than creating all possible image resolutions, and enables developers to easily create 'picture' and 'img' HTML5 elements based on the calculated breakpoints.
Everything works fine with the lazy-loading, but the data-srcset is not working as it should, unfortunately. The image displayed is always the one from the data src so the image breakpoints is not working at all.
I've made a Codepen to illustrate the problem.
HERE: https://codepen.io/cat999/pen/bGEKwNE
How should I fix this?
$(document).ready(function() {
var lazyloadImages;
if ("IntersectionObserver" in window) {
lazyloadImages = document.querySelectorAll(".lazy");
var imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var image = entry.target;
image.src = image.dataset.src;
image.classList.remove("lazy");
image.classList.add("animated");
image.classList.add("fadeIn");
imageObserver.unobserve(image);
}
});
});
lazyloadImages.forEach(function(image) {
imageObserver.observe(image);
});
} else {
var lazyloadThrottleTimeout;
lazyloadImages = $(".lazy");
function lazyload () {
if(lazyloadThrottleTimeout) {
clearTimeout(lazyloadThrottleTimeout);
}
lazyloadThrottleTimeout = setTimeout(function() {
var scrollTop = $(window).scrollTop();
lazyloadImages.each(function() {
var el = $(this);
if(el.offset().top - scrollTop < window.innerHeight) {
var url = el.attr("data-src");
el.attr("src", url);
el.removeClass("lazy");
lazyloadImages = $(".lazy");
}
});
if(lazyloadImages.length == 0) {
$(document).off("scroll");
$(window).off("resize");
}
}, 20);
}
$(document).on("scroll", lazyload);
$(window).on("resize", lazyload);
}
})
<meta name="viewport" content="width=device-width, user-scalable=no">
<img src="https://ik.imagekit.io/demo/img/image1.jpeg?tr=w-400,h-300" />
<img src="https://ik.imagekit.io/demo/img/image2.jpeg?tr=w-400,h-300" />
<img src="https://ik.imagekit.io/demo/img/image3.jpg?tr=w-400,h-300" />
<img
alt="Image 03" class="lazy" src="https://via.placeholder.com/220x280?text=Img+03"
data-src="https://www.matteogiordano.info/img/castle_c_scale,w_200.jpg"
data-srcset="https://www.matteogiordano.info/img/castle_c_scale,w_200.jpg 200w,
https://www.matteogiordano.info/img/castle_c_scale,w_364.jpg 364w,
https://www.matteogiordano.info/img/castle_c_scale,w_486.jpg 486w,
https://www.matteogiordano.info/img/castle_c_scale,w_591.jpg 591w,
https://www.matteogiordano.info/img/castle_c_scale,w_681.jpg 681w,
https://www.matteogiordano.info/img/castle_c_scale,w_764.jpg 764w,
https://www.matteogiordano.info/img/castle_c_scale,w_846.jpg 846w,
https://www.matteogiordano.info/img/castle_c_scale,w_922.jpg 922w,
https://www.matteogiordano.info/img/castle_c_scale,w_993.jpg 993w,
https://www.matteogiordano.info/img/castle_c_scale,w_1064.jpg 1064w,
https://www.matteogiordano.info/img/castle_c_scale,w_1138.jpg 1138w,
https://www.matteogiordano.info/img/castle_c_scale,w_1201.jpg 1201w,
https://www.matteogiordano.info/img/castle_c_scale,w_1261.jpg 1261w,
https://www.matteogiordano.info/img/castle_c_scale,w_1329.jpg 1329w,
https://www.matteogiordano.info/img/castle_c_scale,w_1393.jpg 1393w,
https://www.matteogiordano.info/img/castle_c_scale,w_1397.jpg 1397w,
https://www.matteogiordano.info/img/castle_c_scale,w_1400.jpg 1400w"
data-sizes="220px"/>
I currently have a page on my site that when you go to, it forwards you to a random page on my site. Right now I am trying to shrink that list if the user is viewing it on mobile. I am having trouble figure this out. Right now I have made two different onLoad functions in the script section, and media queries that remove the html that loads it based on screen size.
<html>
<head>
<script type="text/javascript">
<!--
// Create an array of the links to choose from:
var links = new Array();
links[0] = "spinguy.html";
links[1] = "hardware.html";
links[2] = "flappymatt.html";
links[3] = "spinzone.html";
links[4] = "shlink.html";
links[5] = "goop.html";
links[6] = "spinzone.html";
links[7] = "index1.html";
links[8] = "ghoul.html";
links[9] = "grandma.html";
function openLink() {
// Chooses a random link:
var i = Math.floor(Math.random() * links.length);
// Directs the browser to the chosen target:
parent.location = links[i];
return false;
}
<!--
// Create an array of the links to choose from:
var links = new Array();
links[0] = "spinguy.html";
links[1] = "hardware.html";
links[2] = "flappymatt.html";
links[3] = "shlink.html";
links[4] = "ghoul.html";
links[5] = "grandma.html";
function openPhoneLink() {
// Chooses a random link:
var i = Math.floor(Math.random() * links.length);
// Directs the browser to the chosen target:
parent.location = links[i];
return false;
}
//-->
</script>
<style>
.phone{
display: none;
}
#media only screen and (max-width: 800px) {
.computer{
display: none;
}
.phone{
display: inline;
}
}
#media only screen and (max-width: 400px) {
.computer{
display: none;
}
.phone{
display: inline;
}
}
</style>
</head>
<body>
<div class="computer" onload="openLink();"></div>
<div class="phone" onload="openPhoneLink();"></div>
</body>
</html>
A few things.
divs don't have an onload event -- this honor is reserved for the body. As such, I moved your onload call to the body tag. <body onload="openLink()">. Check this out.
display: none; doesn't keep an element from loading, it just keeps it from appearing on the page.
You don't even need to use divs for this. If you look at how I have re-written what you are trying to do, you'll see that there aren't any divs on the page. I simply call the function onload and replace the location within the openLink() function.
Use window.location.href to change a page's URL. StackOverflow question.
You don't need to return false at the end of JavaScript functions. They just return to the program flow when they end. (But if you did call them from something that expected a return value and did not have one, you would get undefined.)
I didn't update openLink() to choose from a different array based on the size, but you should use something like let windowWidth = window.innerHeight; and use an if statement depending on the value. Also, take a look at some better ways to use and populate arrays in JavaScript.
<head>
<script type="text/javascript">
//get size of window using window.innerWidth and make the link array according to the value
// Create an array of the links to choose from:
function openLink() {
var links = new Array();
links[0] = "spinguy.html";
links[1] = "hardware.html";
links[2] = "flappymatt.html";
links[3] = "spinzone.html";
links[4] = "shlink.html";
links[5] = "goop.html";
links[6] = "spinzone.html";
links[7] = "index1.html";
links[8] = "ghoul.html";
links[9] = "grandma.html";
// Chooses a random link:
var i = Math.floor(Math.random() * links.length);
// Directs the browser to the chosen target:
window.location.href = links[i];
}
</script>
</head>
<body onload="openLink()"></body>
</html>
First, your onload attributes will not work because it is only a valid attribute on a subset of HTML elements, namely:
<body>, <iframe>, <img>, <input>, <link>, <script>, <style>
This is because those elements have some sort of async loading associated with them. Check this w3schools.com page for reference.
I assume based on your description that you intended these onload events to occur on the <body> because it has the distinct behavior "to execute a script once a web page has completely loaded all content".
This is okay, because you don't need to separate functions for openLink() and openPhoneLink(), and these can be collapsed into one function for simplicity.
You can avoid the wonkiness of the #media CSS queries as Javascript has the ability to determine the width and height of your viewport anyway.
window.screen.width - device width
window.screen.height - device height
If you want to get real fancy with dimensions and device rules, you can find references like this one which give you a breakdown of what different dimensional variables in Javascript mean.
Now, back to the question at hand...
You can test the device switch by using something like the Chrome Developer Tools and toggling between mobile devices and refreshing the browser. In this case, my 800 pixel check is not good enough to know an iPad is not a computer, but you can put whatever rules you want in here.
I've taken the liberty to give you a more re-usable data structure for your links. I hope this helps you out:
<html>
<head>
<script type="text/javascript">
const Device = {
COMPUTER: "computer",
PHONE: "phone"
}
const links = [
{ href: "spinguy.html", computer: true, phone: true, },
{ href: "hardware.html", computer: true, phone: true, },
{ href: "flappymatt.html", computer: true, phone: true, },
{ href: "spinzone.html", computer: true, phone: false, },
{ href: "shlink.html", computer: true, phone: true, },
{ href: "goop.html", computer: true, phone: false, },
{ href: "index1.html", computer: true, phone: false, },
{ href: "ghoul.html", computer: true, phone: true, },
{ href: "grandma.html", computer: true, phone: true, },
]
const randomIndex = (length) => {
return Math.floor(Math.random() * length)
}
const device = () => {
// modify as needed to distinguish devices you care about
return window.screen.width >= 800 ? Device.COMPUTER : Device.PHONE
}
const openRandomLink = () => {
const deviceKey = device()
// console.log("deviceKey", deviceKey)
const validLinks = links.filter(link => link[deviceKey])
const randomLinkIndex = randomIndex(validLinks.length)
const randomLink = validLinks[randomLinkIndex].href
// console.log("randomLink", randomLink)
window.location.href = randomLink
}
</script>
</head>
<body onload="openRandomLink()">
</body>
</html>
I want to use the DIV to display my report, so i see the icCube documentation icCube Web Reporting : Displaying a Report but when i try to apply it i'm confused about how can I putting the differents functions of the script to gather in the same html page , those are the functions:
The first Part
var ic3reporting = new ic3.Reporting({
noticesLevel: ic3.NoticeLevel.ERROR,
dsSettings: {
userName: "demo",
userPassword: "demo",
url: "http://localhost:8282/icCube/gvi"
}
});
ic3reporting.setupGVIConfiguration(function() {
ic3reporting.setupApplication({
mode: ic3.MainReportMode.REPORTING,
menu: ic3.MainReportMenuMode.OFF,
noticesLevel: ic3.NoticeLevel.ERROR,
container: $("#report-container")
});
});
The Second Part
var options = {
report: { name: 'My Report' },
mode: ic3.MainReportMode.EDITING_REPORTING,
menu: ic3.MainReportMenuMode.ON,
noticesLevel: ic3.NoticeLevel.INFO
};
ic3reporting.openReport(options, function() {
// your callback (I don't inderstand how can i putting this code)
});
I don't inderstand how can I put those parts to gather and
It's very important for me to build this script , That make the exportation of the report easier than before.
You can use these parts together in such way:
<!doctype html>
<head lang="en">
<meta charset="utf-8">
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%
}
</style>
</head>
<body>
<!-- 1. Define container for the report somewhere in html page -->
<div id="report-container"></div>
<!-- 2. Include reporting application scripts -->
<script src="http://localhost:8282/icCube/doc/ic3-report/app/reporting/js/loader/ic3bootstrap.js"></script>
<!-- 3. Initialization sequence -->
<script type="text/javascript">
var ic3root = "http://localhost:8282/icCube/doc/ic3-report/app/";
var ic3rootLocal = "http://localhost:8282/icCube/doc/ic3-report/app-local/";
// ic3reporting variable could be used globally, consider using array or different names here if
// you are going to show multiple report applications at the same time
var ic3reporting = null;
var options = {
root: ic3root,
rootLocal: ic3rootLocal,
// This function starts work just after initialization of reporting framework
callback: function () {
// 3.1 Create reporting instance with proper data source configuration
ic3reporting = new ic3.Reporting({
noticesLevel: ic3.NoticeLevel.ERROR,
dsSettings: {
userName: "demo",
userPassword: "demo",
url: "http://localhost:8282/icCube/gvi"
}
});
// 3.2 This function setups connection to the configured datasource and calls callback when connection is ready
ic3reporting.setupGVIConfiguration(function () {
// 3.3 Here we have ready connection, time to show empty reporting application
var initialApplicationOptions = {
mode: ic3.MainReportMode.REPORTING,
menu: ic3.MainReportMenuMode.OFF,
noticesLevel: ic3.NoticeLevel.ERROR,
container: $("#report-container")
};
ic3reporting.setupApplication(initialApplicationOptions);
// 3.4 just after setupApplication we have ready to work reporting environment, we can open reports, switch modes, etc
// here we have open report sequence
var options = {report: {name: 'My Report'}};
ic3reporting.openReport(options, function () {
alert("Report opened successfully")
});
});
}
};
ic3ready(options);
</script>
</body>
</html>
This is the correcte code
<html>
<head lang="en">
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<!-- ic3 bootstrap javascript -->
<script src="http://localhost:8282/icCube/doc/ic3-report/app/reporting /js/loader/ic3bootstrap.js"></script>
<script type="text/javascript">
/**
* Location of the icCube reporting files; not necessarily co-located
* with this HTML page. For example, assuming this file is located within
* the "Docs" repository of a local icCube install, this path would be :
*
* /icCube/doc/ic3-report/app/reporting/
*/
var ic3root = "http://localhost:8282/icCube/doc/ic3-report/app/";
var ic3rootLocal = "http://localhost:8282/icCube/doc/ic3-report/app-local/";
var options = {
root: ic3root,
rootLocal: ic3rootLocal,
callback: function () {
var ic3reporting = new ic3.Reporting(
{
noticesLevel:ic3.NoticeLevel.ERROR,
dsSettings:{
userName:"demo",
userPassword:"demo",
url: "http://localhost:8282/icCube/gvi"
}
});
ic3reporting.setupGVIConfiguration(function () {
ic3reporting.setupApplication(
{
mode:ic3.MainReportMode.REPORTING,
menu:ic3.MainReportMenuMode.OFF,
noticesLevel:ic3.NoticeLevel.ERROR,
container:$(".ic3-report-content-container")
});
var options = {
report:{
name:'rapportest'
},
mode:ic3.MainReportMode.EDITING_REPORTING,
menu:ic3.MainReportMenuMode.OFF,
noticesLevel:ic3.NoticeLevel.INFO
};
ic3reporting.openReport(options, function () {
alert("Report opened successfully")
});
});
}
};
ic3ready(options);
</script>
<div class="ic3-report-content-container" style="border:solid 1px red;"></div>
I'm trying use to a Conditional CSS loading technique found here but I cannot get this to work. The code can be found below (I've stripped out some parts for clarity) here is live link.
The media queries do not apply when the screen is stretched above 650px. The idea is use conditional loading to prevent downloading unnecessary CSS files.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" class="mediaquerydependent"
data-media="screen and (min-width: 300px)"
data-href="styles/stylemin300.css">
<link rel="stylesheet" class="mediaquerydependent"
data-media="screen and (min-width: 650px)"
data-href="styles/stylemin650.css">
<script type="text/javascript" src="js/mediamatch.js">
</head>
<body>
<h2>HELLO</h2>
</body>
</html>
Here is the JavaScript:
(function(){
var queries = document.
querySelectorAll('.mediaquerydependent'),
all = queries.length,
cur = null,
attr = null;
while (all--) {
cur = queries[all];
if (cur.dataset.media &&
window.matchMedia(cur.dataset.media).matches) {
for (attr in cur.dataset) {
if (attr !== 'media') {
cur.setAttribute(attr, cur.dataset[attr]);
}
}
}
}
}());