Git Product home page Git Product logo

vminpoly's Introduction

vminpoly

A polyfill for CSS units vw, vh & vmin.

Simple online demo right here. A more sophisticated responsive demo demonstrating vw/vh/vmin units along with media queries, working right down to IE5.5 on the desktop and Opera Mini on mobiles!! (In Opera Mini the browser must be refreshed after changing phone orientations as it appears it doesn't trigger the window resize event)

This is a working proof of concept right now. There's a lot of cleanup to do on the code.

Since most browsers ignore rules they don't understand, the code must load and parse the original CSS sourcecode. It does this using a javascript CSS parser. Once this is done, it filters the generated tree leaving only rules that use 'vh', 'vw' & 'vmin' units. At window resize time, it generates CSS code for the 'px' equivalents and appends it in a 'style' element at the end of the 'head' element. The generated code respects media queries.

As it is, it's fast enough for a lot of cases, but the code can still be optimized greatly, both in parsing and in resizing.

Also, any suggestions on how to better organize the repo, specially with respect to third party code, is greatly appreciated.

Notes

  • It's working fine in IE5.5+, Firefox, Opera and even Opera Mini, which doesn't support any of the units or media queries. Chrome, Safari and the Firefox beta don't need it.
  • Well... Chrome and Safari actually can benefit from it as they don't properly handle font-size natively while resizing the window.

TODO:

  • IE9 and IE10 support vw, vh & vm, so the code should only translate 'vmin' units to 'vm'
  • Only linked stylesheets are being parsed right now but it's very easy to also parse 'style' elements.
  • Also, recursively parse @import rules.
  • Add some more examples of what can be achieved.

In short, the only browser with apparently full native support right now is Firefox beta (Aurora). The rest will benefit from this polyfill immediately, even without the badly needed code polishing.

Latest Changes:

  • After some bug fixes it finally works down to IE5.5 on the desktop and Opera Mini on mobile!!
  • Also, I removed the dependency on jQuery.
  • Now resizes correctly right after page load.
  • Media query support!! (rudimentary, but check out the new demo!)
  • Right now, media queries only apply to rules with vw,vh/vmin units. Other rules won't be applied just yet. More to come...

vminpoly's People

Contributors

coldacid avatar deep-spaced avatar rjfranco avatar saabi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vminpoly's Issues

Tackle Todo List

Not to be a total mooch but I'm interested in using this on a project and wondered if you'd abandoned this plugin or intended to do more work on it. If I can help with any of the items there, they could be listed as issues and assigned to me. I'll try to tackle them in the coming month or two.

What is the purpose of the document script?

Could you please spare a moment to document the purpose of the document script found inside both demos?

<script type="text/javascript">
    if (!Array.prototype.filter) {
        Array.prototype.filter = function(fun /*, thisp*/ ) {
            var len = this.length;
            if (typeof fun != "function")
                throw new TypeError();

            var res = new Array();
            var thisp = arguments[1];
            for (var i = 0; i < len; i++) {
                if (i in this) {
                    var val = this[i]; // in case fun mutates this
                    if (fun.call(thisp, val, i, this))
                        res.push(val);
                }
            }

            return res;
        };
    }
</script>

Must I include it in my own web pages? It doesn't seem to do anything.

Thank you very much,
BB

Can't make it work

I have put the scripts in their respective places but for some reason it doesn't work. I loaded the demo in Safari 5.0 for windows and it worked, I don't know what I'm doing wrong. The script files are in the same directory as index.html. Any help would be really appreciated :)
Please forgive me if it's a stupid question put it's the first time that i'm implementing a polyfill.

<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="test"></div>
<script type="text/javascript">
    if (!Array.prototype.filter)
    {
      Array.prototype.filter = function(fun /*, thisp*/)
      {
        var len = this.length;
        if (typeof fun != "function")
          throw new TypeError();
        var res = new Array();
        var thisp = arguments[1];
        for (var i = 0; i < len; i++)
        {
          if (i in this)
          {
            var val = this[i]; // in case fun mutates this
            if (fun.call(thisp, val, i, this))
              res.push(val);
          }
        }
        return res;
      };
    }
  </script>
  <script src="tokenizer.js"></script>
  <script src="parser.js"></script>
  <script src="vminpoly.js"></script>
</body>
</html>
#test {
    width: 10vw;
    height: 10vh;
    background-color: red;
}

