Links, images and media
A page is more than text: it links to other pages, shows pictures, plays sound and video and draws shapes. This lesson covers the elements for all of that, and the attributes that make them fast, accessible and safe.
Links
A link takes the reader somewhere. Its url is required and its content is the text the reader clicks. The address can point to another site, to a file next to your page, or to a place on the same page: a url that starts with # scrolls to the element whose id is the rest of it. Two more kinds are worth knowing. mailto: opens the mail program with a new message, and tel: offers to call the number on a phone.
page:
title = "Links"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" line height = 1.8 end
paragraph:
content = "Read the "
link: url = "#rules" content = "house rules" end
span: content = " first, then write to " end
link: url = "mailto:club@example.com" content = "the club" end
span: content = " or call " end
link: url = "tel:+15550100" content = "555 0100" end
span: content = "." end
end
paragraph:
link: url = "https://example.com/guide" target = "new" rel = "noopener" content = "The full guide (new tab)" end
end
paragraph:
link:
url = "maps/garden.pdf"
download = "garden-map.pdf"
type = "application/pdf"
hreflang = "en"
content = "Download the garden map"
end
end
heading: id = "rules" size = 2 content = "House rules" end
paragraph: content = "Keep the gate closed. Water the beds in the morning." end
endThe attributes in the example each do one job. target says where the page opens: new is a new tab (the HTML word is _blank, and both work), same is the current tab, and parent and top matter only inside frames. rel describes the relationship to the target. With noopener the new tab cannot reach back to your page, which matters for a link to a site you do not control, and nofollow asks search engines not to count the link. download makes the browser save the file instead of showing it, and its value is the suggested file name. type is the kind of file you expect and hreflang the language of the target page. Both are hints. ping lists addresses that are told when someone follows the link, and referrer policy controls how much of your address the target site is given.
Write link text that makes sense on its own, such as "the house rules", and not "click here": screen readers can read out a list of all the links on a page. A link cannot contain another link or a button, and the compiler reports an error (E116) if you try. It also refuses addresses like javascript: that would run code (E018).
Images
image shows a picture. The url is required. The text description is the alt attribute, and content sets the same attribute, so you can write whichever reads better. The description is what a screen reader says and what the browser shows when the file cannot be loaded. Describe what the picture tells, not what it is: "A red kite over green hills", not "image". If the picture is only decoration, give it an empty description, alt = "", and screen readers will skip it. When you give neither, the compiler writes the empty one for you.
page:
title = "Images"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
paragraph: content = "A photo with a description:" end
image:
content = "A red kite flying over green hills"
width = 160
height = 100
loading = lazy
decoding = async
url = "data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%20160%20100%27%20width=%27160%27%20height=%27100%27%3E%3Crect%20width=%27160%27%20height=%27100%27%20fill=%27%23bae6fd%27/%3E%3Cpath%20d=%27M0%20100%20Q50%2055%20100%2085%20T160%2075%20V100Z%27%20fill=%27%2316a34a%27/%3E%3Cpath%20d=%27M110%2012%20L130%2032%20L110%2052%20L90%2032Z%27%20fill=%27%23dc2626%27/%3E%3Cpath%20d=%27M110%2052%20Q100%2070%20112%2082%27%20stroke=%27%23475569%27%20fill=%27none%27/%3E%3Ctext%20x=%276%27%20y=%2714%27%20font-size=%2711%27%20font-family=%27sans-serif%27%20fill=%27%230c4a6e%27%3E%3C/text%3E%3C/svg%3E"
end
paragraph: content = "A decorative picture has an empty description:" end
image: alt = "" width = 80 height = 50 url = "data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%20160%20100%27%20width=%27160%27%20height=%27100%27%3E%3Crect%20width=%27160%27%20height=%27100%27%20fill=%27%23bae6fd%27/%3E%3Cpath%20d=%27M0%20100%20Q50%2055%20100%2085%20T160%2075%20V100Z%27%20fill=%27%2316a34a%27/%3E%3Cpath%20d=%27M110%2012%20L130%2032%20L110%2052%20L90%2032Z%27%20fill=%27%23dc2626%27/%3E%3Cpath%20d=%27M110%2052%20Q100%2070%20112%2082%27%20stroke=%27%23475569%27%20fill=%27none%27/%3E%3Ctext%20x=%276%27%20y=%2714%27%20font-size=%2711%27%20font-family=%27sans-serif%27%20fill=%27%230c4a6e%27%3E%3C/text%3E%3C/svg%3E" end
paragraph: content = "A picture that fails to load shows its description instead:" end
image: content = "Photo of the garden gate" width = 200 height = 40 url = "missing/gate.jpg" end
endAlways set width and height to the real size of the file. The browser then reserves the space before the picture arrives, and the text below does not jump when it does. loading = lazy tells the browser to fetch the picture only when the reader scrolls near it, which saves data for pictures far down the page. Leave the first picture on the page at the default, eager. decoding chooses whether decoding may happen off to the side (async) and fetch priority lets you mark the most important picture as high.
The long text in url is a data address: the whole picture written as text, so the example needs no extra file. The compiler accepts data addresses for images, audio, video and fonts and refuses the rest. In your own pages you will usually write a file name or an address instead.
One picture, many sizes
A phone and a large monitor do not need the same file. srcset lists several versions of the picture, and the browser picks one. There are two ways to describe them. With density descriptors, as in the example, each file is marked 1x, 2x and so on, and the browser chooses by the pixel density of the screen. With width descriptors, photo-480.jpg 480w, photo-960.jpg 960w, each file is marked with its real width, and sizes tells the browser how wide the picture will be drawn, for example sizes = "(max-width: 600px) 100vw, 600px". The url stays as the fallback for browsers that do not know srcset.
import dom
page:
title = "Image sets"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" line height = 1.6 end
image:
id = "swatch"
content = "A color swatch (the files do not exist here)"
width = 160
height = 100
srcset = "swatch.png 1x, swatch-2x.png 2x"
url = "swatch.png"
error = (): dom.SetText(dom.ById("chosen"), "The browser chose: " + dom.GetStr(dom.ById("swatch"), "currentSrc")) end
end
paragraph: id = "chosen" content = "Waiting for the browser." end
endThe files in this example do not exist, so the browser draws nothing. It still decides which one it would load, and the function named after error = runs when the image cannot be loaded and reads that choice from the currentSrc property of the image. On a screen with twice the pixels you would read the second name.
When the versions are not the same picture, for example a wide crop for a desktop and a tall one for a phone, use picture. Inside it, each source has a media condition and a srcset, and the browser takes the first source whose condition is true. The last child is always a normal image: it is the fallback and it carries the description. A source can also have a type, such as image/webp, so that browsers that do not know the format skip it.
page:
title = "Picture"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
picture:
source: media = "(min-width: 500px)" srcset = "data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%20320%20120%27%20width=%27320%27%20height=%27120%27%3E%3Crect%20width=%27320%27%20height=%27120%27%20fill=%27%23bae6fd%27/%3E%3Ccircle%20cx=%27260%27%20cy=%2736%27%20r=%2720%27%20fill=%27%23facc15%27/%3E%3Cpath%20d=%27M0%20120%20Q90%2060%20170%20100%20T320%2085%20V120Z%27%20fill=%27%2316a34a%27/%3E%3Ctext%20x=%278%27%20y=%2716%27%20font-size=%2712%27%20font-family=%27sans-serif%27%20fill=%27%230c4a6e%27%3Ewide%3C/text%3E%3C/svg%3E" end
image:
content = "Green hills under a yellow sun"
url = "data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%20120%20160%27%20width=%27120%27%20height=%27160%27%3E%3Crect%20width=%27120%27%20height=%27160%27%20fill=%27%23bae6fd%27/%3E%3Ccircle%20cx=%2790%27%20cy=%2730%27%20r=%2716%27%20fill=%27%23facc15%27/%3E%3Cpath%20d=%27M0%20160%20Q40%2090%2080%20140%20T120%20120%20V160Z%27%20fill=%27%2316a34a%27/%3E%3Ctext%20x=%278%27%20y=%2716%27%20font-size=%2712%27%20font-family=%27sans-serif%27%20fill=%27%230c4a6e%27%3Enarrow%3C/text%3E%3C/svg%3E"
end
end
paragraph: content = "In a window narrower than 500 pixels you see the tall picture. In a wider window the browser swaps in the wide one." end
endClickable image maps
An image map makes parts of one picture into separate links. The image names the map with use map = "#shapes", and an image map with name = "shapes" holds one area per hotspot. An area has a shape: rect with the coordinates left,top,right,bottom, circle with center-x,center-y,radius, poly with the corners as x1,y1,x2,y2 and so on, or default for everything not covered. The coordinates are in pixels of the picture as it is drawn. An area is a link, so it also takes url, target, rel, download, ping and referrer policy, and it needs alt, the text for people who cannot click the picture.
import dom
page:
title = "Image map"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
image:
content = "A red square next to a blue circle"
use map = "#shapes"
width = 200
height = 100
url = "data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%20200%20100%27%3E%3Crect%20x=%2710%27%20y=%2710%27%20width=%2780%27%20height=%2780%27%20fill=%27%23dc2626%27/%3E%3Ccircle%20cx=%27150%27%20cy=%2750%27%20r=%2740%27%20fill=%27%232563eb%27/%3E%3C/svg%3E"
end
image map: name = "shapes"
area: shape = "rect" coords = "10,10,90,90" alt = "red square" url = "#" click = (): dom.SetText(dom.ById("said"), "You chose the square.") end end
area: shape = "circle" coords = "150,50,40" alt = "blue circle" url = "#" click = (): dom.SetText(dom.ById("said"), "You chose the circle.") end end
end
paragraph: id = "said" content = "Click a shape." end
endIn the example each area also has a click handler that writes into the paragraph. The older ismap attribute is different: on an image inside a link it makes the browser send the clicked coordinates to the server, which then decides what to do.
Audio and video
audio and video play sound and moving pictures without any plug-in. Add controls or the reader gets no way to start them. Give the file with url or, better, with one or more source children, each with its type. The browser takes the first one it can play, so list the best format first. The content text is shown only by a browser that cannot play the element at all.
page:
title = "Audio"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
paragraph: content = "A short beep. Press play:" end
audio:
controls = true
preload = "auto"
content = "Your browser cannot play audio."
source: url = "data:audio/wav;base64,UklGRnwCAABXQVZFZm10IBAAAAABAAEAoA8AAKAPAAABAAgAZGF0YVgCAACAgYSGg3xzbnJ+jpqbjXdhWGF6ma+wmnVRQU1zocPHqXVDKzlpp9Xeunk7HCthpNfiv39AHShbntTjxIZFHyVVmNDjyIxKICNPks3kzZJPIyBKjMjj0JhVJR9FhsTj1J5bKB1AgL/i16RhKxw7ebrg2qpnLxw3c7Xf3LBtMhwybbDc37VzNxwvZ6ra4Lp5OxwrYaTX4r+AQB0oW57U48SGRR8lVZjQ48iMSiAjT5LN5M2STyMgSozI49CYVSUfRYbE49SeWygdQIC/4tekYSscO3m64NqqZy8cN3O139ywbTIcMm2w3N+1czccL2eq2uC6eTscK2Gk1+K/f0AdKFue1OPEhkUfJVWY0OPIjEogI0+SzeTNkk8jIEqMyOPQmFUlH0WGxOPUnlsoHUB/v+LXpGErHDt5uuDaqmcvHDdztd/csG0yHDJtsNzftXM3HC9nqtrgunk7HCthpNfiv39AHShbntTjxIZFHyVVmNDjyIxKICNPks3kzZJPIyBKjMjj0JhVJR9FhsTj1J5bKB1AgL/i16RhKxw7ebrg2qpnLxw3c7Xf3LBtMhwybbDc37VzNxwvZ6ra4Lp5OxwrYaTX4r9/QB0oW57U48SGRR8lVZjQ48iMSiAjT5LN5M2STyMgSozI49CYVSUfRYbE49SeWygdQIC/4NWjYjAjQXq01s+lajssQ3WrzMmlcUU1RnKiwsKkd08+S3CauLujfFhHUG+TrrOgf2BQVm+NpaqcgmhaXXCInKGYhG9jZXKFlJmShHVsbHWCjI+Mg3p1dXqAhYaFgX59fn8=" type = "audio/wav" end
source: url = "beep.mp3" type = "audio/mpeg" end
end
paragraph: content = "The browser plays the first source it understands." end
endpreload says how much to fetch before the reader presses play: none, metadata (only the duration and size) or auto. loop starts again at the end, and muted starts silent. autoplay starts at once, but browsers usually refuse it for sound, so it works reliably only together with muted. A video also has width and height, a poster picture shown until it plays, and plays inline, which stops phones from forcing it to full screen.
page:
title = "Video"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
video:
width = 288
controls = true
autoplay = true
muted = true
loop = true
plays inline = true
preload = "auto"
poster = "data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20viewBox=%270%200%2096%2054%27%3E%3Crect%20width=%2796%27%20height=%2754%27%20fill=%27%23134e4a%27/%3E%3Cpath%20d=%27M40%2018%20L40%2036%20L56%2027Z%27%20fill=%27%23ccfbf1%27/%3E%3C/svg%3E"
content = "Your browser cannot play video."
source: url = "data:video/webm;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEAAAAAAAKAEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHWTbuMU6uEElTDZ1OsggEjTbuMU6uEHFO7a1OsggJq7AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmsCrXsYMPQkBNgIxMYXZmNjIuMy4xMDBXQYxMYXZmNjIuMy4xMDBEiYhAp3AAAAAAABZUrmvIrgEAAAAAAAA/14EBc8WIcy20VtKTuA+cgQAitZyDdW5kiIEAhoVWX1ZQOIOBASPjg4QdzWUA4JCwgWC6gTaagQJVsIRVuYEBElTDZ/tzc59jwIBnyJlFo4dFTkNPREVSRIeMTGF2ZjYyLjMuMTAwc3PWY8CLY8WIcy20VtKTuA9nyKFFo4dFTkNPREVSRIeUTGF2YzYyLjExLjEwMCBsaWJ2cHhnyKFFo4hEVVJBVElPTkSHkzAwOjAwOjAzLjAwMDAwMDAwMAAfQ7Z1QMHngQCjxIEAAIDwAwCdASpgADYAAEcIhYWIhYSIAgICdaoD+AIGwSzT6hw4cOHDhw4ZAP78KdH/iGej1Ml3/6Jr+ia/omv/obgAo5aBAfQA0QEAARAQABgAGFgv9AAIhSgAo5aBA+gA0QEAARAQABgAGFgv9AAIhSgAo5aBBdwA0QEAARAQABgAGFgv9AAIhSgAo5aBB9AA0QEAARAQABgAGFgv9AAIhSgAo5aBCcQA0QEAARAQABgAGFgv9AAIhSgAHFO7a5G7j7OBALeK94EB8YIBo/CBAw==" type = "video/webm" end
track: url = "captions/en.vtt" kind = "subtitles" srclang = "en" label = "English" default = true end
end
endThe track element adds text to a video or an audio file from a WebVTT file. Its kind is subtitles (a translation), captions (speech and sounds, for the deaf), descriptions, chapters or metadata. srclang is the language of the text, label is the name in the menu, and default turns it on at the start. The file in the example does not exist. Real pages need captions for anything that is spoken.
Frames and embedded objects
iframe shows another page inside yours. The page can be an address in url or a short document written in srcdoc. Give it a title so screen readers can announce it, and a width and height. Use loading = lazy for frames far down the page.
page:
title = "Frames"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
paragraph: content = "A separate little page, locked in a sandbox with no scripts:" end
iframe:
title = "Greeting"
width = 320
height = 90
sandbox = ""
loading = lazy
srcdoc = "<body style='font-family:sans-serif'><h3>Inside the frame</h3><p>This page cannot run scripts.</p></body>"
border = "2px solid #0f766e"
end
endA frame can bring a stranger's code into your page, so lock it down with sandbox. An empty sandbox = "" removes every permission: no scripts, no forms, no popups. You then give back only what the frame needs, by listing words such as allow-scripts or allow-forms, separated by spaces. Never combine allow-scripts with allow-same-origin for a page you do not trust. allow is a separate list for browser features, such as "fullscreen; camera", and allow fullscreen permits the full screen button. name gives the frame a name for scripts, and referrer policy works as for links.
embed and object place an external resource, such as a PDF, into the page. Both take a url, a type and a size. embed has no content. object shows its content when the browser cannot display the file, which is the place for a download link, and its form and name attributes connect it to a form. For a PDF, a plain link is often the better choice.
Canvas, SVG and math
canvas is a blank rectangle you draw on with code. Set its size with the width and height attributes, which are the number of pixels of the drawing surface. A size set with CSS only stretches those pixels, and the drawing turns blurry. Drawing itself is done through the dom package. dom.GetContext(canvas, "2d") returns the drawing tool, dom.SetStr sets a property of it such as fillStyle, and dom.Call4 calls one of its methods with four numbers. The example stamps a square where you click: dom.GetNum(e, "offsetX") reads the click position inside the canvas from the event. The two functions above the page, stamp and wipe, are connected to the canvas and the button with click = stamp and click = wipe.
import dom
func stamp(e: i64):
ctx := dom.GetContext(dom.ById("pad"), "2d")
dom.SetStr(ctx, "fillStyle", "#0f766e")
_ := dom.Call4(ctx, "fillRect", dom.GetNum(e, "offsetX") - 10, dom.GetNum(e, "offsetY") - 10, 20, 20)
end
func wipe():
ctx := dom.GetContext(dom.ById("pad"), "2d")
_ := dom.Call4(ctx, "clearRect", 0, 0, 320, 160)
end
page:
title = "Canvas"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
paragraph: content = "Click the canvas to stamp a square." end
canvas: id = "pad" width = 320 height = 160 background = "#f1f5f9" border = "1px solid #94a3b8" click = stamp end
box: margin top = 8
button: content = "Clear" click = wipe end
end
endText inside the canvas element, if you add some, is shown only when the browser cannot draw, and screen readers cannot see into the drawing. Put any information the drawing carries into the page as text as well.
svg draws with shapes that stay sharp at every size. The content of an svg is the markup of its shapes, written as it is, and it is not escaped, so use it only for markup you wrote yourself. view box is the coordinate system inside, four numbers min-x min-y width height, and width and height are the size on the page. The drawing scales to fit. xmlns is only needed when the SVG is a file of its own. math works the same way for mathematics, with MathML in its content: mi for a name, mo for an operator, mn for a number, mfrac for a fraction and msup for a power.
page:
title = "SVG and math"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
svg:
view box = "0 0 120 60"
width = 240
height = 120
content = "<rect width='120' height='60' rx='8' fill='#ccfbf1'/><circle cx='30' cy='30' r='18' fill='#0f766e'/><text x='58' y='36' font-size='16' fill='#134e4a'>Salam</text>"
end
paragraph:
content = "The area of a circle is "
math: content = "<mi>A</mi><mo>=</mo><mi>π</mi><msup><mi>r</mi><mn>2</mn></msup>" end
span: content = "." end
end
endReference: links, images and media
Every element of this lesson is below, with its attributes and a short example. The examples are checked by the compiler, so you can paste any of them inside a page: block. Files such as photo.jpg in the examples are only names, you need your own files to see them. The attributes that every element has, such as id and title, are in the lesson on the head and global attributes.
Links
link (Persian: پیوند; HTML: <a>)
A link (HTML a). The required url is where it goes and the content is the text to click. It can hold text, an image or other inline content, but not another link or a button.
link: url = "/guide" content = "Read the guide" end
| Attribute | What it does | Example |
|---|---|---|
typeنوع | A hint about the kind of file at the address, as a MIME type such as application/pdf. The browser may use it before it has fetched the file. It does not change what the file is. [mime] | link: url = "notes.pdf" type = "application/pdf" content = "Notes (PDF)" end |
downloadدانلود | Makes the browser save the target instead of opening it. The value is the file name to suggest; an empty value keeps the original name. It works for files from your own site. [string] | link: url = "report.pdf" download = "report-2026.pdf" content = "Save the report" end |
relرابطه | A space separated list of words that describe how the target relates to this page, such as noopener (the new page cannot control this one), noreferrer, nofollow (search engines should not count the link) or external. [token (list)] | link: url = "https://example.org" target = "new" rel = "noopener nofollow" content = "A site we do not vouch for" end |
referrer policyسیاست ارجاع | How much of this page's address is sent to the target: no-referrer (nothing), same-origin, origin (only the site), strict-origin-when-cross-origin and others. Use no-referrer when the address of your page is private. [enum: referrer_policy] | link: url = "https://example.com" referrer policy = "no-referrer" content = "Leave quietly" end |
pingپینگ | A space separated list of addresses that the browser notifies when the link is followed. It is used for click counting. Some browsers ignore it. [url (list)] | link: url = "/offer" ping = "https://example.com/count" content = "See the offer" end |
hreflangزبان مقصد | The language of the target page, as a language code such as fa or en. It is a hint for browsers and search engines. [lang] | link: url = "/fa/" hreflang = "fa" content = "Persian version" end |
urlنشانی | The address the link goes to, required. It can be a full address (https://...), a file name next to the page, a place on this page (#id), mailto: or tel:. Addresses that run code, such as javascript:, are refused. [url] | link: url = "#prices" content = "Jump to the prices" end |
targetهدف | Where the page opens: new (or _blank) for a new tab, same (_self) for the current one, parent and top for the enclosing frame or the whole window. [enum: target] | link: url = "https://example.com" target = "new" content = "Open in a new tab" end |
Images and maps
image (Persian: تصویر; HTML: <img>)
A picture (HTML img). The url is required. It has no children. Give it a description in alt or content, and its width and height.
image: url = "photo.jpg" content = "The garden gate in spring" width = 320 height = 200 end
| Attribute | What it does | Example |
|---|---|---|
widthعرض | The width of the picture. A bare number means pixels. Set it, with height, to the real size of the file so the browser can reserve the space before the picture loads. [ulength] | image: url = "photo.jpg" alt = "Gate" width = 240 height = 150 end |
heightارتفاع | The height of the picture, in pixels when it is a bare number. Together with width it lets the browser keep the picture's shape while it loads. [ulength] | image: url = "photo.jpg" alt = "Gate" width = 240 height = 150 end |
srcsetمجموعه منبع | A list of picture files for the browser to choose from, separated by commas. Each item is an address followed by 1x, 2x (screen density) or 480w, 960w (file width in pixels). [srcset] | image: url = "photo-480.jpg" alt = "Gate" srcset = "photo-480.jpg 480w, photo-960.jpg 960w" sizes = "480px" end |
sizesاندازهها | How wide the picture will be drawn, so the browser can pick from a srcset that uses w descriptors. A list of conditions with widths, ending with a default, for example (max-width: 600px) 100vw, 600px. [string] | image: url = "photo-480.jpg" alt = "Gate" srcset = "photo-480.jpg 480w, photo-960.jpg 960w" sizes = "(max-width: 600px) 100vw, 600px" end |
crossoriginمیانمبدا | Whether the request for a picture from another site carries credentials: anonymous (none) or use-credentials. It is needed when a script reads the pixels of a picture from another site. [enum: crossorigin] | image: url = "https://cdn.example.com/map.png" alt = "Map" crossorigin = "anonymous" end |
referrer policyسیاست ارجاع | How much of this page's address is sent when the picture is requested. The words are the same as for a link: no-referrer, origin, same-origin and so on. [enum: referrer_policy] | image: url = "https://img.example.com/a.png" alt = "Ad" referrer policy = "no-referrer" end |
loadingبارگذاری | When to fetch the picture: eager at once (the default) or lazy only when the reader scrolls close to it. Use lazy for pictures below the first screen. [enum: loading] | image: url = "footer-photo.jpg" alt = "The team" width = 320 height = 180 loading = "lazy" end |
decodingرمزگشایی | Whether the browser may decode the picture off to the side: async (yes, so the page is not held up), sync (decode together with the rest) or auto (the browser decides, the default). [enum: decoding] | image: url = "big.jpg" alt = "A large panorama" width = 640 height = 200 decoding = "async" end |
fetch priorityاولویت دریافت | A hint about how urgent the picture is: high, low or auto. Mark the main picture of the page high. [enum: fetch_priority] | image: url = "hero.jpg" alt = "The harbour at dawn" width = 640 height = 260 fetch priority = "high" end |
use mapنقشه | Connects the picture to an image map. The value is a # followed by the name of the map. [string] | image: url = "plan.png" alt = "Floor plan" use map = "#rooms" end
image map: name = "rooms"
area: shape = "rect" coords = "0,0,50,50" alt = "Kitchen" url = "#kitchen" end
end |
ismapنقشه سمت سرور | A boolean. On an image inside a link, it makes the browser add the click position to the address, so a server can decide what the click meant. Rarely needed today. [bool] | link: url = "/where"
image: url = "map.png" alt = "Map" ismap = true end
end |
urlنشانی | The address of the picture file, required. It can be a file name, a full address or a data address for small pictures. [url] | image: url = "images/kite.png" alt = "A red kite" end |
altجایگزین | The text description of the picture. Screen readers read it, and the browser shows it if the file cannot be loaded. Use an empty value (alt = "") for a picture that is only decoration. [string] | image: url = "chart.png" alt = "Rainfall by month, highest in March" end |
contentمحتوا | Another way to write alt: the text you give as content becomes the description. Use whichever reads better; do not give both. [string] | image: url = "logo.png" content = "Salam logo" end |
picture (Persian: عکس; HTML: <picture>)
A container that lets the browser choose between several versions of a picture. It holds source elements and ends with the normal image, which is the fallback and carries the description.
picture:
source: media = "(min-width: 700px)" srcset = "wide.jpg" end
image: url = "narrow.jpg" alt = "The harbour" end
end
source (Persian: منبع; HTML: <source>)
One candidate file for a picture, an audio or a video. The browser uses the first one whose conditions it meets and whose type it understands. It has no content.
video: controls = true
source: url = "intro.webm" type = "video/webm" end
source: url = "intro.mp4" type = "video/mp4" end
end
| Attribute | What it does | Example |
|---|---|---|
widthعرض | The width of the picture file of this candidate, in pixels. It helps the browser keep the right shape before the file arrives. [ulength] | picture:
source: srcset = "wide.jpg" media = "(min-width: 700px)" width = 1200 height = 600 end
image: url = "narrow.jpg" alt = "The harbour" end
end |
heightارتفاع | The height of the picture file of this candidate, in pixels. Give it together with width. [ulength] | picture:
source: srcset = "square.jpg" media = "(max-width: 400px)" width = 400 height = 400 end
image: url = "wide.jpg" alt = "The harbour" end
end |
urlنشانی | The address of the audio or video file. Inside a picture use srcset instead. [url] | audio: controls = true
source: url = "song.mp3" type = "audio/mpeg" end
end |
srcsetمجموعه منبع | The picture files of this candidate inside a picture, written like the srcset of an image. [srcset] | picture:
source: srcset = "photo.avif 1x, photo-2x.avif 2x" type = "image/avif" end
image: url = "photo.jpg" alt = "Gate" end
end |
sizesاندازهها | How wide the picture will be drawn, as for an image, used with w descriptors in srcset. [string] | picture:
source: srcset = "s-480.jpg 480w, s-960.jpg 960w" sizes = "(max-width: 600px) 100vw, 600px" end
image: url = "s-480.jpg" alt = "Gate" end
end |
typeنوع | The file type of this candidate, as a MIME type such as image/webp or video/mp4. A browser that does not know it skips the candidate without fetching. [mime] | picture:
source: srcset = "photo.webp" type = "image/webp" end
image: url = "photo.jpg" alt = "Gate" end
end |
mediaرسانه | A media condition, written as in CSS. The candidate is used only while the condition is true, such as (min-width: 700px) or (orientation: portrait). [media_query] | picture:
source: media = "(orientation: portrait)" srcset = "tall.jpg" end
image: url = "wide.jpg" alt = "The harbour" end
end |
image map (Persian: نقشه تصویر; HTML: <map>)
A set of clickable regions for an image (HTML map). The name is required and an image points at it with use map. Its children are area elements.
image map: name = "rooms"
area: shape = "circle" coords = "40,40,30" alt = "Kitchen" url = "#kitchen" end
end
| Attribute | What it does | Example |
|---|---|---|
nameنام | The name of the map, required. An image refers to it as use map = "#name". [string] | image map: name = "shapes"
area: shape = "rect" coords = "0,0,40,40" alt = "Box" url = "#box" end
end |
area (Persian: ناحیه; HTML: <area>)
One clickable region of an image map. It is a link: it takes url, target and the other link attributes, and its shape and coords say where it is. It has no content.
image map: name = "m"
area: shape = "rect" coords = "10,10,90,60" alt = "Home" url = "/" end
end
| Attribute | What it does | Example |
|---|---|---|
urlنشانی | Where a click on the region goes. Same kinds of address as for a link. [url] | image map: name = "m"
area: shape = "rect" coords = "0,0,50,50" alt = "Contact" url = "mailto:hi@example.com" end
end |
coordsمختصات | The points of the region as numbers separated by commas, in pixels of the picture. For rect: left,top,right,bottom. For circle: x,y,radius. For poly: x1,y1,x2,y2,.... [string] | image map: name = "m"
area: shape = "poly" coords = "10,60,50,10,90,60" alt = "Roof" url = "#roof" end
end |
shapeقالب ناحیه | The shape of the region: rect, circle, poly, or default for everything not covered by another area. [enum: area_shape] | image map: name = "m"
area: shape = "circle" coords = "50,50,30" alt = "Sun" url = "#sun" end
end |
targetهدف | Where the page opens, with the same words as for a link: new, same, parent, top. [enum: target] | image map: name = "m"
area: shape = "rect" coords = "0,0,50,50" alt = "Docs" url = "https://example.com" target = "new" end
end |
downloadدانلود | Saves the target as a file instead of opening it, as for a link. The value is the suggested file name. [string] | image map: name = "m"
area: shape = "rect" coords = "0,0,50,50" alt = "Menu" url = "menu.pdf" download = "menu.pdf" end
end |
relرابطه | How the target relates to the page, with the same words as for a link, such as noopener or nofollow. [token (list)] | image map: name = "m"
area: shape = "rect" coords = "0,0,50,50" alt = "Partner" url = "https://example.org" target = "new" rel = "noopener" end
end |
referrer policyسیاست ارجاع | How much of this page's address is sent to the target, as for a link. [enum: referrer_policy] | image map: name = "m"
area: shape = "rect" coords = "0,0,50,50" alt = "Away" url = "https://example.com" referrer policy = "no-referrer" end
end |
pingپینگ | Addresses that are notified when the region is followed, as for a link. [url (list)] | image map: name = "m"
area: shape = "rect" coords = "0,0,50,50" alt = "Offer" url = "/offer" ping = "https://example.com/count" end
end |
altجایگزین | The text for the region, for people who cannot click on the picture. Screen readers read it as the name of the link. Always give it. [string] | image map: name = "m"
area: shape = "rect" coords = "0,0,50,50" alt = "Open the kitchen page" url = "/kitchen" end
end |
Audio and video
audio (Persian: صدا; HTML: <audio>)
A sound player. Add controls so the reader can start it. Give the file with url or with source children. The content is shown only by a browser that cannot play audio.
audio: controls = true url = "song.mp3" content = "Your browser cannot play audio." end
| Attribute | What it does | Example |
|---|---|---|
urlنشانی | The address of the sound file. Use source children instead when you offer several formats. [url] | audio: url = "rain.ogg" controls = true end |
crossoriginمیانمبدا | Whether the request for a file from another site carries credentials: anonymous or use-credentials. Needed when a script analyses the sound. [enum: crossorigin] | audio: url = "https://cdn.example.com/a.mp3" controls = true crossorigin = "anonymous" end |
preloadپیشبارگذاری | How much to fetch before the reader presses play: none (nothing), metadata (only the length) or auto (as much as the browser likes). [enum: preload] | audio: url = "long-talk.mp3" controls = true preload = "metadata" end |
autoplayپخش خودکار | A boolean. Start playing as soon as possible. Browsers ignore it for sound unless the element is also muted or the reader has already interacted with the page. [bool] | audio: url = "ambient.mp3" autoplay = true muted = true loop = true end |
loopحلقه | A boolean. When the sound ends, start again from the beginning. [bool] | audio: url = "rain.ogg" controls = true loop = true end |
mutedبیصدا | A boolean. Start with the sound off. The reader can turn it on in the controls. [bool] | audio: url = "rain.ogg" controls = true muted = true end |
controlsکنترلها | A boolean. With true the browser shows its own play, pause, volume and position controls. Without them the player is invisible. [bool] | audio: url = "song.mp3" controls = true end |
video (Persian: ویدیو; HTML: <video>)
A video player. Add controls so the reader can start it, and give width and height. The file comes from url or from source children, and subtitles from track children.
video: width = 320 controls = true poster = "cover.jpg"
source: url = "clip.mp4" type = "video/mp4" end
end
| Attribute | What it does | Example |
|---|---|---|
widthعرض | The width of the player in pixels. Set it, with height, to keep the page from jumping when the video loads. [ulength] | video: url = "clip.mp4" controls = true width = 480 height = 270 end |
heightارتفاع | The height of the player in pixels. [ulength] | video: url = "clip.mp4" controls = true width = 480 height = 270 end |
urlنشانی | The address of the video file. Use source children instead when you offer several formats. [url] | video: url = "clip.mp4" controls = true width = 320 end |
crossoriginمیانمبدا | Whether the request for a file from another site carries credentials: anonymous or use-credentials. Needed when a script reads the frames, or when subtitles come from another site. [enum: crossorigin] | video: url = "https://cdn.example.com/v.mp4" controls = true crossorigin = "anonymous" width = 320 end |
preloadپیشبارگذاری | How much to fetch before the reader presses play: none, metadata or auto. metadata is a good choice for a page with many videos. [enum: preload] | video: url = "clip.mp4" controls = true preload = "metadata" width = 320 end |
autoplayپخش خودکار | A boolean. Start at once. Browsers allow it only for a video that is also muted. [bool] | video: url = "loop.mp4" autoplay = true muted = true loop = true plays inline = true width = 320 end |
loopحلقه | A boolean. When the video ends, start again from the beginning. [bool] | video: url = "loop.mp4" controls = true loop = true width = 320 end |
mutedبیصدا | A boolean. Start with the sound off. [bool] | video: url = "clip.mp4" controls = true muted = true width = 320 end |
controlsکنترلها | A boolean. With true the browser shows its play, pause, volume, position and full screen controls. [bool] | video: url = "clip.mp4" controls = true width = 320 end |
posterپوستر | A picture shown in place of the video until it plays. Give it a file name or address. [url] | video: url = "clip.mp4" controls = true poster = "cover.jpg" width = 320 end |
plays inlineپخش درجا | A boolean. On phones that would otherwise open every video in full screen, keep it playing inside the page. [bool] | video: url = "clip.mp4" controls = true plays inline = true width = 320 end |
track (Persian: شیار; HTML: <track>)
A text track for a video or audio: subtitles, captions, descriptions or chapters, from a WebVTT file. The url is required. It has no content.
video: url = "talk.mp4" controls = true width = 320
track: url = "talk.en.vtt" kind = "subtitles" srclang = "en" label = "English" end
end
| Attribute | What it does | Example |
|---|---|---|
urlنشانی | The address of the WebVTT file, required. [url] | video: url = "talk.mp4" controls = true width = 320
track: url = "captions/talk.vtt" kind = "captions" srclang = "en" label = "Captions" end
end |
kindنوع شیار | What the text is: subtitles (a translation of the speech), captions (speech and sounds, for deaf readers), descriptions (what is seen, for blind readers), chapters (titles for navigation) or metadata (for scripts, not shown). [enum: track_kind] | video: url = "talk.mp4" controls = true width = 320
track: url = "talk.vtt" kind = "chapters" srclang = "en" label = "Chapters" end
end |
srclangزبان شیار | The language of the text, as a language code such as en or fa. Required for subtitles. [lang] | video: url = "talk.mp4" controls = true width = 320
track: url = "talk.fa.vtt" kind = "subtitles" srclang = "fa" label = "Persian" end
end |
labelبرچسب | The name of the track in the player's menu, for example English. [string] | video: url = "talk.mp4" controls = true width = 320
track: url = "talk.vtt" kind = "subtitles" srclang = "en" label = "English (UK)" end
end |
defaultپیشفرض | A boolean. Turn this track on when the video starts, unless the reader has chosen another. Use it on one track only. [bool] | video: url = "talk.mp4" controls = true width = 320
track: url = "talk.vtt" kind = "subtitles" srclang = "en" label = "English" default = true end
end |
Frames and embedded objects
iframe (Persian: قاب درونی; HTML: <iframe>)
A frame that shows another page inside this one. The page is an address in url or a short document in srcdoc. Give it a title and a size, and lock it down with sandbox.
iframe: url = "https://example.com/widget" title = "Widget" width = 400 height = 240 sandbox = "allow-scripts" end
| Attribute | What it does | Example |
|---|---|---|
widthعرض | The width of the frame. A bare number means pixels. Browsers give a frame 300 pixels by default. [ulength] | iframe: url = "https://example.com/embed" title = "Embedded" width = 480 height = 270 end |
heightارتفاع | The height of the frame. A bare number means pixels. The default is 150 pixels. [ulength] | iframe: url = "https://example.com/embed" title = "Embedded" width = 480 height = 270 end |
nameنام | A name for the frame, so that scripts can find it as a named window. The page language accepts only the four words (new, same, parent, top) as the target of a link. [string] | iframe: name = "preview" title = "Preview" width = 300 height = 160 srcdoc = "<p>Empty</p>" end |
referrer policyسیاست ارجاع | How much of this page's address is sent when the frame's page is requested, with the same words as for a link. [enum: referrer_policy] | iframe: url = "https://example.com/embed" title = "Embedded" width = 300 height = 160 referrer policy = "no-referrer" end |
loadingبارگذاری | When to load the frame: eager at once or lazy when the reader scrolls close to it. Use lazy for a frame far down the page. [enum: loading] | iframe: url = "https://example.com/map" title = "Map" width = 400 height = 240 loading = "lazy" end |
srcdocمحتوای سند | A complete small document, written as HTML text, to show in the frame instead of loading an address. It is escaped for you. [string] | iframe: title = "Note" width = 300 height = 80 srcdoc = "<p style='font-family:sans-serif'>Hello from the frame</p>" end |
allow fullscreenاجازه تمامصفحه | A boolean. With true the page in the frame may go full screen. [bool] | iframe: url = "https://example.com/player" title = "Player" width = 400 height = 240 allow fullscreen = true end |
sandboxقرنطینه | Restrictions for the frame. An empty value removes every permission. Words separated by spaces give some back: allow-scripts, allow-forms, allow-popups, allow-same-origin and others. Do not give allow-scripts and allow-same-origin together to a page you do not trust. [string] | iframe: url = "https://example.com/form" title = "Form" width = 400 height = 240 sandbox = "allow-forms allow-scripts" end |
allowاجازه | A list of browser features the frame may use, separated by semicolons, such as fullscreen, camera, microphone or geolocation. The default is to allow none for pages from another site. [string] | iframe: url = "https://example.com/call" title = "Video call" width = 400 height = 300 allow = "camera; microphone" end |
urlنشانی | The address of the page to show in the frame. Use srcdoc instead for a short document written right here. [url] | iframe: url = "https://example.com/embed" title = "Embedded page" width = 400 height = 200 end |
embed (Persian: جاسازی; HTML: <embed>)
Places an external resource, such as a PDF, into the page (HTML embed). The url is required. It has no content, so there is no fallback text.
embed: url = "report.pdf" type = "application/pdf" width = 400 height = 300 end
| Attribute | What it does | Example |
|---|---|---|
widthعرض | The width of the embedded area, in pixels when it is a bare number. [ulength] | embed: url = "report.pdf" type = "application/pdf" width = 500 height = 300 end |
heightارتفاع | The height of the embedded area, in pixels when it is a bare number. [ulength] | embed: url = "report.pdf" type = "application/pdf" width = 500 height = 300 end |
urlنشانی | The address of the resource, required. [url] | embed: url = "slides.pdf" type = "application/pdf" width = 400 height = 300 end |
typeنوع | The MIME type of the resource, such as application/pdf. It helps the browser choose how to show it. [mime] | embed: url = "report.pdf" type = "application/pdf" width = 400 height = 300 end |
object (Persian: شیء; HTML: <object>)
An external resource shown in the page, with fallback content (HTML object). The url is required. If the browser cannot show the file, it shows the children instead, which is the place for a link to download it.
object: url = "report.pdf" type = "application/pdf" width = 400 height = 300
link: url = "report.pdf" content = "Download the report" end
end
| Attribute | What it does | Example |
|---|---|---|
widthعرض | The width of the object, in pixels when it is a bare number. [ulength] | object: url = "chart.svg" type = "image/svg+xml" width = 320 height = 200 content = "A chart" end |
heightارتفاع | The height of the object, in pixels when it is a bare number. [ulength] | object: url = "chart.svg" type = "image/svg+xml" width = 320 height = 200 content = "A chart" end |
typeنوع | The MIME type of the resource, such as application/pdf or image/svg+xml. [mime] | object: url = "chart.svg" type = "image/svg+xml" width = 300 height = 200 content = "A chart" end |
nameنام | A name for the object, for scripts and forms. [string] | object: url = "chart.svg" type = "image/svg+xml" name = "chart" width = 300 height = 200 content = "A chart" end |
urlنشانی | The address of the resource, required. It becomes the data attribute in HTML. [url] | object: url = "chart.svg" type = "image/svg+xml" width = 300 height = 200 content = "A chart" end |
formفرم | The id of a form this object belongs to. The compiler checks that an element with that id exists on the page. [idref] | box: id = "order" end
object: form = "order" url = "widget.svg" type = "image/svg+xml" width = 200 height = 100 content = "Widget" end |
Drawing
canvas (Persian: بوم; HTML: <canvas>)
A blank drawing surface (HTML canvas). You draw on it with code, through dom.GetContext. Give it an id so the code can find it, and set its size with the attributes, not with CSS.
canvas: id = "pad" width = 300 height = 150 background = "#f1f5f9" end
| Attribute | What it does | Example |
|---|---|---|
widthعرض | The width of the drawing surface in pixels. This is the number of pixels you draw on. A width set with CSS only stretches them. [ulength] | canvas: width = 400 height = 200 border = "1px solid #94a3b8" end |
heightارتفاع | The height of the drawing surface in pixels. The default is 150. [ulength] | canvas: width = 400 height = 200 border = "1px solid #94a3b8" end |
svg (Persian: اسویجی; HTML: <svg>)
A vector picture written in place (HTML svg). Its content is the markup of the shapes, inserted as written and not escaped, so use only markup you wrote yourself. The picture stays sharp at every size.
svg: view box = "0 0 100 100" width = 120 height = 120 content = "<circle cx='50' cy='50' r='40' fill='tomato'/>" end
| Attribute | What it does | Example |
|---|---|---|
view boxجعبه دید | The coordinate system inside the picture: four numbers, min-x min-y width height. The shapes are drawn in these units and scaled to the width and height on the page. [string] | svg: view box = "0 0 200 100" width = 200 height = 100 content = "<rect width='200' height='100' fill='#ccfbf1'/>" end |
widthعرض | The width of the picture on the page, such as 120 or 50%. [string] | svg: view box = "0 0 100 100" width = "50%" height = 100 content = "<circle cx='50' cy='50' r='40' fill='gold'/>" end |
heightارتفاع | The height of the picture on the page, such as 120. [string] | svg: view box = "0 0 100 100" width = 100 height = 100 content = "<circle cx='50' cy='50' r='40' fill='gold'/>" end |
xmlnsفضای نام | The XML namespace address, http://www.w3.org/2000/svg. It is only needed when the SVG is saved as a file of its own. Inside a page you can leave it out. [absolute_url] | svg: xmlns = "http://www.w3.org/2000/svg" view box = "0 0 100 100" width = 100 height = 100 content = "<circle cx='50' cy='50' r='40' fill='teal'/>" end |
math (Persian: ریاضی; HTML: <math>)
A mathematical formula written in MathML (HTML math). Its content is the markup, inserted as written: mi for a name, mn for a number, mo for an operator, mfrac for a fraction, msup for a power, msqrt for a square root.
math: content = "<msqrt><mi>x</mi></msqrt><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac>" end
Try it yourself
- Write a page with a table of contents: a list of links that point with
#to three headings further down. Add a link at the bottom that goes back to the top. - Draw your own picture in an
svg: a house from arect, apolygonfor the roof and acirclefor the sun. Then change thewidthandheightbut keep theview box, and watch it scale. - Change the image map so that the red square is a
linkto a heading on the same page, and add a third hotspot withpoly. - Open the canvas example, make the stamp a different color on every click by using
dom.Random(), and add a second button that fills the whole canvas.