Git Product home page Git Product logo

object-fit's Introduction

Polyfill for CSS object-fit property

This is a headless polyfill for the CSS object-fit property which defines the sizing mode for content images (similar to background-size for CSS background sources).


NOTICE: DEPRECATED / Non-Functional

Please note that as Microsoft Edge does not support a good way to get matching CSS rules, and there are a couple of other issues that aren’t likely to be fixed, this polyfill is of limited benefit for most projects as all other browser vendors support object-fit natively now.


Alternatives with Edge support

object-fit-images and fitie can be used instead of this polyfill.


The Webstandard

The specification for object-fit is to be found at W3C CSS3 Images. The property scales the image to fit in a certain way into a defined area, e.g:

img {
	width: 100%; // dimensions are mandatory
	height: 35em; // dimensions are mandatory

	object-fit: cover;
	overflow: hidden; // Cuts off the parts of the image poking out
}

Normally, the image would be stretched to the specified dimensions but due to the usage of the CSS property object-fit: cover; the image now is scaled proportionally, until every pixel of the defined area is covered by parts of it. In the case of cover this means that parts of the image will overlap the given area.

The following are the possible values and their implications:

  • fill streches the image exactly to the defined dimensions which results in a distorted image. Comparable to background-size: 100% 100%. That's the default value.
  • none leaves the image at its natural size and centers it inside within the defined area. If the image's natural dimensions are larger than the defined area parts of the image will poke out of it unless you also set overflow: hidden on it. Comparable to background-size: auto auto; background-position: center center.
  • contain scales the image up or down until all of it fits into the defined area. This mode respects the image's natural aspect-ratio. It's also called "letterbox view". Comparable to background-size: contain.
  • cover scales the image up or down until every pixel of the defined area is covered with parts of the image. Sort of "pan and scan view". This means that parts of the image will poke out of the defined area unless you also set overflow: hidden on it. This mode respects the image's natural aspect-ratio. Comparable to background-size: cover.

How object-fit works

Feature Detection

The polyfill uses a feature detection method to see if object-fit is supported. If it's not it will active itself.

Browser Support

This polyfill works in all major browsers as well as in IE9+. Find out which browsers support object-fit natively.