Media Query max-width

Hi,

parsing of my mediaQuery ist not working!
How can i fix this?

@media only screen and (max-width: 320px) {
..
}

Consider adding tags for the repo.

Hi~
Adding tags for repo could specify points in history and mark release points.
It's helpful for user to know the version and status of repository, and would enable wider distribution of the library, for example on CDNJS
Would you please consider on using tags?

Thanks for your great work!!
Piicksarn

Doesn't work with Modernizr

When I use:

<script src="stc/js/default/modernizr.custom.98457.js"></script>
<script type="text/javascript">
    Modernizr.load([{
        test : Modernizr.cssvhunit,
        nope : 'stc/js/default/vimpoly.min.js',
    }]);
</script>

Modernizr code

Only works when opera 12 and never on the browser of Android 4.1

Stop running this script? IE 8

On IE 8..

Stop running this script?
A script on this page is causing Internet Explorer to run slowly. If this continues to run, your computer might become unresponsive.

screen shot 2015-09-08 at 11 41 31

This is on a blank WordPress theme with Bootstrap CSS & JS.
The three JS files (tokenizer, parser, vminpoly) are minified into one file along with Bootstrap. In this order:

1. bootstrap.js
2. tokenizer.js
3. parser.js
4. vminpoly.js

The minified file is in the footer of my theme after including jQuery.

My CSS:

section.banner {height: 90vh;}

I am using BrowserStack to test my local site.

Here is a screenshot of my JS code before being minified with CodeKit

screen shot 2015-09-08 at 11 53 19

Licensing

i wish to use this for commercial project... could you please provide licence.txt

Adds empty style tag

The script finds vh/vw units but only adds empty <style></style> to the header. I tried to remove other js libraries that i use in my project but it didn't help.
Errors in console:

Parse error at token 334: DELIM(*).
undefined parser.js:56
Uncaught TypeError: Cannot read property 'append' of undefined parser.js:62
pop parser.js:62
parse parser.js:129
(anonymous function) vminpoly.js:272
xmlhttp.onreadystatechange vminpoly.js:45
Parse error at token 296: DELIM(*).
undefined parser.js:56
Parse error at token 456: DELIM(*).
undefined parser.js:56
Uncaught TypeError: Cannot read property 'append' of undefined parser.js:62
pop parser.js:62
parse parser.js:129
(anonymous function) vminpoly.js:272
xmlhttp.onreadystatechange

No feature test for window dimensions in testXSupport functions

The getViewportSize function does a comprehensive job of feature-testing how to get the pixel dimensions of the window/document. However, the testVHSupport and testVWSupport functions use window.innerHeight/innerWidth directly, and testVMinSupport uses document.documentElement.clientHeight/clientWidth directly.

The tests should probably go through getViewportSize to obtain the necessary pixel dimension.

Can't get it working in IE8

image

That <p>1</p> element has the following style:

p {
  height: 30vh;
  background: black;
  width: 100%;
}

Here is the result (not fixing the <p> to 30vh):

image

Would appreciate any help!

Tokenizer breaks IE 8 and older - Quick fix

This plugin seems to break on IE 8 and older because Array.filter is not supported and will give you an error.

https://github.com/saabi/vminpoly/blob/master/tokenizer.js#L501

A quick way to fix this yourself is to include the following snippet:

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var res = [];
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in t)
      {
        var val = t[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, t))
          res.push(val);
      }
    }

    return res;
  };
}

window.innerWidth and window.innerHeight are not available in IE < 9

Hi, first of all thank you congraturations for this idea!

I thinks this project is very important and useful, I belive the future of the webdesign is in these units (I needed to implemented some strange .js way to do these layouts in the recent past, sadly without knowing the existence of the vw,vh,vmin,vmax units)

