satori icon indicating copy to clipboard operation
satori copied to clipboard

Throw an error when CSS property or Tailwind API is not supported

Open styfle opened this issue 2 years ago • 7 comments

We know which properties are supported (the list is in the readme) so we should throw an error when a CSS property isn't implemented so its clear to the user.

Here's the exhaustive list:

https://developer.mozilla.org/en-US/docs/Web/CSS/Reference

Details
["--*","-webkit-line-clamp","accent-color",":active","additive-symbols (@counter-style)","::after (:after)","align-content","align-items","align-self","align-tracks","all","","","","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timeline","animation-timing-function","@annotation","annotation()",":any-link","appearance","ascent-override (@font-face)","aspect-ratio","attr()","::backdrop","backdrop-filter","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-position-x","background-position-y","background-repeat","background-size","","::before (:before)",":blank","bleed (@page)","","block-overflow","block-size","blur()","border","border-block","border-block-color","border-block-end","border-block-end-color","border-block-end-style","border-block-end-width","border-block-start","border-block-start-color","border-block-start-style","border-block-start-width","border-block-style","border-block-width","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-end-end-radius","border-end-start-radius","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-inline","border-inline-color","border-inline-end","border-inline-end-color","border-inline-end-style","border-inline-end-width","border-inline-start","border-inline-start-color","border-inline-start-style","border-inline-start-width","border-inline-style","border-inline-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-start-end-radius","border-start-start-radius","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","@bottom-center","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","brightness()","calc()","caption-side","caret-color","@character-variant","character-variant()","@charset",":checked","circle()","clamp()","clear","clip","clip-path","","color","color-scheme","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","conic-gradient()","contain","content","content-visibility","contrast()","","counter-increment","counter-reset","counter-set","@counter-style","counters()","cross-fade()","cubic-bezier()","::cue","::cue-region",":current","cursor","","length#cap","length#ch","length#cm","angle#deg",":default",":defined","descent-override (@font-face)","",":dir","direction",":disabled","display","","","","","","","drop-shadow()","resolution#dpcm","resolution#dpi","resolution#dppx","element()","ellipse()",":empty","empty-cells",":enabled","env()","length#em","length#ex","fallback (@counter-style)","filter","",":first",":first-child","::first-letter (:first-letter)","::first-line (:first-line)",":first-of-type","fit-content()","","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","flex_value#fr","float",":focus",":focus-visible",":focus-within","font","font-display (@font-face)","@font-face","font-family","font-family (@font-face)","font-feature-settings","font-feature-settings (@font-face)","@font-feature-values","font-kerning","font-language-override","font-optical-sizing","font-size","font-size-adjust","font-stretch","font-stretch (@font-face)","font-style","font-style (@font-face)","font-synthesis","font-variant","font-variant (@font-face)","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-variation-settings","font-variation-settings (@font-face)","font-weight","font-weight (@font-face)","forced-color-adjust","format()","","",":fullscreen",":future","angle#grad","gap","","::grammar-error","grayscale()","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","frequency#Hz","hanging-punctuation",":has","height","height (@viewport)","@historical-forms",":host()",":host-context()",":hover","hsl()","hsla()","hue-rotate()","hwb()","hyphenate-character","hyphens","","","image()","image-orientation","image-rendering","image-resolution","image-set()","@import",":in-range",":indeterminate","inherit","inherits (@property)","initial","initial-letter","initial-letter-align","initial-value (@property)","inline-size","input-security","inset","inset()","inset-block","inset-block-end","inset-block-start","inset-inline","inset-inline-end","inset-inline-start","",":invalid","invert()",":is","isolation","length#ic","length#in","justify-content","justify-items","justify-self","justify-tracks","frequency#kHz","@keyframes",":lang",":last-child",":last-of-type","@layer","layer()","layer() (@import)","leader()",":left","left","@left-bottom","","","letter-spacing","line-break","line-clamp","line-gap-override (@font-face)","line-height","line-height-step","linear-gradient()",":link","list-style","list-style-image","list-style-position","list-style-type","local()",":local-link","length#mm","margin","margin-block","margin-block-end","margin-block-start","margin-bottom","margin-inline","margin-inline-end","margin-inline-start","margin-left","margin-right","margin-top","margin-trim","::marker","marks (@page)","mask","mask-border","mask-border-mode","mask-border-outset","mask-border-repeat","mask-border-slice","mask-border-source","mask-border-width","mask-clip","mask-composite","mask-image","mask-mode","mask-origin","mask-position","mask-repeat","mask-size","mask-type","masonry-auto-flow","math-style","matrix()","matrix3d()","max()","max-block-size","max-height","max-height (@viewport)","max-inline-size","max-lines","max-width","max-width (@viewport)","max-zoom (@viewport)","@media","min()","min-block-size","min-height","min-height (@viewport)","min-inline-size","min-width","min-width (@viewport)","min-zoom (@viewport)","minmax()","mix-blend-mode","time#ms","@namespace","negative (@counter-style)",":not",":nth-child",":nth-col",":nth-last-child",":nth-last-col",":nth-last-of-type",":nth-of-type","","object-fit","object-position","offset","offset-anchor","offset-distance","offset-path","offset-position","offset-rotate",":only-child",":only-of-type","opacity","opacity()",":optional","order","orientation (@viewport)","@ornaments","ornaments()","orphans",":out-of-range","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-anchor","overflow-block","overflow-clip-margin","overflow-inline","overflow-wrap","overflow-x","overflow-y","overscroll-behavior","overscroll-behavior-block","overscroll-behavior-inline","overscroll-behavior-x","overscroll-behavior-y","Pseudo-classes","Pseudo-elements","length#pc","length#pt","length#px","pad (@counter-style)","padding","padding-block","padding-block-end","padding-block-start","padding-bottom","padding-inline","padding-inline-end","padding-inline-start","padding-left","padding-right","padding-top","@page","page-break-after","page-break-before","page-break-inside","paint()","paint-order","::part",":past","path()",":paused","","perspective","perspective()","perspective-origin",":picture-in-picture","place-content","place-items","place-self","::placeholder",":placeholder-shown",":playing","pointer-events","polygon()","","position","prefix (@counter-style)","print-color-adjust","@property","length#Q","quotes","angle#rad","length#rem","radial-gradient()","range (@counter-style)","",":read-only",":read-write","rect()","repeat()","repeating-linear-gradient()","repeating-radial-gradient()",":required","resize","","revert","rgb()","rgba()",":right","right","@right-bottom",":root","rotate","rotate()","rotate3d()","rotateX()","rotateY()","rotateZ()","row-gap","ruby-align","ruby-merge","ruby-position","saturate()","scale","scale()","scale3d()","scaleX()","scaleY()","scaleZ()",":scope","scroll-behavior","scroll-margin","scroll-margin-block","scroll-margin-block-end","scroll-margin-block-start","scroll-margin-bottom","scroll-margin-inline","scroll-margin-inline-end","scroll-margin-inline-start","scroll-margin-left","scroll-margin-right","scroll-margin-top","scroll-padding","scroll-padding-block","scroll-padding-block-end","scroll-padding-block-start","scroll-padding-bottom","scroll-padding-inline","scroll-padding-inline-end","scroll-padding-inline-start","scroll-padding-left","scroll-padding-right","scroll-padding-top","scroll-snap-align","scroll-snap-stop","scroll-snap-type","@scroll-timeline","scrollbar-color","scrollbar-gutter","scrollbar-width","::selection","selector()","sepia()","","shape-image-threshold","shape-margin","shape-outside","size (@page)","size-adjust (@font-face)","skew()","skewX()","skewY()","::slotted","speak-as (@counter-style)","::spelling-error","src (@font-face)","steps()","","@styleset","styleset()","@stylistic","stylistic()","suffix (@counter-style)","@supports","supports() (@import)","@swash","swash()","symbols (@counter-style)","symbols()","syntax (@property)","system (@counter-style)","time#s","angle#turn","tab-size","table-layout",":target","target-counter()","target-counters()","::target-text","target-text()",":target-within","text-align","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-skip-ink","text-decoration-style","text-decoration-thickness","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-indent","text-justify","text-orientation","text-overflow","text-rendering","text-shadow","text-size-adjust","text-transform","text-underline-offset","text-underline-position","

styfle avatar Mar 17 '22 19:03 styfle

There are some cases where a CSS rule is used for compatibility reason like -webkit-* (the component can be used by both Satori and Next.js). But I think it should be easy to filter them out.

shuding avatar Oct 10 '22 19:10 shuding

This is something I'm running into quite a bit when porting headless chrome OG image templates over to Satori.

The process currently involves lots of trial & error to figure out which properties aren't being handled properly, whereas I'd rather fail-fast — or at least have some prominent warnings to go off of.

transitive-bullshit avatar Oct 14 '22 19:10 transitive-bullshit

@transitive-bullshit Are you using Tailwind mode or just the normal style prop?

shuding avatar Oct 14 '22 22:10 shuding

Just normal style props.

Here's my before & after in case you find it helpful (playground link).

I ended up starting mostly from scratch since there were so many small issues (definitely not a knock; this library is amazing).

Some of the issues I ran into include:

  • flexbox gap property unsupported
  • vmin, vmax, vw, vh units silently unsupported
  • specifying fontSize in em didn't seem to take effect
  • the div must explicitly declare display: flex error came up a lot and is pretty annoying, though I understand the intent behind it since it differs from the normal HTML spec
  • backgroundSize: cover not supported
  • position: absolute doesn't seem to respect it's nearest relative ancestor; e.g,. it always is relative to the document root
  • I had issues getting the local next.js version to display the same as the playground, presumably since they're both using slightly different versions of Satori and the lib is new + updating frequently. Some things like filter: blur(8px) + transform: scale(1.1) would work on the playground but not with the latest version of next.js. Not sure there's much that can be done with these sorts of things aside from just maturing the libs, but I wanted to at least call it out.

None of these issues is a big deal; the real pain is that they're all silent, and the only way to figure out what works & what doesn't is through trial & error.

I know some of the compatibility issues are covered in the readme already and this list goes outside the scope of this issue, but I'm just giving feedback on my experience and hope you find it helpful.

transitive-bullshit avatar Oct 14 '22 22:10 transitive-bullshit

Thanks for the great feedback @transitive-bullshit! I think most of these can be improved in future updates.

shuding avatar Oct 15 '22 14:10 shuding

backgroundSize: contain isn't supported either

rickyzhangca avatar Mar 11 '24 23:03 rickyzhangca

Some of these issues could be fixed by upgrading twnrc. For example v3.6.0 adds support for gap.

zhouzi avatar Mar 14 '24 03:03 zhouzi