Tutorial: HTML5 – the basics on stacking elements with position: and z-index:

stacking-order

Source Code & Working Example

If you’ve ever tried to make a popup window, like toast(), or a dialog, like alert(),  and you’ve been frustrated by the process, this tutorial should help. NOTE: This code will work in your webbrowser and a mobile device; adding config.xml will allow it to build with Phonegap Build.

When trying to do a popup window, there are three important things to know:

  • positioning
  • stacking (or z-index)
  • hiding the popup

In this article I cover, stacking – or when and how to use z-index. Reminder, “stacking” allows HTML elements to overlap each other. Hence, using stacking allows overlapping to take place. This tutorial will use the “Working Example” linked at the top of the article.

Previously, I covered positioning in another article Tutorial – Text Overlay on to an Image with CSS.

Hiding the popup will be covered in a future article. I will add that link here, when it is done.

Important Note on Using z-index

z-index will only work on an element whose position property has been explicitly set to absolute, fixed, or relative.

Setting Up the Popup

start

START

If you look in app.css, you will see:

#stack1 {left:50px;top:50px;}
#stack2 {left:70px;top:70px;}
#stack3 {left:90px;top:90px;}

From this code, it appears that the stack1 should start before stack2 and stack3, but with the image with the caption START, this does not appear to be the case.

A closer look at index.html shows:

stack-code

A bug in wordpress requires me make this an image.

In this case, simple moving the <div> with id=stack1 above id=stack2 will solve the issue. However for this example we are going to use the z-index to place the element how we want it.

Simple Examples with z-index

doit

DOIT

However, when we do it the results are not what we expect. If we click the button labelled doit, the code below gets executed and the results are shown in the image DOIT. It is not quite what we expect. The order is correct, but for some reason the red element is transparent. (more on this later)

 

document.getElementById('stack1').style.zIndex = -1;
doit2

DOIT2

The alternative to this is to move the other two (2) elements so they are above the red element. If we then recycle the page and click the button labelled doit2, then we see the effect we have been desiring (DOIT2). The code below shows the method.

 

 

document.getElementById('stack2').style.zIndex = 2;
document.getElementById('stack3').style.zIndex = 3;

It is also worth noting that we could have set the z-index of both elements to the value of two (2) and gotten the same result.

Closing Comments

This very simple example was to show four (4) things that should now be obvious

  1. Overlapping HTML elements is available with the natural stacking order.
  2. When the natural stacking order of HTML does not work, use z-index.
  3. Sometimes things do not work as expected.
  4. Sometimes the longer approach works better.

To be clear, when you write HTML – the first element will stack below the second element, and the second element will stack below the third element, and so forth. This is called the “natural stacking order” (or the stacking order based on appearance). So when an element needs to overlap above other elements and it is not in the “natural stacking order”, use z-index. For more details on z-index see below.

Said another way, if you plan the order of your HTML elements correctly, you will not need to use z-index.

Lastly, above I said I would talk about the transparent issue. In the README.md there is a link to an article:

What No One Told You About Z-Index by Philip Walton

In this article, Philip presents the lesson as a challenge to solve a problem. He solves the problem by using opacity. As you read it, you’ll find out why we got a weird outcome earlier, and about “stacking context”. Note: opacity produces a side effect used with stacking.

Advertisements

Tutorial: HTML5 Dynamic Font Resize

Source Code & Working Example font-sizes

Every modern webbrowser today has variable font sizes. There are two reasons for this: 1. It was a fairly trivial addition for browser makers. 2. It made the web more accessible to people with disabilities. On the later, it is important to note as the population grows older, vision becomes strained – and therefore adding an option to resize fonts is an important feature.

NOTE: This Working Example works in your webbrowser and on your mobile device; adding config.xml will allow it to build with Phonegap Build.

Today with responsive web, it is a matter of a few lines of code. However, there are a few issues that you will run into.

  • One issue is where to hook the font-size change.
  • The other is margins and padding.

Both of those will be covered after a walk through the example. Note, if you have trouble with the buttons, recycle the webpage.

Initial Size

font-size = 100%

font-size = 100%

The default size set for the <html> element is font-size=100%. In the emulator, the page layout looks very similar to the image with the caption font-size = 100%.

Bigger Size

font-size = 125%

font-size = 125%

If you click the button [bigger], the entire page will have the all the fonts increased in size – to 125% of the original. The emulator results are visible in the image with the caption font-size = 125%. The code to change the font-size looks like this:

document.body.parentNode.style.fontSize = '125%';

Smaller Size

font-size = 75%

font-size = 75%

If you click the button [smaller], the entire page will have the all the fonts decreased in size – to 75% of the original. The emulator results are visible in the image with the caption font-size = 75%. The code to change the font-size looks like this:

 document.body.parentNode.style.fontSize = '75%';

Hooking the font-size Change

If you look at the code in app.js, you will see the modifications to the font-size made three (3) different ways. The code snippet below outlines the different methods. For all intensive purposes, the first two (2) lines are equivalent.

document.getElementById('allOfIt').style.fontSize = '100%';
document.body.parentNode.style.fontSize = '100%';
document.body.style.fontSize = '100%';

The first two (2) references above are for the document element – the one and only <html>. The third reference is for <body>. They will all do the same thing, when you make a change to fontSize.