With my experience on this i found a potential problem in your code,
you use:

   dims = {
      vh: window.innerHeight / 100,
      vw: window.innerWidth / 100
    };

to get the viewport size, anyway window.innerXXX are not supported in IE < 9:

I know maybe you don't support IE8 but it sadly has 20% of the share so a "polyfill" should look to support it (i hate IE8 don't misundestand me: my customers sadly love it :) )

I also think that using self instead of windows may prevent some problem in iframes see:

https://developer.mozilla.org/en-US/docs/Web/API/window.innerWidth#Example

So I paste here my cross browser getViewportSize function code from my old private plugin to implement something like this just to inspire you

absolutleyRelative.getViewportSize = function() {
    var x=0;
    var y=0;
    if (self.innerHeight) // all except Explorer < 9
    {
        x = self.innerWidth;
        y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight)
    // Explorer 6 Strict Mode
    {
        x = document.documentElement.clientWidth;
        y = document.documentElement.clientHeight;
    }
    else if (document.body) // other Explorers < 9
    {
        x = document.body.clientWidth;
        y = document.body.clientHeight;
    }
    return {
        width: x, 
        height: y
    };
}


absolutleyRelative.getViewportWidth= function(){
    return  absolutleyRelative.getViewportSize().width; 
//return absolutleyRelative.useWindowInnerSize ? window.innerWidth :rootElement.width()
}
absolutleyRelative.getViewportHeight= function(){
    return  absolutleyRelative.getViewportSize().height;
//return absolutleyRelative.useWindowInnerSize ?window.innerHeight:rootElement.height()
}

(see also commented part in last two functions, another useful cross-browser technique is to use a dummy root element with stlye="position:absolute;top:0px;left:0px;width:100%;height:100%;visibility:hidden;..." placed just after the body, it also solve the "scrollbar width" problem in some browser but is too tricky)

There is a duplicate check with the same method

In the following line

test_results = testVWSupport(test_element, style_block) and testVWSupport(test_element, style_block) and testVMinSupport(test_element, style_block)

testVWSupport has been used two times. I think second one should be testVHSupport .

closure error

There is an closure error in the code, if there are many css link, it may work incorrect.

for (_i = 0, _len = links.length; _i < _len; _i++) {
  i = links[_i];
  if (i.rel !== 'stylesheet') {
    continue;
  }
  innerSheetCount++;
  ajax(i.href, function(cssText) {
    var sheet, tokenlist;

    tokenlist = tokenize(cssText);
    sheet = parse(tokenlist);
    analyzeStylesheet(sheet);
    sheets[i.href] = sheet;
    outerSheetCount++;
    if (outerSheetCount === innerSheetCount) {
      window.onresize();
    }
  });
}

How to organize your repo a bit better

Also, any suggestions on how to better organize the repo, specially with respect to third party code, is greatly appreciated.

  • put all demo stuff in a /demo folder, preferably in a gh-pages branch
  • put all test stuff in a /tests folder
  • put all source stuff (.coffee, etc.) in a /src folder
  • put all distribution stuff (requirements like parser.js, etc. and vminpoly.js) in a /dist folder
  • get a fancy Bower badge http://shields.io so people can quickly see what version you're on
  • consider changing the name of the project from vminpoly to something like viewport-units-polyfill since it's not vmin specific anymore
  • "Notes" should be titled "Browser Support"
  • "TODO:" shouldn't be in your README. Create issues for anything like that.
  • Get rid of "Latest Changes:" as well and just keep logs when you package a release example
  • Get rid of the warnings throughout the README that it's a work in progress and instead create an Issue titled "Refactor" and assign "Help Wanted" to it.
  • Add installation/usage instructions (What requirement files do I need to load before vminpoly.js? Where should I put them in my HTML? Should I put them in a conditional comment so only IE8 users have to face the downloads?)

If you want help on this stuff I can open a PR. Just want to make sure you'd accept it before doing the work.

Padding problem

Hey
If you add padding to elements, the polyfill does not account for it. Like if you stack two elements vertically, and add 50vh to them with padding-bottom of 10px to the first and padding-top 10px to the second, the second one clips a little.