Browser polyfill? natively?
Google Chrome yes v31+
Opera yes v24+
Firefox 4+ (#13) v36+
Internet Explorer 9+ "under consideration"

Setup / Usage

This polyfill is available as Bower component or via npm. Use it right away from bower:

$ bower install --save object-fit

or set up via npm

$ npm install --save object-fit

The --save flag is used to store the package dependency in the package.json so it can be automatically fetched next time using npm install. Use --save-dev to use it only as development dependency (but only do if you are sure you know what you do).

Or set up manually by grabbing the download from GitHub. Then include the CSS file polyfill.object-fit.css in your HTML <head>, the JavaScript file polyfill.object-fit.min.js at the bottom of your HTML <body>. Right behind the JavaScript file reference you now need to call the polyfill:

<script>
	objectFit.polyfill({
		selector: 'img', // this can be any CSS selector
		fittype: 'cover', // either contain, cover, fill or none
		disableCrossDomain: 'true' // either 'true' or 'false' to not parse external CSS files.
	});
</script>

You can find sample implementations in our test directory.

Testing

Due to CSP restrictions and our CSS parser there’s no way to test this polyfill from a filesystem. You need to set up a local server that serves from root directory. Calling http://localhost:8000/tests/index-cover.html should work then. php -S localhost:8000 for example would start a local PHP server on your current directory.

DOM watching capabilities

In browsers greater IE8 the polyfill uses DOM Mutation Events or Mutation Observers (depending on what's available) to detect the injection of further images matching the defined selector. This means that it will also apply itself to any images that you append to the DOM at any later point. And it will detach itself from images that you remove from the DOM. Since this feature is sort of complicated to craft in a rock solid way, you might look out for unexpected behaviors.

Security / Mixed Content Issues and 3rd Party CSS

If you use any third party CSS or mixed content on your website (Webfonts from a service, a CDN, or similar), the polyfill might not work as expected. You can still use the polyfill but then need to set some options regarding CSP:

For example you need to set the header to:

'Access-Control-Allow-Origin: *'

This should fix the issue. If you also need to support credentials, you can’t use * but need the server reply with two headers (server needs also to reply with Access-Control-Allow-Credentials: true), one of which includes the origin in question.

It is recommended to add the attribute crossorigin="" to your CSS link element that is called from the external resource to indicate what type of CORS the server should reply with.

In case you can’t alter the CSP / CORS settings of the server in question, you can disable parsing external CSS files in the config of the call:

<script>
	objectFit.polyfill({
		selector: 'img',
		fittype: 'cover',
		disableCrossDomain: 'true'
	});
</script>

Author

This polyfill is written by Anselm Hannemann and Christian "Schepp" Schaefer. Follow them on Twitter via @helloanselm and @derSchepp or check their GitHub profiles via anselmh and Schepp for more information.

License

This project is under the MIT Open Source License. See the LICENSE file for more information.

object-fit's People

Contributors

ahmadalfy avatar anselmh avatar bfred-it avatar drublic avatar fluke avatar hotmeteor avatar koffeinflummi avatar maximilianos avatar nyalab avatar schepp avatar spacecowboyian avatar teaualune avatar xax 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

object-fit's Issues

Usage of objectfit as global variable in module context

In src/polyfill.getMatchedCSSRules.js you are using objectfit as a global variable, which is not set, if the polyfill is loaded via an AMD module loader.

Code that throws the exception "ReferenceError: objectFit is not defined": if (objectFit.disableCrossDomain == 'true')

Currently the polyfill is not usable when using an AMD loader…

Does this also work with videos?

I was able to download the master file and run it in visual studio. However I have a video (via HTML5 video tag) that uses object-fit (and I need it to work in Internet Explorer). Does anyone know if it is just for images or can I apply it to videos as well?

Does this work in IE8?

Thanks for the great polyfill. I've got a question about IE 8 support as the readme is confusing.

This polyfill works in all major browsers as well as in IE8+.

Sounds like it does.

Google Chrome | yes | (from v31 natively via experimental flag)
Opera | 14+ | (from v18 natively via experimental flag)
Firefox | 4+ | (vote for this bug)
Internet Explorer | 8+ | (not implemented yet)

Sounds like it doesn't.

img-circle

hi, i have been trying to make this work on a circle container, but unsuccessfully so far. I have tried to add the border radius 50% in my selector, but it gets ignored and when I use an extra class the object-fit does not work.

Any suggestions and help would be great . Thanks

Not working in Microsoft Edge

Due to a bug in getMatchedCSSRules in Microsoft Edge this polyfill won’t work as expected in Microsoft Edge. As this function is basically the heart of the polyfill, I have no clue how to fix this without refactoring the whole polyfill (which due to other restrictions is unwanted).

I’m very sorry about this. In case anyone has a solution, please let me know or send a Pull Request.

Installing through bower fails for me

bower object-fit#*          not-cached git://github.com:anselmh/object-fit.git#*
bower object-fit#*             resolve git://github.com:anselmh/object-fit.git#*
bower object-fit#*             ECMDERR Failed to execute "git ls-remote --tags --heads git://github.com:anselmh/object-fit.git", exit code of #128

Additional error details:
fatal: Unable to look up github.com (port anselmh) (nodename nor servname provided, or not known)

Doesn't work?

Hello,

Is the polyfill still under development?

I've tested the examples using ie 8 and 9, using the download without modification and non of the examples work.

Cheers, Stephen

IE9 issues

IE9 shows a bit weird behavior. While it does apply the tags it sucks at maintaining the styles and then cuts the image dimensions in a completely wrong way.

This might be because we’re not using currentStyle (which is non-standard and has very ugly issues) for getting and setting the styles.

CSS2Properties doesn't have an indexed property setter in FF (28)

Getting the following error in Firefox on my implementation and your test files:
I'm seeing:

Timestamp: 19/02/2014 11:39:33
Error: Error: Permission denied to access property 'mediaText'
Source File: http://comeround.bbpdev.com/__dev/all/object-fit/dist/polyfill.object-fit.js
Line: 32

Timestamp: 19/02/2014 11:39:56
Error: TypeError: CSS2Properties doesn't have an indexed property setter.
Source File: http://comeround.bbpdev.com/__dev/all/object-fit/dist/polyfill.object-fit.js
Line: 396

SecurityError: The operation is insecure

Firefox console outputs:
SecurityError: The operation is insecure.

And points towards this:

// get the style rules of this sheet
return toArray(stylesheet.cssRules);

Initialise polyfill repeatedly

Less of an issue, more of a support request.

I'm currently trying to implement the polyfill on a website that uses infinite-scroll and I need some method of re-running the polyfill every time new content is loaded in. The first initialisation works great, but does not affect the newly loaded content.

I've tried calling objectFit.polyfill() repeatedly, however it returns the error Can't execute code from a freed script, which is apparently related to the use of iframes within the polyfill.

If there's some way of being able to run the polyfill several times without encountering this issue?

Thanks!

Initialize after window load

With a simple check of document.readyState === 'complete', the plugin could work even after the page is loaded.

Document CSSOM CORS: "SecurityError: The operation is insecure." with ext. CSS

When using external CSS (like a CDNed CSS, ext. Webfonts) Firefox throws an error in part of our script:
resp. https://gist.github.com/ydaniv/3033012/#file-mozgetmatchedcssrules-js-L23

There are some hints for this here: http://stackoverflow.com/a/5323868 and http://stackoverflow.com/questions/3211536/accessing-cross-domain-stylesheet-with-cssrules.

The issue, solution and circumvention hack should be well documented so authors don't run into it not knowing what is going on.

Firefox 17.0.6 script not responding

Firefox 17.0.6 displays a popup indicating the script polyfill.object-fit.min.js:1 is not responding.

I'll try to get more information about this and keep you informed.

Warn developers about usage

You should consider adding a warning to the readme about using this polyfill.

It has 677 stars but you've stated in #46 that you are no longer actively developing it. Plus, there is no support for Microsoft Edge (#45), and some quite serious problems (#38, #23) that suggest it is slightly broken.

Some might miss this info and dive into it - best for them and for this project to be up front about it's state.

Tests not working in IE9

Maybe a duplicate of #23

I just tried the included tests in IE9 and they don't seem to work. All files are being loaded and there are no errors in the console. However, the image is missing for an unknown reason.

IE version: 9.0.8112

ie9 - win7

Works fine in IE10. Let me know if you need more information.

Rewrite / Replace CSS parser with proper solution

I at least found some information what causes the trouble and makes Firefox slow and unresponsive when dealing with multiple images here. It’s the selector matching and generally getting the computedStyles from the elements and re-applying them.

François Remy (@FremyCompany) wrote his own parser based on Tab Atkins’. Probably this will perform better and with less errors than the currently used one.

Sources

Hopefully I’m able to test this out in the next weeks. I’ve started a branch here, so if you want to try helping out, please use this branch as base.

It might also solve the CORS/CSP issue we’re currently facing. cc @ketri.

Bountysource

slow

obect-fit.js is very slow on firefox

I think the probleme is getMatchedCSSRules polyfill


Bountysource

CORS advice is bogus

There's some CORS advice in the README.md that suggests "use-credentials" would work with *, but it won't. If you include credentials the server needs to reply with two headers, one of which includes the origin on question.

IE11 crashes because of css crawling

Unfortunately in my project your plugin causes IE11 to crash. My project contains a lot of css-files and since the plugin is crawling all css files it seems to overcharge the browser. Why is it necessary to browse the css, when the plugin is initialized with explicit options like selector: 'img' and fittype: 'cover'? Is there any way to prevent css crawling?

Object-fit replaces classes on image

https://github.com/anselmh/object-fit/blob/master/src/polyfill.object-fit.core.js#L134 and https://github.com/anselmh/object-fit/blob/master/src/polyfill.object-fit.core.js#L143 mean that any classes on the default image get replaced completely by the object-fit polyfill.

My issue is that I am using @aFarkas's https://github.com/aFarkas/lazysizes which works with the class lazyload to watch for images to lazy-load. When the object-fit polyfill is applied on the image as below, the image never loads because the class lazyload on the element is replaced with x-object-fit-taller.

Shall I create a pull request? the change would be to change it to: replacedElement.className += ' x-object-fit-taller'; for example.

The code for reference. Webpack+Babel used to package modules.

<img alt="" data-object-fit="contain" class="lazyload" data-srcset="..." data-sizes="..." src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
/** Responsive Images Polyfill */
import 'picturefill';

/** Lazyload Images */
import '../../node_modules/lazysizes/plugins/bgset/ls.bgset.js';
import 'lazysizes';

/** Object-fit/Object-position Polyfill */
import objectFit from 'object-fit';

window.objectFit = objectFit; // because objectFit referenced on global object within polyfill code

let addEvent = () => window.addEventListener || window.attachEvent; 
// if above value and not fn IE complains about 'Invalid calling object' for some reason...
let event = ( window.addEventListener ? '' : 'on' ) + 'DOMContentLoaded';

addEvent()(event, () => {
    objectFit.polyfill({
        selector: '[data-object-fit="cover"]',
        fittype: 'cover',
        disableCrossDomain: true
    });

    objectFit.polyfill({
        selector: '[data-object-fit="contain"]',
        fittype: 'contain',
        disableCrossDomain: true
    });
});

Not working in IE11

Just tried this out in IE11 and it is not working. It looks like the issue is that <x-object-fit> has it's parent container's styling applied to it.

Here's the code:

HTML

<div class="img_container img_container-portrait">
  <img class="img-cover" src="https://placeimg.com/640/480/any" alt="" />
</div>

CSS

body {box-sizing: border-box;}
*, *::before, *::after {position: relative;box-sizing: inherit;}

.img-cover {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  object-fit: cover;
}

.img_container {
  width: 50%;
  max-width: 25rem;
  margin: 5rem auto;
  overflow: hidden;
  border: 2px solid #313131;
}

.img_container-portrait::before {
  content: '';
  display: block;
  padding-top: 130%;
}

JS

window.objectFit.polyfill({
  selector: '.img-cover',
  fittype: 'cover',
  disableCrossDomain: 'false'
});

Here is the resulting html:

<div class="img_container img_container-portrait">
  <x-object-fit class="x-object-fit-cover" style="margin: 5rem auto; border: 2px solid rgb(49, 49, 49); border-image: none; width: 50%; overflow: hidden; max-width: 25rem;">
  <img class="x-object-fit-taller" alt="" src="https://placeimg.com/640/480/any" data-x-object-relation="taller">
  </x-object-fit>
</div>

You can see that <x-object-fit> has the parent's styling in it's style attribute.

JSFiddle Example

Drop auto-detection for explicit usage

I may be mistaken, but it seems various problems are stemming from attempting to auto-detect usage of object-fit?

If this is true, wouldn't it make sense to drop that in favour of explicit usage? Like this for example: https://github.com/steveworkman/jquery-object-fit

Seems simpler, and I think it's reasonable to expect people using object-fit to be prepared to add polyfill code to their projects.

No bower as postinstall.

package.json is for npm. It shouldn't contain bower install as postinstall. You should give to dev a /dist version. (and still make it work with bower if you want, yes).

Missing 'scale-down`

Just wanted to point out that this is missing one of the property values: scale-down.

From W3C Spec:

‘scale-down’
Size the content as if ‘none’ or ‘contain’ were specified, whichever would result in a smaller concrete object size.

Not working in Firefox 35

Firefox 35 does not implement object-fit, thus the importance of supporting in with your object-fit polyfill.

Firefox console reports

SecurityError: The operation is insecure. polyfill.object-fit.js:109

Line 109 is:

// get the style rules of this sheet
return toArray(stylesheet.cssRules);

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.