1667094240
Satori: Enlightened library to convert HTML and CSS to SVG.
Note
To use it in Next.js, take a look at the Next.js Open Graph Image Generation template →
Satori supports the JSX syntax, which makes it very straightforward to use. Here’s an overview of the basic usage:
// api.jsx
import satori from 'satori'
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
width: 600,
height: 400,
fonts: [
{
name: 'Roboto',
// Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
data: robotoArrayBuffer,
weight: 400,
style: 'normal',
},
],
},
)
Satori will render the element into a 600×400 SVG, and return the SVG string:
'<svg ...><path d="..." fill="black"></path></svg>'
Under the hood, it handles layout calculation, font, typography and more, to generate a SVG that matches the exact same HTML and CSS in a browser.
Satori only accepts JSX elements that are pure and stateless. You can use a subset of HTML elements (see section below), or custom React components, but React APIs such as useState
, useEffect
, dangerouslySetInnerHTML
are not supported.
If you don't have JSX transpiler enabled, you can simply pass React-elements-like objects that have type
, props.children
and props.style
(and other properties too) directly:
await satori(
{
type: 'div',
props: {
children: 'hello, world',
style: { color: 'black' },
},
},
options
)
Satori supports a limited subset of HTML and CSS features, due to its special use cases. In general, only these static and visible elements and properties that are implemented.
For example, the <input>
HTML element, the cursor
CSS property are not in consideration. And you can't use <style>
tags or external resources via <link>
or <script>
.
Also, Satori does not guarantee that the SVG will 100% match the browser-rendered HTML output since Satori implements its own layout engine based on the SVG 1.1 spec.
You can find the list of supported HTML elements and their preset styles here.
You can use <img>
to embed images. However, width
, and height
attributes are recommended to set:
await satori(
<img src="https://picsum.photos/200/300" width={200} height={300} />,
options
)
When using background-image
, the image will be stretched to fit the element by default if you don't specify the size.
If you want to render the generated SVG to another image format such as PNG, it would be better to use base64 encoded image data directly as props.src
so no extra I/O is needed.
Satori uses the same Flexbox layout engine as React Native, and it’s not a complete CSS implementation. However, it supports a subset of the spec that covers most common CSS features:
Property | Property Expanded | Supported Values |
---|---|---|
display | none and flex , default to flex | |
position | relative and absolute , default to relative | |
color | Supported | |
margin | ||
marginTop | Supported | |
marginRight | Supported | |
marginBottom | Supported | |
marginLeft | Supported | |
Position | ||
top | Supported | |
right | Supported | |
bottom | Supported | |
left | Supported | |
Size | ||
width | Supported | |
height | Supported | |
Min & max size | ||
min-width | Supported | |
min-height | Supported | |
max-width | Supported | |
max-height | Supported | |
border | ||
Width (borderWidth , borderTopWidth , ...) | Supported | |
Style (borderStyle , borderTopStyle , ...) | solid and dashed , default to solid | |
Color (borderColor , borderTopColor , ...) | Supported | |
Shorthand (border , borderTop , ...) | Supported, i.e. 1px solid gray | |
borderRadius | ||
borderTopLeftRadius | Supported | |
borderTopRightRadius | Supported | |
borderBottomLeftRadius | Supported | |
borderBottomRightRadius | Supported | |
Shorthand | Supported, i.e. 5px , 50% / 5px | |
Flex | ||
flexDirection | column , row , row-reverse , column-reverse , default to row | |
flexWrap | wrap , nowrap , wrap-reverse , default to wrap | |
flexGrow | Supported | |
flexShrink | Supported | |
flexBasis | Supported except for auto | |
alignItems | Supported | |
alignContent | Supported | |
alignSelf | Supported | |
justifyContent | Supported | |
Font | ||
fontFamily | Supported | |
fontSize | Supported | |
fontWeight | Supported | |
fontStyle | Supported | |
Text | ||
textAlign | start , end , left , right , center , justify , default to start | |
textTransform | none , lowercase , uppercase , capitalize , defaults to none | |
textOverflow | clip , ellipsis , defaults to clip | |
textDecoration | Support line types underline and line-through , and styles dotted , dashed , solid | |
textShadow | Support single shadow | |
lineHeight | Supported | |
letterSpacing | Supported | |
whiteSpace | normal , pre , pre-wrap , pre-line , nowrap , defaults to normal | |
wordBreak | normal , break-all , break-word , keep-all , defaults to normal | |
Background | ||
backgroundColor | Supported, single value | |
backgroundImage | linear-gradient , radial-gradient , url , single value | |
backgroundPosition | Support single value | |
backgroundSize | Support two-value size i.e. `10px 20%` | |
backgroundClip | border-box , text | |
backgroundRepeat | repeat , repeat-x , repeat-y , no-repeat , defaults to repeat | |
transform | ||
Translate (translate , translateX , translateY ) | Supported | |
Rotate | Supported | |
Scale (scale , scaleX , scaleY ) | Supported | |
Skew (skew , skewX , skewY ) | Supported | |
transformOrigin | Support one-value and two-value syntax (both relative and absolute values) | |
objectFit | contain , cover , none , default to none | |
opacity | Supported | |
boxShadow | Supported | |
overflow | visible and hidden , default to visible | |
filter | Supported |
Note:
z-index
support in SVG. Elements that come later in the document will be painted on top.box-sizing
is set to border-box
for all elements.calc
isn't supported.overflow: hidden
and transform
can't be used together.Advanced typography features such as kerning, ligatures and other OpenType features are not currently supported.
RTL languages are not supported either.
Satori currently supports three font formats: TTF, OTF and WOFF. Note that WOFF2 is not supported at the moment. You must specify the font if any text is rendered with Satori, and pass the font data as ArrayBuffer (web) or Buffer (Node.js):
await satori(
<div style={{ fontFamily: 'Inter' }}>Hello</div>,
{
width: 600,
height: 400,
fonts: [
{
name: 'Inter',
data: inter,
weight: 400,
style: 'normal',
},
{
name: 'Inter',
data: interBold,
weight: 700,
style: 'normal',
},
],
}
)
Multiple fonts can be passed to Satori and used in fontFamily
.
To render custom images for specific graphemes, you can use graphemeImages
option to map the grapheme to an image source:
await satori(
<div>Next.js is 🤯!</div>,
{
...,
graphemeImages: {
'🤯': 'https://twemoji.maxcdn.com/v/13.1.0/svg/1f92f.svg',
},
}
)
The image will be resized to the current font-size (both width and height) as a square.
Satori supports dynamically loading emoji images (grapheme pictures) and fonts. The loadAdditionalAsset
function will be called when a text segment is rendered but missing the image or font:
await satori(
<div>👋 你好</div>,
{
// `code` will be the detected language code, `emoji` if it's an Emoji, or `unknown` if not able to tell.
// `segment` will be the content to render.
loadAdditionalAsset: async (code: string, segment: string) => {
if (code === 'emoji') {
// if segment is an emoji
return `data:image/svg+xml;base64,...`
}
// if segment is normal text
return loadFontFromSystem(code)
}
}
)
Satori can be used in browser, Node.js (>= 16), and Web Workers.
By default, Satori depends on asm.js for the browser runtime, and native module in Node.js. However, you can optionally load WASM instead by importing satori/wasm
and provide the initialized WASM module instance of Yoga to Satori:
import satori, { init } from 'satori/wasm'
import initYoga from 'yoga-wasm-web'
const yoga = initYoga(await fetch('/yoga.wasm').then(res => res.arrayBuffer()))
init(yoga)
await satori(...)
By default, Satori renders the text as <path>
in SVG, instead of <text>
. That means it embeds the font path data as inlined information, so succeeding processes (e.g. render the SVG on another platform) don’t need to deal with font files anymore.
You can turn off this behavior by setting embedFonts
to false
, and Satori will use <text>
instead:
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
...,
embedFont: false,
},
)
To draw the bounding box for debugging, you can pass debug: true
as an option:
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
...,
debug: true,
},
)
You can use the Vercel OG Image Playground to test and report bugs of Satori. Please follow our contribution guidelines before opening a Pull Request.
Author: vercel
Source Code: https://github.com/vercel/satori
License: MPL-2.0 license
1667094240
Satori: Enlightened library to convert HTML and CSS to SVG.
Note
To use it in Next.js, take a look at the Next.js Open Graph Image Generation template →
Satori supports the JSX syntax, which makes it very straightforward to use. Here’s an overview of the basic usage:
// api.jsx
import satori from 'satori'
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
width: 600,
height: 400,
fonts: [
{
name: 'Roboto',
// Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
data: robotoArrayBuffer,
weight: 400,
style: 'normal',
},
],
},
)
Satori will render the element into a 600×400 SVG, and return the SVG string:
'<svg ...><path d="..." fill="black"></path></svg>'
Under the hood, it handles layout calculation, font, typography and more, to generate a SVG that matches the exact same HTML and CSS in a browser.
Satori only accepts JSX elements that are pure and stateless. You can use a subset of HTML elements (see section below), or custom React components, but React APIs such as useState
, useEffect
, dangerouslySetInnerHTML
are not supported.
If you don't have JSX transpiler enabled, you can simply pass React-elements-like objects that have type
, props.children
and props.style
(and other properties too) directly:
await satori(
{
type: 'div',
props: {
children: 'hello, world',
style: { color: 'black' },
},
},
options
)
Satori supports a limited subset of HTML and CSS features, due to its special use cases. In general, only these static and visible elements and properties that are implemented.
For example, the <input>
HTML element, the cursor
CSS property are not in consideration. And you can't use <style>
tags or external resources via <link>
or <script>
.
Also, Satori does not guarantee that the SVG will 100% match the browser-rendered HTML output since Satori implements its own layout engine based on the SVG 1.1 spec.
You can find the list of supported HTML elements and their preset styles here.
You can use <img>
to embed images. However, width
, and height
attributes are recommended to set:
await satori(
<img src="https://picsum.photos/200/300" width={200} height={300} />,
options
)
When using background-image
, the image will be stretched to fit the element by default if you don't specify the size.
If you want to render the generated SVG to another image format such as PNG, it would be better to use base64 encoded image data directly as props.src
so no extra I/O is needed.
Satori uses the same Flexbox layout engine as React Native, and it’s not a complete CSS implementation. However, it supports a subset of the spec that covers most common CSS features:
Property | Property Expanded | Supported Values |
---|---|---|
display | none and flex , default to flex | |
position | relative and absolute , default to relative | |
color | Supported | |
margin | ||
marginTop | Supported | |
marginRight | Supported | |
marginBottom | Supported | |
marginLeft | Supported | |
Position | ||
top | Supported | |
right | Supported | |
bottom | Supported | |
left | Supported | |
Size | ||
width | Supported | |
height | Supported | |
Min & max size | ||
min-width | Supported | |
min-height | Supported | |
max-width | Supported | |
max-height | Supported | |
border | ||
Width (borderWidth , borderTopWidth , ...) | Supported | |
Style (borderStyle , borderTopStyle , ...) | solid and dashed , default to solid | |
Color (borderColor , borderTopColor , ...) | Supported | |
Shorthand (border , borderTop , ...) | Supported, i.e. 1px solid gray | |
borderRadius | ||
borderTopLeftRadius | Supported | |
borderTopRightRadius | Supported | |
borderBottomLeftRadius | Supported | |
borderBottomRightRadius | Supported | |
Shorthand | Supported, i.e. 5px , 50% / 5px | |
Flex | ||
flexDirection | column , row , row-reverse , column-reverse , default to row | |
flexWrap | wrap , nowrap , wrap-reverse , default to wrap | |
flexGrow | Supported | |
flexShrink | Supported | |
flexBasis | Supported except for auto | |
alignItems | Supported | |
alignContent | Supported | |
alignSelf | Supported | |
justifyContent | Supported | |
Font | ||
fontFamily | Supported | |
fontSize | Supported | |
fontWeight | Supported | |
fontStyle | Supported | |
Text | ||
textAlign | start , end , left , right , center , justify , default to start | |
textTransform | none , lowercase , uppercase , capitalize , defaults to none | |
textOverflow | clip , ellipsis , defaults to clip | |
textDecoration | Support line types underline and line-through , and styles dotted , dashed , solid | |
textShadow | Support single shadow | |
lineHeight | Supported | |
letterSpacing | Supported | |
whiteSpace | normal , pre , pre-wrap , pre-line , nowrap , defaults to normal | |
wordBreak | normal , break-all , break-word , keep-all , defaults to normal | |
Background | ||
backgroundColor | Supported, single value | |
backgroundImage | linear-gradient , radial-gradient , url , single value | |
backgroundPosition | Support single value | |
backgroundSize | Support two-value size i.e. `10px 20%` | |
backgroundClip | border-box , text | |
backgroundRepeat | repeat , repeat-x , repeat-y , no-repeat , defaults to repeat | |
transform | ||
Translate (translate , translateX , translateY ) | Supported | |
Rotate | Supported | |
Scale (scale , scaleX , scaleY ) | Supported | |
Skew (skew , skewX , skewY ) | Supported | |
transformOrigin | Support one-value and two-value syntax (both relative and absolute values) | |
objectFit | contain , cover , none , default to none | |
opacity | Supported | |
boxShadow | Supported | |
overflow | visible and hidden , default to visible | |
filter | Supported |
Note:
z-index
support in SVG. Elements that come later in the document will be painted on top.box-sizing
is set to border-box
for all elements.calc
isn't supported.overflow: hidden
and transform
can't be used together.Advanced typography features such as kerning, ligatures and other OpenType features are not currently supported.
RTL languages are not supported either.
Satori currently supports three font formats: TTF, OTF and WOFF. Note that WOFF2 is not supported at the moment. You must specify the font if any text is rendered with Satori, and pass the font data as ArrayBuffer (web) or Buffer (Node.js):
await satori(
<div style={{ fontFamily: 'Inter' }}>Hello</div>,
{
width: 600,
height: 400,
fonts: [
{
name: 'Inter',
data: inter,
weight: 400,
style: 'normal',
},
{
name: 'Inter',
data: interBold,
weight: 700,
style: 'normal',
},
],
}
)
Multiple fonts can be passed to Satori and used in fontFamily
.
To render custom images for specific graphemes, you can use graphemeImages
option to map the grapheme to an image source:
await satori(
<div>Next.js is 🤯!</div>,
{
...,
graphemeImages: {
'🤯': 'https://twemoji.maxcdn.com/v/13.1.0/svg/1f92f.svg',
},
}
)
The image will be resized to the current font-size (both width and height) as a square.
Satori supports dynamically loading emoji images (grapheme pictures) and fonts. The loadAdditionalAsset
function will be called when a text segment is rendered but missing the image or font:
await satori(
<div>👋 你好</div>,
{
// `code` will be the detected language code, `emoji` if it's an Emoji, or `unknown` if not able to tell.
// `segment` will be the content to render.
loadAdditionalAsset: async (code: string, segment: string) => {
if (code === 'emoji') {
// if segment is an emoji
return `data:image/svg+xml;base64,...`
}
// if segment is normal text
return loadFontFromSystem(code)
}
}
)
Satori can be used in browser, Node.js (>= 16), and Web Workers.
By default, Satori depends on asm.js for the browser runtime, and native module in Node.js. However, you can optionally load WASM instead by importing satori/wasm
and provide the initialized WASM module instance of Yoga to Satori:
import satori, { init } from 'satori/wasm'
import initYoga from 'yoga-wasm-web'
const yoga = initYoga(await fetch('/yoga.wasm').then(res => res.arrayBuffer()))
init(yoga)
await satori(...)
By default, Satori renders the text as <path>
in SVG, instead of <text>
. That means it embeds the font path data as inlined information, so succeeding processes (e.g. render the SVG on another platform) don’t need to deal with font files anymore.
You can turn off this behavior by setting embedFonts
to false
, and Satori will use <text>
instead:
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
...,
embedFont: false,
},
)
To draw the bounding box for debugging, you can pass debug: true
as an option:
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
...,
debug: true,
},
)
You can use the Vercel OG Image Playground to test and report bugs of Satori. Please follow our contribution guidelines before opening a Pull Request.
Author: vercel
Source Code: https://github.com/vercel/satori
License: MPL-2.0 license
1618667723
how to create a Sidebar Menu using HTML and CSS only. Previously I have shared a Responsive Navigation Menu Bar using HTML & CSS only, now it’s time to create a Side Navigation Menu Bar that slides from the left or right side.
#sidebar menu using html css #side navigation menu html css #css side navigation menu bar #,pure css sidebar menu #side menu bar html css #side menu bar using html css
1617789060
The prospect of learning HTML can seem confusing at first: where to begin, what to learn, the best ways to learn — it can be difficult to get started. In this article, we’ll explore the best ways for learning HTML to assist you on your programming journey.
Hypertext Markup Language (HTML) is the standard markup language for documents meant to be displayed in a web browser. Along with Cascading Style Sheets (CSS) and JavaScript, HTML completes the trio of essential tools used in creating modern web documents.
HTML provides the structure of a webpage, from the header and footer sections to paragraphs of text, videos, and images. CSS allows you to set the visual properties of different HTML elements, like changing colors, setting the order of blocks on the screen, and defining which elements to display. JavaScript automates changes to HTML and CSS, for example, making the font larger in a paragraph when a user clicks a button on the page.
#html #html-css #html-fundamentals #learning-html #html-css-basics #html-templates
1621077133
Hello Readers, welcome to my other blog, today in this blog I’m going to create a Responsive Footer by using HTML & CSS only. Earlier I have shared How to create a Responsive Navigation Menu and now it’s time to create a footer section.
As you can see on the image which is given on the webpage. There are various important topics there like About us, Our services and subscribes, some social media icons, and a contact section for easy connection. I want to tell you that it is fully responsive. Responsive means this program is fit in all screen devices like tablet, small screen laptop, or mobile devices.
#responsive footer html css template #footer design in html #simple footer html css code #simple responsive footer codepen #responsive footer code in html and css #responsive footer html css codepen
1603188000
The other day one of our students asked about possibility of having a CSS cheatsheet to help to decide on the best suited approach when doing this or that layout.
This evolved into the idea of making a visual CSS cheatsheet with all (most) of the common patterns we see everyday and one of the best possible conceptual implementation for them.
In the end any layout could and should be split into parts/blocks and we see every block separately.
Here is our first take on that and we would be happy to keep extending it to help us all.
Please, send you suggestions in the comments in community or via gitlab for the repeated CSS patterns with your favourite implementation for that so that we will all together make this as useful as it can be.
#css #css3 #cascading-style-sheets #web-development #html-css #css-grids #learning-css #html-css-basics