JS errors cause the library to not work

My web page makes use of a couple of Google fonts which are referenced using link tags:

<link href="http://fonts.googleapis.com/css?family=Raleway:400,300,500,700' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>

On my Windows desktop running Chrome 38 the following errors propagate:

XMLHttpRequest cannot load http://fonts.googleapis.com/css?family=Raleway:400,300,500,700. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:2602' is therefore not allowed access. index.html:1
Uncaught Error! vminpoly.js:43
XMLHttpRequest cannot load http://fonts.googleapis.com/css?family=Lato:300,400,700. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:2602' is therefore not allowed access. index.html:1
Uncaught Error! vminpoly.js:43

It is difficult to confirm whether the library actually works on my desktop because Chrome 38 supports vh and vw. What I can confirm is that the correct styles are generated in the head tag.

The observable problem occurs on my Samsung Galaxy II running Chrome for Android 18. On my mobile device the polyfill simply doesn't work when those errors occur. When I remove/comment out the previously listed links - preventing the errors - the polyfill works.


My workaround is to link my Google Fonts using CSS @import instead.

Which file to quote?

Your demo references three files(js);

So, do we also need to refer to these three files?

Some question for install?

Hi,
a small installation manual would be awesome?
Is it necessary to use tokenizer and parser js-files to get it work?
Have I put some JS-Code in my website to initialize this polyfill?

Kind regards

[enhancement] Add missing bower.json.

Hey, maintainer(s) of saabi/vminpoly!

We at VersionEye are working hard to keep up the quality of the bower's registry.

We just finished our initial analysis of the quality of the Bower.io registry:

7530 - registered packages, 224 of them doesnt exists anymore;

We analysed 7306 existing packages and 1070 of them don't have bower.json on the master branch ( that's where a Bower client pulls a data ).

Sadly, your library saabi/vminpoly is one of them.

Can you spare 15 minutes to help us to make Bower better?

Just add a new file bower.json and change attributes.

{
  "name": "saabi/vminpoly",
  "version": "1.0.0",
  "main": "path/to/main.css",
  "description": "please add it",
  "license": "Eclipse",
  "ignore": [
    ".jshintrc",
    "**/*.txt"
  ],
  "dependencies": {
    "<dependency_name>": "<semantic_version>",
    "<dependency_name>": "<Local_folder>",
    "<dependency_name>": "<package>"
  },
  "devDependencies": {
    "<test-framework-name>": "<version>"
  }
}

Read more about bower.json on the official spefication and nodejs semver library has great examples of proper versioning.

NB! Please validate your bower.json with jsonlint before commiting your updates.

Thank you!

Timo,
twitter: @versioneye
email: [email protected]
VersionEye - no more legacy software!

Will not work in Safari until browser window is resized

Hi Saabi,

Thank you for the time and effort you've put into this polyfill.

I'm experiencing one issue while using this with Safari in a test webpage I'm building, wherein the vw, vh, vmin etc untils are not being converted to pixels until after the browser is resized.

If you know anything about this issue, any tips you have will be appreciated.

Thanks,

Cleaning up

Also, any suggestions on how to better organize the repo, specially with respect to third party code, is greatly appreciated.

I gotcha. =) ๐Ÿ‘

appendChild error

Getting the following error:

Uncaught TypeError: Cannot read property 'appendChild' of undefined vminpoly.js:80 browserSupportsUnitsNatively
(anonymous function) vminpoly.js:351
(anonymous function) vminpoly.js:351

Any way to fix this? completely kills IE

Please advise: Attempt to open a curly-block in a statement-type at-rule. parser.js:56

I'm getting this many times in the console and the style isn't added to the head of the document.

Parse error at token 21574: {.
Attempt to open a curly-block in a statement-type at-rule. parser.js:56

Having read around it seems that this is either a issue with parser.js or perhaps more likely my css.

Assuming it's my css, can you advise me on how to identify what it has a problem with? I imagine it's a small tweak to the parser file. I'm really new to all this, so feel really lost right now. I really want to get this working. It's a great end-result.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.