ausi / cq-prolyfill Goto Github PK
View Code? Open in Web Editor NEWProlyfill for CSS Container Queries
Home Page: https://au.si/css-container-element-queries
License: MIT License
Prolyfill for CSS Container Queries
Home Page: https://au.si/css-container-element-queries
License: MIT License
Add a .scss file to the project with a mixin that escapes the selector like https://gist.github.com/rask/434e96f603e8b439dc64 but in SCSS only if possible.
A rule like _::-webkit-:not(:root:root) > * { width: 100px; }
lets the script stop working in Safari.
Queries against containers with calc()
expressions don’t work correclty. width: calc(100% / 10)
doesn’t work while width: 10%
does.
Hi,
It's a bit hard to describe but my app loads multiple of the same files and I located it back to the xhr request done in the cq-prolyfill lib. I looked througout the code to see if I could locate where the problem lies but I can't pin it down exactly. Do you have any pointers where I might look for debugging and all?
It's an app written in Angular.
Sorry for the vague description, don't really know how to explain this problem.
Thanks!
Is there a particular reason why attribute mutations (e.g. class
being changed by frameworks like Aurelia or AngularJS) aren't obeserved by the script?
see https://github.com/MicheleBertoli/css-in-js
I'm following element queries
and container queries
for quite some time now and think they will be part of the future for sure. Meanwhile, i also think the future of css will be js in one way or another, so i wonder if it's possible to use a container query ponyfill :-) with for example jss, and especially because in jss or in general through javascript, all CSS Stylesheets can be updated during runtime by interacting with document.styleSheets
I just checked out your Element query. I'm using this library on top of Drupal 8.
I found out that you are not handling CSS Import when parsing rules.
After checking in your code, I found a solution that fixes it.
function parseRule(rule) {
// Handle rule type#3 – CSS Import
if (rule.type === 3) {
var importedRules = rule.styleSheet.cssRules;
if (importedRules) {
for (var i = 0; i < importedRules.length; i++) {
parseRule(importedRules[i]);
}
}
}
}
Today i have tested your CQ Prolyfill, also the Lightness Check and i'm a little bit irritated because the Results - "its bright". With black and white Background anytime the same result.
.test {
background-color: black; }
.test__inner {
color: #ccc; }
.test:container("background-color lightness > 50%") .test__inner:before {
content: 'its bright'; }
.test:container("background-color lightness <= 49%") .test__inner:before {
content: 'its dark'; }
I added a Test with a Single Condition with a Color (HSB Model with 30% Brightness)
.test {
background-color: #1a364d; }
.test__inner {
color: #ccc; }
.test:container("background-color lightness > 50%") .test__inner:before {
content: 'its bright'; }
Anytime "its bright". When i switch the Condition
.test:container("background-color lightness < 50%") .test__inner:before {
content: 'its bright'; }
I can set the Number from 0 to 100%, no results.
I'm loving this 'prolyfill' but I'm encountering some issues with Angular directives (atleast, I'm guessing it's that).
Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
It's line 1059 that's throwing this error. I know this isn't completely relevant for this library but I was wondering if somebody found a workaround for this.
Best,
Tom
To elaborate, it would be great to completely avoid the fetching & parsing hit at runtime by creating a module (and/or webpack loader) that could do the rule parsing and return the mapping of available queries as JSON. I'm still noodling on how this might work given people generally produce CSS from some other format (less, sass, etc), but if it's plausible then the resulting benefit of having no runtime parse overhead would be pretty great.
Examples:
.child:container(font-size > 20px) {
font-size: 0.8em;
}
.child:container(background-color lightness < 30%) {
color: white;
}
.child:container(background-color hue > 60deg < 120deg):container(background-color lightness > 20% < 80%) {
}
.child:container(text-align = right) {
}
.child:container(opacity < 0.25) {
}
.child:container(pointer-events = none) {
}
.child:container(white-space = nowrap) {
}
.child:container(--foo = bar) {
}
.swap-visibility:container(visibility = hidden) {
visibility: visible;
}
.swap-visibility:container(visibility != hidden) {
visibility: hidden;
}
Hi there,
first of all: great project! Thanks!
Now my issue/question:
If the parent element has a width defined in percent, the getContainer() function returns a wrong element. If I am right, it should return the element itself, because the width has a fixed definition (isIntrinsicSize() returns false). So there should be the following check after the isFixedSize check:
else if (!isIntrinsicSize(element, prop)) {
cache[prop] = element;
}
Or am I wrong and the check is missing with a reason, and if yes, what reason?
Thanks, best regards, Pascal
If possible we should add support for attribute selectors like:
.element[data-cq~="width>99px"] {}
This makes the prolyfill faster for people that cannot use a CSS preprocessor.
I'm using Webpack and the Sass mixin, and I'm having files get reloaded 6+ times. Am I wrong that passing postcss
shouldn't reload external files at all?
I'm loading the polyfill like so:
var cq = require('cq-prolyfill')({ postcss: true });
And then calling
cq.reevaluate(false);
Is there an extra step I need to do, or something I'm missing?
I'm trying to create color and background container queries, but it doesn't work. What am I doing wrong?
.element:container(color = green) {
}
.element:container(background-color = green) {
}
Add support for new CSS layout modules and new display values like:
{
display: contents;
display: flex;
display: inline-flex;
display: grid;
display: inline-grid;
display: run-in;
}
Don’t forget the vendor-prefixed variations.
This would allow people to limit fetching of external stylesheets (for parsing) to a known set.
The Media Queries Level 4 draft allows a slightly different syntax for media features than cq-prolyfill. Using the same syntax as media queries would be more consistent and thus easier to reason about for CSS authors.
The current syntax would still be valid for simple queries e.g. width > 100px
, but more variants would be possible like min-width: 100px
, text-align: right
or even 100px < width
.
Queries with two comparisons would change from width > 100px < 200px
to the range syntax of the specification 100px < width < 200px
or 200px > width > 100px
.
The color filters would be changed to a suffix so color lightness <= 20%
gets color-lightness <= 20%
or max-color-lightness: 20%
.
The biggest difference is that media queries don’t allow the not-equal (!=
) comparision, so :container(text-align != right)
would become :not(:container(text-align = right))
or :not(:container(text-align: right))
.
Are the benefits of this enough to justify another change to the syntax of cq-prolyfill? (+1 or -1 comments are welcome too :)
A PostCSS plugin could take care of the selector escaping to improve the client side JavaScript performance.
I believe this is more an issue with react-css-modules clobbering the class name in the css file, but I thought I'd place it here so some collaboration could take place and maybe a better solution could be found.
I think we should remove support for IE 9 and 10 and also look for other code that can be removed by raising the supported browser versions.
Please vote via 👍 or 👎 reactions.
We just figured out, that this is not longer working in Chrome.
Even the Demo is not working.
Any suggestions how to get this working again?
I was wondering why my sourcemaps isn't working, since the style is being inlined in the head but i haven't done that.
Turn out the cq-prolyfill did that, is there any way to still use sourcemap while using cq-prolyfill.
Hi! Are sizing keywords like max-content
, min-content
, column-width
, etc. supported in container queries? (Two questions, really: are they supported in cq-prolyfill, and, to your knowledge, are they possible/expected in the eventual CSS spec?)
In this example .child
should not turn red:
.parent {
float: left;
max-width: 50px;
}
.child:container(width > 100px) {
color: red;
}
If a parent element between the container and the element has a max-width
set, the containers width should be capped at that value.
Some reactions on twitter pointed out that supporting queries for all properties may not be the best idea.
Parent elements using width: fit-content
should be skipped for example. Currently they can result in the circularity issue.
Use the new ResizeObserver API to watch the size of container elements that have width or height queries attached.
The Sass compiler has problems with the syntax and throws an invalid top-level expression
error.
A possible fix could be to allow quotes for the comparison part like :container("width <= 100px")
or get Sass to escape the container query like .\:container\(width\<\=100px\)
.
Source: https://twitter.com/alanontheweb/status/675223579705872384
Hello, can I use this as element query? I Just realize that this library will watch the container of asigned element, and add class to it.
But what if i want to watch the element itself, not the container? So for example i want to change the style when the width of element is on certain size.
Love where you're going with this.
Would you say this is more experimental? Or is there confidence in it being production ready?
I must say that this is very impressive and exciting tech. Thank you for open sourcing.
I did run into a small syntax issue. I'm using SASS to precompile my stylesheets and it doesn't like your new syntax. Eg:
:container( margin-top = 8px ){}
gulp sass, which is just a wrapper of node sass, will throw a syntax error. It doesn't like to use the "=" operator.
I escaped it as follows:
&:container( margin-top \= 8px ){
and edited the regex to match ""
var SELECTOR_REGEXP = /\.?:container\(\s*"?\s*[a-z-]+(?:(?:\s+|\|)[a-z-]+)?\s*(?:[<>!=\\]=?)\s*[^)]+\s*\)/gi;
However this still does not match the actual element or apply any of the required styles.
What are your thoughts?
Support complex selectors like .fo\,o[attr="val,u\"e"]
, see cq-prolyfill.js:349-358.
With the next major version we should turn the postcss
configuration option on by default or rename it to preprocess
and invert the value.
The goal of this change is to make the use in production more straight forward and that the default case is the one with better performance.
Maybe we should also add a loadCorsStylesheets
configuration option that defaults to false, so that we don’t fetch any stylesheets by default (in modern browsers). Legacy browsers would still need an ajax call for stylesheets that have the crossorigin
attribute set.
So I'm using Gulp with the popular gulp-concat package. It allows me to compile and minify a collection of Javascript files into one minified file.
Even if I minify and include just the cq-prolyfill.js file; the script doesn't work. No errors, it just doesn't work. Your own latest release cq-prolyfill.min.js works perfectly.
Anyway, taking the uncompressed file into JSHint, revealed a large amount of these warnings:
Misleading line break before '&&'; readers may interpret this as an expression boundary.
I went through and removed those line-breaks, and gulp-concat minified it like a charm. I think it's fair to say gulp-concat has an issue with certain line-breaks.
So, you can either make your code a little less legible and remove those line breaks... or say tough-luck to the millions of gulp-concat users. Then again, maybe I'm the only one in this situation somehow.
Just thought I'd share my findings! Loving CQ-Prolyfill!
Version 0.3.2 without linebreaks: cq-prolyfill-no-linebreaks.js.zip
I think if the script loads fast enough and the page ist not too long it should be possible to avoid a flash of unstyled content.
We would need an event that fires directly before the first render, maybe a requestAnimationFrame
? In the initial rendering case we should also try to run the process synchronously so that we don’t miss the first render.
See also https://twitter.com/etportis/status/867023541614460928
/cc @eeeps
Hi,
I try to use this component with react, css-modules and server-side rendering. But server side rendering won't work because of this error :
/home/xxxx/Development/galaxy/node_modules/cq-prolyfill/cq-prolyfill.js:1440
})(window, document);
^
ReferenceError: window is not defined
Any workaround ?
Thanks
Currently I use CSS Grids in combination with the Prolyfill. IE10 - Edge 15 in the old CSS specification. The problem is that the Polyfill behaves incorrectly with elements within the CSS grid layout. IE10 to Edge 15 simply trigger the conditions, it looks like the Polyfill uses the dimensions of the container outside the CSS grid.
If I switch to Flexbox for testing, the Prolyfill behaves regularly.
Hello,
the source maps do not work because the styles are written directly into the head area. It would be nice if you could change this, so we are able to work with sourcemaps.
Thanks in advance,
Burgart
How can I use this with Radium?
I am using the post css plugin along with the popular webpack css modules. This is preventing cq-prolyfill from being able to keep the classnames.
I've investigated the source of the issue and I think it's because the :container(...) is being read as a class name by css modules and being converted to a garbagey string.
I have not been able to find a work around.
getContainer()
should skip parent nodes of position: absolute
elements until it finds a “positioned” parent. For position: fixed
it should skip directly to the viewport.
Hi there,
Here we use SystemJS (with JSPM) as module loader to load ES6 modules.
SystemJS also supports CommonJS and AMD modules but it's not working with cq-prolyfill.
The code I have is very simple :
import cq from 'cq-prolyfill';
cq.reevaluate(false, function() {
// Do something after all elements were updated
});
The JS file for cq-prolyfill is well loaded by the browser but the cq variable does not contain the reevaluate method. So it seems that the export is not properly done.
Do you have an idea of what could be the problem?
It would be really interesting cq-prolyfill can be loaded with SystemJS and not just with Browserify or Webpack.
In Safari 10.1.1 (12603.2.4) with disabled cache I have a page with async scripts loading after domready event and after that cq rules doesn't applies to elements untill window resize or it works when i manually call function window.cqApi.reevaluate() in browsers console.
When cache is enabled in Safari all works fine.
In Chrome and Firefox with disabled cache all works fine.
Use getComputedStyleMap
(element).get(prop)
in getOriginalStyle()
if available and skip buildStyleCache()
. This will be a big performance improvement for browsers with Houdini support.
E.g. for the initial frame cq-prolyfill may run 4 times (initial, MutationObserver, domready and load).
These calls should be scheduled and executed by an animation frame callback. This change must not create a FOUC problem.
The mixins.scss
file is missing from the npm package. This means it's not possible to use the package as documented.
I think the problem is caused by the files
property of the package.json
file.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.