However, if you change to <body>, you will notice that the [reset] for the first two (2) references (<html>) do nothing at all. This is because the changes are compounding (or inherited, or scoping – depending on your point of view). This means, if make the font bigger for <html>, then that makes the font bigger for <body>. IF THEN, the final font size is 125% bigger for <html> + 125% bigger for <body>. In px this means, we start with 16px, then increase by 125% for <html> – making it 20px, then increase by 125% for <body> – making it 25px!

In the end, <body> seems to be the better choice. However, even after making this decision. There is another hidden pitfall, namely – margins and padding.

margins and padding

When I design my pages I do NOT use px or percent (%); as px is fixed and would require me to hunt down every instance of px and change it — And percent (%) would require similar. I use em, but even this has the infamous css compounding problem (google search link).

So you should be aware that for dynamically font resizing, there are two (2) possible solutions – em and rem.

  • em is equal to the size of the font that applies to the parent of the element. (So, this suffers from compounding.)
  • rem is equal to the size of the font that applies to the root html element, not the parent element.

In general, em works for padding, and rem works for margin. However – excluding headers, I tend to stick to one font. So, you’ll have to make your own judgement – but be diligently consistent!

Sidenote, some designers use 0.625em as a design reference. This Google search will help you research this point.

Bottom Line

Having Dynamic Font Resize is fairly trivial, but requires diligence when design – even for mobile device.

Addendum

Kerri Shotts has suggested also adding a user device preference from phonegap-plugin-mobile-accessibility.

Tutorial: Phonegap Build external webpage in iframe with whitelist example

https://pixabay.com/photo-25490/Source Code & Working Example

In the last few months, the architecture `du jour` has been to create an app that open webpages. This tutorial shows you how to do that for Cordova/Phonegap. The example is written for Phonegap Build, but will work with CLI with minor modification.

The sections below include:

  • Mobile App Caveat – Something every hybrid mobile developer should know.
  • Opening and Closing a URL – Deals with the mechanics of HTML and Javascript.
  • Addressing Security Concerns – How to secure your app when opening a URL.

Mobile App Caveat

Putting aside the security concerns, the most difficult part for mobile developers is that your app may be rejected by the “app stores” – if you do this.

Quote Google Developer Program PoliciesSpam and Placement in the Store

Do not post an app where the primary functionality is to:

  • Drive affiliate traffic to a website or
  • Provide a webview of a website not owned or administered by you (unless you have permission from the website owner/administrator to do so)

Quote Apple iTunes Guidelines – 2.12

Apps that are not very useful, unique, are simply web sites bundled as Apps, or do not provide any lasting entertainment value may be rejected

In addition there is the android-block-pre-4.1.1:

Beginning May 9, 2016, Google Play will block publishing of any new apps or updates that use pre-4.1.1 versions of Apache Cordova.

Google’s Official Alert: How to fix apps with Apache Cordova vulnerabilities

Opening and Closing a URL

This section deals with the mechanics of HTML and Javascript to show an external webpage. In addition, more notes are available in the README.md and the source code.

The code that toggles the iframe uses zepto.js, a light weight jquery clone alternative. The code is listed below; just below is a button. Notice this is not a <submit> element as *was* previously used to create a buttons with HTML forms. This is an HTML5 button and zepto.js working together.

<button id=toggle>toggle</button>

Next, the iframe is wrapped with a <div>. This is where we hide the external webpage (http://cordova.apache.org/blog/). The <div> is initially set to class=hide. This hides the <div> and any children that it has; include the iframe. This class uses the CSS attribue display=none to accomplish this (See: app.css).

code_snippet_001

Below is the mechanics that make the <div> hide and show the external webpage in the iframe. It has one (1) global variable, that can easily be scoped. And as can be seen, if the element isVisible, then removeClass() else addClass(). The variable isVisible keeps track of our state.

var isVisible = 0; // if element initially hidden, zero (0) else one (1)
$('#toggle').on('click', function() {
    console.log("isVisible:" + isVisible );
    if (isVisible) {
        $('#togglePane').addClass('hide');
        isVisible = 0;
    } else {
        $('#togglePane').removeClass('hide');
        isVisible = 1;
    }
});

Next, when testing the working example, you will likely notice a small side effect. The “sided effect” is that the webpage does not load until the hidden <div> is exposed (or has the ‘hide’ class removed). Pre-loading the page is available, but is beyond the scope of this tutorial.

Addressing Security Concerns

At this point in order to appease the “stores”, you will need to use an appropriate whitelist setting. This requires the whitelist plugin and the <allow-navigation> tag with Andoird and <access origin=(...)> for iOS.

The plugin entry in the config.xml should look like this:

 <plugin name="cordova-plugin-whitelist" source="npm" />

The <allow-navigation> tags needed should look like this:

<allow-navigation href="http://cordova.apache.org/" />
<allow-navigation href="https://slack.cordova.io" />
<allow-navigation href="http://www.google-analytics.com/" />
<allow-navigation href="https://*.imgur.com/" />
<allow-navigation href="https://*.twitter.com/" />
<allow-navigation href="https://*.twimg.com/" />
<allow-navigation href="http://cordovablogs.discus.com/" />

What is not immediately apparent is that all the domains listed are required so that the one external webpage will be rendered correctly. Generally, the list of the domains can be extracted by looking at the source, but sometimes you’ll need to open the “information page” for that webpage. On firefox, that is ctrl-i.

Last but not least, is the <access> tag. This is set to the “wild card”, which will allow anything through. To secure the app better, this should mirror the the entry for allow-navigations.

<access origin="*" />

If you have any question, please use the comment section below, or find me on Google Group for Cordova/Phonegap.

For more detailed information on the whitelist and the plugin, read: