Borders, outlines and shadows
The edge of a box is where a design gets its character: a thin line, a rounded card, a glowing ring, a shadow that lifts it off the page. This lesson covers every border, outline and shadow property, shows how the compiler checks your values, and explains why you should never remove a focus ring.
The border shorthand
A border is a line drawn between the padding of a box and its margin. It has three parts: a width, a style and a color. The shorthand border takes all three in one string, in any order: "2px solid #0f766e". A bare number written without quotes, such as 6, means pixels. The style decides what is drawn: solid is a plain line, dashed and dotted are broken lines, double is two thin lines with a gap, and groove, ridge, inset and outset imitate a carved or raised edge by shading two sides lighter and two darker. none draws nothing and hidden does the same, but wins when two borders meet in a table.
component Sample(kind):
box:
border style = kind
border width = 6
border color = "#0f766e"
padding = 12
content = kind
end
end
page:
title = "Border styles"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
display = grid gap = 12 grid template columns = "repeat(auto-fit, minmax(110px, 1fr))" text align = center
Sample: kind = "solid" end
Sample: kind = "dashed" end
Sample: kind = "dotted" end
Sample: kind = "double" end
Sample: kind = "groove" end
Sample: kind = "ridge" end
Sample: kind = "inset" end
Sample: kind = "outset" end
end
endThe example uses a small component, Sample, so each border style is one line. It passes the style name to border style and also shows it as text. The same three parts exist as separate properties: border width, border style and border color.
The style is the part people forget. The default style is none, so border color = "red" or border width = 5 on their own draw nothing at all. Always write a style, either in the shorthand or with border style = solid.
The three longhands take from one to four values, and the rule is the same for each of them. One value applies to all four sides. Two values are the top and bottom, then the left and right. Three values are the top, then the left and right, then the bottom. Four values go clockwise from the top: top, right, bottom, left. Padding and margin use the same rule, so you only learn it once.
A border is part of the box. With the default sizing a box of width = 200 and a border of 6px on each side becomes 212px wide. Many pages add a global rule box sizing = "border-box", which makes the width include padding and border, and the next lessons assume you know both ways.
One side at a time
Each side has its own shorthand and its own three longhands. border top, border right, border bottom and border left take the usual width, style and color. border top color and its twelve relatives change one part of one side. The example shows the most common uses: a thick stripe on the left of a warning, an underline under a heading, and two ways to give the four sides different widths and colors in a single line.
page:
title = "Borders on one side"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
display = grid gap = 14
box: border left = "6px solid #dc2626" background = "#fef2f2" padding = "10px 14px" content = "A warning: border left" end
heading: size = 3 margin = 0 padding = "0 0 6px 0" border bottom = "3px solid #0f766e" content = "A heading: border bottom" end
box: border style = "solid" border width = "2px 10px" border color = "#6366f1" padding = 12 content = "Two values: top and bottom, left and right" end
box: border style = "solid" border width = 6 border color = "#ef4444 #22c55e #3b82f6 #eab308" padding = 12 content = "Four colors: top, right, bottom, left" end
end
endWhen a side has no border you can leave it out. The usual way to build a mixed border is to set border first and then overwrite the one side that must differ, for example border = "1px solid #cbd5e1" followed by border bottom color = "#0f766e". The later property wins, so the order of the lines matters.
Logical sides for any language
left and right are wrong for a page that is read from right to left: a stripe at the left of an English quotation belongs at the right of a Persian one. The logical properties name the sides by the direction of the text instead. The inline direction is the way a line of text runs. Inline start is where a line begins, which is the left in English and the right in Persian or Arabic, and inline end is the opposite side. The block direction is the way lines stack, so block start is the top and block end is the bottom in ordinary horizontal text.
That gives border inline start, border inline end, border block start and border block end, each with its width, style and color. The shorthand border inline sets both inline sides and border block sets both block sides, and their color, style and width forms take one or two values (start, then end). In the example the same line of code puts the stripe on the left of the English box and on the right of the Persian box, because the second box has dir = "rtl".
page:
title = "Logical borders"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
dir = "ltr"
border inline start = "6px solid #0f766e"
padding = "10px 14px"
margin = "0 0 14px 0"
background = "#f0fdfa"
content = "English text: the stripe is on the left."
end
box:
dir = "rtl"
border inline start = "6px solid #0f766e"
padding = "10px 14px"
background = "#f0fdfa"
content = "متن فارسی: خط کنار راست است."
end
endPrefer the logical names in anything that may be shown in more than one language. In a Persian-only project the physical names are fine, and they are often what you want for something that is tied to the screen, such as a shadow.
Rounded corners
border radius rounds the corners. A single length makes circular corners of that radius. Two to four values follow the corner order: with two, the first is for the top left and bottom right corners and the second for the top right and bottom left; with four they go clockwise from the top left. A slash makes oval corners: 50% / 30% sets a horizontal radius of 50% and a vertical radius of 30%. A radius larger than the box can fit is reduced, so 999px is the usual way to make a pill, and 50% on a square makes a circle.
Each corner also has its own property: border top left radius, border top right radius, border bottom left radius and border bottom right radius, and the logical versions border start start radius, border start end radius, border end start radius and border end end radius. The first word after border is the block side and the second is the inline side, so border start end radius is the top right corner in English and the top left in Persian.
component Tile(label, corners):
box:
width = 100
height = 70
background = "#f59e0b"
display = flex
align items = center
justify content = center
font size = 13
border radius = corners
content = label
end
end
page:
title = "Rounded corners"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
display = flex gap = 14 flex wrap = wrap
Tile: label = "12" corners = 12 end
Tile: label = "30px 0" corners = "30px 0" end
Tile: label = "pill" corners = "999px" end
Tile: label = "50% / 30%" corners = "50% / 30%" end
Tile: label = "4 values" corners = "40px 4px 40px 4px" end
box: width = 70 height = 70 border radius = "50%" background = "#f59e0b" end
box: width = 100 height = 70 border top left radius = 40 background = "#f59e0b" display = flex align items = center justify content = center font size = 13 content = "top left" end
box: width = 100 height = 70 border start end radius = 35 background = "#f59e0b" display = flex align items = center justify content = center font size = 13 content = "start end" end
end
endRounding shapes the background, the border and the shadow, but it does not clip the content. A child that is larger than the box still sticks out of its rounded corner unless the box has overflow = hidden.
Border images
A border does not have to be a line. border image source draws a picture or a gradient in the border area instead. The picture is cut into nine pieces by border image slice: four corners, four edges and a middle. The corners go into the corners of the border as they are, the edges are stretched or repeated along the sides, and the middle is thrown away unless you add fill. This is called a nine-slice frame, and it lets one small picture fit boxes of any size.
The properties that control it are border image slice (how far from each edge of the picture to cut, as a number of the picture's own pixels or a percentage), border image width (how thick the frame is drawn, a length or a multiple of the border width), border image outset (how far it reaches outside the box) and border image repeat (stretch, repeat, round or space). border image is the shorthand for all five, in the order source slice / width / outset repeat. The border itself must still have a width, and a transparent color is the usual choice so that nothing shows through under the picture.
const FRAME := "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2790%27 height=%2790%27%3E%3Crect x=%275%27 y=%275%27 width=%2780%27 height=%2780%27 rx=%2710%27 fill=%27none%27 stroke=%27%230f766e%27 stroke-width=%274%27/%3E%3Ccircle cx=%2715%27 cy=%2715%27 r=%2712%27 fill=%27%23f59e0b%27/%3E%3Ccircle cx=%2775%27 cy=%2715%27 r=%2712%27 fill=%27%23f59e0b%27/%3E%3Ccircle cx=%2715%27 cy=%2775%27 r=%2712%27 fill=%27%23f59e0b%27/%3E%3Ccircle cx=%2775%27 cy=%2775%27 r=%2712%27 fill=%27%23f59e0b%27/%3E%3C/svg%3E')"
page:
title = "Border image"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
width = 260
padding = 14
border = "30px solid transparent"
border image source = FRAME
border image slice = 30
border image width = "30px"
border image repeat = "round"
content = "The four corners come from the corners of the picture. The edges are stretched or repeated to fit the box."
end
endThe frame in the example is a small SVG picture written as a data URL, with an amber circle in each corner. Because the corners are copied and never stretched, the circles stay round on a box of any size, and round repeats the edges a whole number of times so no piece is cut. A gradient works as a source too, and with a slice of 1 it makes the popular gradient border: border image = "linear-gradient(135deg, #f59e0b, #db2777) 1". The one thing a border image cannot do is follow border radius, because the image replaces the line that the radius would have curved.
Outlines and focus rings
outline looks like a border and takes the same width, style and color, but it is different in three ways. It is drawn outside the box and takes no room in the layout, so adding one never moves anything. It can be pushed away from the box with outline offset, or pulled inside with a negative offset. And it is the tool of the browser for showing keyboard focus. The longhands are outline color, outline style (the border styles and also auto, the browser's own ring) and outline width.
Focus is the element that receives the keyboard. A person who cannot use a mouse presses Tab to move from link to button to field, and the focus ring is the only thing that shows where they are. Write the state as a prefix: focus outline = "3px solid #2563eb" applies only while the element has focus. Click into the example and press Tab: the button gets a blue ring set three pixels away, and the input gets a pink one.
page:
title = "Outlines and focus rings"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
display = flex gap = 24 flex wrap = wrap align items = center
button:
id = "go"
content = "Tab to me"
padding = "8px 16px"
border = "2px solid #0f766e"
background = "white"
border radius = 6
focus outline = "3px solid #2563eb"
focus outline offset = 3
end
input: type = "text" placeholder = "Focus me" padding = 8 focus outline color = "#db2777" focus outline width = 3 focus outline style = solid end
box: outline = "3px dashed #db2777" outline offset = 6 padding = 12 content = "outline offset 6" end
end
endNever write outline = none to get rid of the ring that browsers draw around a focused control, unless you replace it with another clearly visible focus style. Without a ring, a keyboard user cannot tell where they are, and the page fails the accessibility rules that many countries require. The right fix for an ugly ring is a better looking ring, not no ring. The ring should have a contrast ratio of at least 3 to 1 against what is around it.
Box shadows
box shadow draws a shadow behind the box, shaped like its rounded corners. One shadow is written as up to five parts: x y blur spread color. The first two numbers move the shadow right and down (negative numbers move it left and up). Blur softens the edge: 0 is sharp and a bigger number is softer. Spread makes the shadow bigger or, if negative, smaller than the box. The color is almost always a transparent black such as rgb(0 0 0 / 20%), because a shadow lets the page show through. Put inset first and the shadow is drawn inside the box, as if it were pressed in.
Separate several shadows with commas and the first one is on top. A pair of shadows, one close and tight and one far and soft, looks far more natural than a single one, which is how the "layered" card gets its depth. A shadow with no blur and a spread of 4px is a ring that follows the corners, and a blurry shadow with a bright color is a glow.
component Card(label, shadow):
box:
background = "white"
width = 120
height = 80
display = flex
align items = center
justify content = center
text align = center
font size = 13
border radius = 10
box shadow = shadow
content = label
end
end
page:
title = "Box shadows"
global: selector = "body" font family = "system-ui, sans-serif" margin = 0 padding = "1.5rem" background = "#e2e8f0" end
box:
display = flex gap = 24 flex wrap = wrap
Card: label = "soft" shadow = "0 4px 12px rgb(0 0 0 / 18%)" end
Card: label = "hard offset" shadow = "6px 6px 0 #0f172a" end
Card: label = "spread ring" shadow = "0 0 0 4px #60a5fa" end
Card: label = "inset" shadow = "inset 0 3px 8px rgb(0 0 0 / 30%)" end
Card: label = "glow" shadow = "0 0 24px #22d3ee" end
Card: label = "layered" shadow = "0 1px 2px rgb(0 0 0 / 20%), 0 8px 24px rgb(0 0 0 / 18%)" end
end
endThe next example lets you try the values. The sliders write a new box-shadow and border-radius to the card and print the CSS they made, so you can read how each number changes the look.
import dom
func update():
x := dom.GetValue(dom.ById("x"))
y := dom.GetValue(dom.ById("y"))
blur := dom.GetValue(dom.ById("blur"))
radius := dom.GetValue(dom.ById("radius"))
shadow := x + "px " + y + "px " + blur + "px rgb(0 0 0 / 35%)"
dom.SetStyle(dom.ById("card"), "box-shadow", shadow)
dom.SetStyle(dom.ById("card"), "border-radius", radius + "px")
dom.SetText(dom.ById("css"), "box-shadow: " + shadow + "; border-radius: " + radius + "px")
end
page:
title = "Shadow lab"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box: id = "card" width = 180 height = 90 margin = "10px 0 20px" background = "white" border = "1px solid #cbd5e1" box shadow = "0px 4px 12px rgb(0 0 0 / 35%)" border radius = 12 end
box: label: content = "x" width = 60 display = "inline-block" end input: type = "range" id = "x" min = "-20" max = "20" value = "0" input = update end end
box: label: content = "y" width = 60 display = "inline-block" end input: type = "range" id = "y" min = "-20" max = "20" value = "4" input = update end end
box: label: content = "blur" width = 60 display = "inline-block" end input: type = "range" id = "blur" min = "0" max = "40" value = "12" input = update end end
box: label: content = "radius" width = 60 display = "inline-block" end input: type = "range" id = "radius" min = "0" max = "45" value = "12" input = update end end
paragraph: id = "css" content = "box-shadow: 0px 4px 12px rgb(0 0 0 / 35%); border-radius: 12px" end
endA shadow is only decoration and never changes the layout, so it can overlap the neighbours and it can be cut by a parent with overflow = hidden. For text use text shadow, and for the shape of an image with transparent parts use the drop-shadow() filter from the previous lesson.
Broken boxes and new corner shapes
An inline element such as a span can wrap onto several lines, and then its padding, border and background have to be drawn on more than one piece. box decoration break chooses how. With slice, the default, the element is drawn as if it were one long box that has been cut with scissors, so the left edge appears only on the first piece and the right edge only on the last. With clone every piece is a complete box with its own edges, padding and corners. Use clone for highlights and tags that may wrap.
page:
title = "Box decoration break"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" max width = "280px" line height = 2.2 end
paragraph:
content = "Slice (the default): "
span: background = "#fde68a" padding = "2px 10px" border radius = 8 border = "2px solid #b45309" box decoration break = "slice" content = "one highlight cut into pieces where the line breaks" end
end
paragraph:
content = "Clone: "
span: background = "#fde68a" padding = "2px 10px" border radius = 8 border = "2px solid #b45309" box decoration break = "clone" content = "every piece gets its own padding, border and corners" end
end
endThe corner shape properties change what a rounded corner looks like. Until now the curve was always a quarter circle. corner shape can make it a squircle (a softer, superelliptical curve, like app icons), a bevel (cut straight across), a scoop (curved inward) or a notch (a square cut inward), and each corner has its own property, such as corner top left shape. The shape is applied to the corners that border radius sets, so the radius is still needed to say how large the corner is.
component Tile(label, shape):
box:
width = 100
height = 80
background = "#7c3aed"
color = "white"
display = flex
align items = center
justify content = center
border radius = 28
font size = 13
corner shape = shape
content = label
end
end
page:
title = "Corner shapes"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
display = flex gap = 16 flex wrap = wrap
Tile: label = "round" shape = "round" end
Tile: label = "squircle" shape = "squircle" end
Tile: label = "bevel" shape = "bevel" end
Tile: label = "scoop" shape = "scoop" end
Tile: label = "notch" shape = "notch" end
Tile: label = "scoop bevel" shape = "scoop bevel" end
end
endCorner shapes are new and so far only Chromium browsers draw them. In other browsers the corners simply stay round, which is a fine fallback because the box still works. Do not make a design depend on them yet. Borders in tables, with border collapse, are covered in the lesson on more properties.
How the compiler checks values
Every style value in a page is checked while the page is compiled, not in the browser. A browser silently ignores a CSS value it does not understand, and the page just looks wrong with no message. In Salam a bad value stops the build with error E018. The message names the property, shows the value you wrote and says what was expected. For example, writing a style of wobbly in border style reports invalid value for 'border style': 'wobbly' is not 'none', 'hidden', 'dotted', ... followed by the file, line and column where the value is. A radius of big reports that it is not a length or a percentage, and a border shorthand with parts that do not belong together says that it is not a valid combination for this property.
The check works on the shorthands as well. It splits border into its parts and checks each part against its own rules, so a typo in a color name inside "2px solid reed" is found too. Persian files accept the Persian value names such as یکپارچه and خطچین in the same places, and the messages are in Persian. The tables below show the values each property accepts.
Reference: borders, outlines and shadows
Every property of this lesson is listed below. Each one has a one-line description of what it accepts and an example that the compiler has checked. The groups follow the lesson: the shorthand and the four values rule, the four physical sides, the logical sides, the corners, the border image, and then outline, shadow and the corner shapes.
All sides
| Property | What it does and what it accepts | Example |
|---|---|---|
borderکادر border | Draws a border on all four sides. The value is a width, a style and a color in any order, for example 2px solid #0f766e. The style is required, because the default none shows nothing. [CSS-wide keywords only] | box: padding = 12 border = "2px solid #0f766e" content = "border" end |
border widthضخامت کادر border-width | The thickness of the borders, with the same one to four value rules as border color. Each value is a length, or thin, medium or thick. [length / thin, medium, thick; up to 4 values] | box: padding = 12 border style = solid border color = "#0f766e" border width = "1px 4px 8px 12px" content = "1, 4, 8, 12" end |
border styleسبک کادر border-style | The line style of the borders, with the same one to four value rules as border color. The values are none, hidden, dotted, dashed, solid, double, groove, ridge, inset and outset. [none, hidden, dotted, dashed, solid, double, ...; up to 4 values] | box: padding = 12 border = "6px solid #7c3aed" border style = "solid dashed" content = "solid, dashed" end |
border colorرنگ کادر border-color | The color of the borders. One value colors all four sides; two values are top and bottom then left and right; three are top, left and right, bottom; four go clockwise from the top. [color; up to 4 values] | box: padding = 12 border = "8px solid black" border color = "#ef4444 #22c55e #3b82f6 #eab308" content = "four colors" end |
Top
| Property | What it does and what it accepts | Example |
|---|---|---|
border topکادر بالا border-top | Sets the width, style and color of the top border in one value, such as 3px solid #0f766e. A part you leave out gets its default, and the style must be present because the default style none draws nothing. [CSS-wide keywords only] | box: padding = 12 border top = "3px solid #0f766e" content = "top border" end |
border top widthضخامت کادر بالا border-top-width | The thickness of the top border: a length such as 4px, or thin, medium or thick. It has no effect while the style is none. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #0f766e" border top width = 8 content = "top 8px" end |
border top styleسبک کادر بالا border-top-style | The line style of the top border: none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. With no style, nothing is drawn. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #0f766e" border top style = dashed content = "top dashed" end |
border top colorرنگ کادر بالا border-top-color | The color of the top border only. It takes any color. Without it the border uses the text color of the element. [color] | box: padding = 12 border = "4px solid #cbd5e1" border top color = "#db2777" content = "top color" end |
Right
| Property | What it does and what it accepts | Example |
|---|---|---|
border rightکادر راست border-right | Sets the width, style and color of the right border in one value, such as 5px solid #dc2626. A part you leave out gets its default, and the style must be present because the default style none draws nothing. [CSS-wide keywords only] | box: padding = 12 border right = "5px solid #dc2626" content = "right border" end |
border right widthضخامت کادر راست border-right-width | The thickness of the right border: a length such as 4px, or thin, medium or thick. It has no effect while the style is none. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #dc2626" border right width = 11 content = "right 11px" end |
border right styleسبک کادر راست border-right-style | The line style of the right border: none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. With no style, nothing is drawn. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #dc2626" border right style = dotted content = "right dotted" end |
border right colorرنگ کادر راست border-right-color | The color of the right border only. It takes any color. Without it the border uses the text color of the element. [color] | box: padding = 12 border = "4px solid #cbd5e1" border right color = "#ca8a04" content = "right color" end |
Bottom
| Property | What it does and what it accepts | Example |
|---|---|---|
border bottomکادر پایین border-bottom | Sets the width, style and color of the bottom border in one value, such as 7px solid #2563eb. A part you leave out gets its default, and the style must be present because the default style none draws nothing. [CSS-wide keywords only] | box: padding = 12 border bottom = "7px solid #2563eb" content = "bottom border" end |
border bottom widthضخامت کادر پایین border-bottom-width | The thickness of the bottom border: a length such as 4px, or thin, medium or thick. It has no effect while the style is none. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #2563eb" border bottom width = 14 content = "bottom 14px" end |
border bottom styleسبک کادر پایین border-bottom-style | The line style of the bottom border: none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. With no style, nothing is drawn. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #2563eb" border bottom style = double content = "bottom double" end |
border bottom colorرنگ کادر پایین border-bottom-color | The color of the bottom border only. It takes any color. Without it the border uses the text color of the element. [color] | box: padding = 12 border = "4px solid #cbd5e1" border bottom color = "#7c3aed" content = "bottom color" end |
Left
| Property | What it does and what it accepts | Example |
|---|---|---|
border leftکادر چپ border-left | Sets the width, style and color of the left border in one value, such as 9px solid #db2777. A part you leave out gets its default, and the style must be present because the default style none draws nothing. [CSS-wide keywords only] | box: padding = 12 border left = "9px solid #db2777" content = "left border" end |
border left widthضخامت کادر چپ border-left-width | The thickness of the left border: a length such as 4px, or thin, medium or thick. It has no effect while the style is none. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #db2777" border left width = 17 content = "left 17px" end |
border left styleسبک کادر چپ border-left-style | The line style of the left border: none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. With no style, nothing is drawn. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #db2777" border left style = groove content = "left groove" end |
border left colorرنگ کادر چپ border-left-color | The color of the left border only. It takes any color. Without it the border uses the text color of the element. [color] | box: padding = 12 border = "4px solid #cbd5e1" border left color = "#ea580c" content = "left color" end |
Block sides
| Property | What it does and what it accepts | Example |
|---|---|---|
border blockکادر بلوکی border-block | Sets the border on both block sides at once, which are the top and the bottom in horizontal text. It takes the same width, style and color as border. [CSS-wide keywords only] | box: padding = 12 border block = "3px solid #0f766e" content = "block: top and bottom" end |
border block widthضخامت کادر بلوکی border-block-width | The thickness of the two block borders. One value sets both; two values give the start and then the end. [length / thin, medium, thick; up to 2 values] | box: padding = 12 border = "1px solid #7c3aed" border block width = "2px 10px" content = "thin above, thick below" end |
border block styleسبک کادر بلوکی border-block-style | The line style of the two block borders. One value styles both; two values give the start and then the end. [none, hidden, dotted, dashed, solid, double, ...; up to 2 values] | box: padding = 12 border = "5px solid #0f766e" border block style = "dashed double" content = "dashed above, double below" end |
border block colorرنگ کادر بلوکی border-block-color | The color of the two block borders. One value colors both; two values give the start and then the end. [color; up to 2 values] | box: padding = 12 border = "5px solid #e2e8f0" border block color = "#dc2626 #2563eb" content = "start red, end blue" end |
border block startکادر بلوکی آغاز border-block-start | Sets the width, style and color of the border at the start of the block direction (the top in horizontal text) in one value. It follows the writing direction, so the same code works in left to right and right to left pages. [CSS-wide keywords only] | box: padding = 12 border block start = "4px solid #7c3aed" content = "block-start" end |
border block start widthضخامت کادر بلوکی آغاز border-block-start-width | The thickness of the border at the start of the block direction (the top in horizontal text): a length, or thin, medium or thick. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #7c3aed" border block start width = 9 content = "block-start 9px" end |
border block start styleسبک کادر بلوکی آغاز border-block-start-style | The line style of the border at the start of the block direction (the top in horizontal text): none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #7c3aed" border block start style = dashed content = "block-start dashed" end |
border block start colorرنگ کادر بلوکی آغاز border-block-start-color | The color of the border at the start of the block direction (the top in horizontal text). It takes any color. [color] | box: padding = 12 border = "4px solid #e2e8f0" border block start color = "#16a34a" content = "block-start color" end |
border block endکادر بلوکی انتها border-block-end | Sets the width, style and color of the border at the end of the block direction (the bottom in horizontal text) in one value. It follows the writing direction, so the same code works in left to right and right to left pages. [CSS-wide keywords only] | box: padding = 12 border block end = "6px solid #ea580c" content = "block-end" end |
border block end widthضخامت کادر بلوکی انتها border-block-end-width | The thickness of the border at the end of the block direction (the bottom in horizontal text): a length, or thin, medium or thick. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #ea580c" border block end width = 11 content = "block-end 11px" end |
border block end styleسبک کادر بلوکی انتها border-block-end-style | The line style of the border at the end of the block direction (the bottom in horizontal text): none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #ea580c" border block end style = dotted content = "block-end dotted" end |
border block end colorرنگ کادر بلوکی انتها border-block-end-color | The color of the border at the end of the block direction (the bottom in horizontal text). It takes any color. [color] | box: padding = 12 border = "4px solid #e2e8f0" border block end color = "#be123c" content = "block-end color" end |
Inline sides
| Property | What it does and what it accepts | Example |
|---|---|---|
border inlineکادر خطی border-inline | Sets the border on both inline sides at once, which are the left and the right in horizontal text. It takes the same width, style and color as border. [CSS-wide keywords only] | box: padding = 12 border inline = "4px dotted #ea580c" content = "inline: left and right" end |
border inline widthضخامت کادر خطی border-inline-width | The thickness of the two inline borders. One value sets both; two values give the start and then the end. [length / thin, medium, thick; up to 2 values] | box: padding = 12 border = "1px solid #be123c" border inline width = "12px 2px" content = "thick start, thin end" end |
border inline styleسبک کادر خطی border-inline-style | The line style of the two inline borders. One value styles both; two values give the start and then the end. [none, hidden, dotted, dashed, solid, double, ...; up to 2 values] | box: padding = 12 border = "5px solid #0891b2" border inline style = "solid dotted" content = "solid start, dotted end" end |
border inline colorرنگ کادر خطی border-inline-color | The color of the two inline borders. One value colors both; two values give the start and then the end. [color; up to 2 values] | box: padding = 12 border = "5px solid #e2e8f0" border inline color = "#16a34a #ca8a04" content = "start green, end yellow" end |
border inline startکادر خطی آغاز border-inline-start | Sets the width, style and color of the border at the side where a line of text starts (left in English, right in Persian) in one value. It follows the writing direction, so the same code works in left to right and right to left pages. [CSS-wide keywords only] | box: padding = 12 border inline start = "8px solid #0891b2" content = "inline-start" end |
border inline start widthضخامت کادر خطی آغاز border-inline-start-width | The thickness of the border at the side where a line of text starts (left in English, right in Persian): a length, or thin, medium or thick. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #0891b2" border inline start width = 13 content = "inline-start 13px" end |
border inline start styleسبک کادر خطی آغاز border-inline-start-style | The line style of the border at the side where a line of text starts (left in English, right in Persian): none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #0891b2" border inline start style = double content = "inline-start double" end |
border inline start colorرنگ کادر خطی آغاز border-inline-start-color | The color of the border at the side where a line of text starts (left in English, right in Persian). It takes any color. [color] | box: padding = 12 border = "4px solid #e2e8f0" border inline start color = "#4f46e5" content = "inline-start color" end |
border inline endکادر خطی انتها border-inline-end | Sets the width, style and color of the border at the side where a line of text ends (right in English, left in Persian) in one value. It follows the writing direction, so the same code works in left to right and right to left pages. [CSS-wide keywords only] | box: padding = 12 border inline end = "10px solid #16a34a" content = "inline-end" end |
border inline end widthضخامت کادر خطی انتها border-inline-end-width | The thickness of the border at the side where a line of text ends (right in English, left in Persian): a length, or thin, medium or thick. [length / thin, medium, thick] | box: padding = 12 border = "1px solid #16a34a" border inline end width = 15 content = "inline-end 15px" end |
border inline end styleسبک کادر خطی انتها border-inline-end-style | The line style of the border at the side where a line of text ends (right in English, left in Persian): none, hidden, dotted, dashed, solid, double, groove, ridge, inset or outset. [none, hidden, dotted, dashed, solid, double, ...] | box: padding = 12 border = "6px solid #16a34a" border inline end style = ridge content = "inline-end ridge" end |
border inline end colorرنگ کادر خطی انتها border-inline-end-color | The color of the border at the side where a line of text ends (right in English, left in Persian). It takes any color. [color] | box: padding = 12 border = "4px solid #e2e8f0" border inline end color = "#0d9488" content = "inline-end color" end |
Corners
| Property | What it does and what it accepts | Example |
|---|---|---|
border radiusگردی کادر border-radius | Rounds the corners. One value rounds all four; two values are top left with bottom right, then top right with bottom left; four go clockwise from the top left. A / gives separate horizontal and vertical radii for oval corners, and 50% on a square makes a circle. [length / percentage; up to 4 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border radius = "24px 4px" content = "24px 4px" end |
border top left radiusگردی کادر بالا چپ border-top-left-radius | Rounds only the top left corner. One value makes it circular; two values (40px 20px) make an oval with a horizontal and then a vertical radius. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border top left radius = "40px 20px" content = "top left 40px 20px" end |
border top right radiusگردی کادر بالا راست border-top-right-radius | Rounds only the top right corner. One value makes it circular; two values (40px 20px) make an oval with a horizontal and then a vertical radius. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border top right radius = 30 content = "top right 30" end |
border bottom left radiusگردی کادر پایین چپ border-bottom-left-radius | Rounds only the bottom left corner. One value makes it circular; two values (40px 20px) make an oval with a horizontal and then a vertical radius. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border bottom left radius = "50%" content = "bottom left 50%" end |
border bottom right radiusگردی کادر پایین راست border-bottom-right-radius | Rounds only the bottom right corner. One value makes it circular; two values (40px 20px) make an oval with a horizontal and then a vertical radius. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border bottom right radius = "60px 10px" content = "bottom right 60px 10px" end |
border start start radiusگردی کادر آغاز آغاز border-start-start-radius | Rounds the corner at the start of the block side at the start of the inline side (top left in English, top right in Persian). It follows the writing direction, like the other logical properties. One or two values, as for the physical corners. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border start start radius = 28 content = "start-start" end |
border start end radiusگردی کادر آغاز انتها border-start-end-radius | Rounds the corner at the block start with the inline end (top right in English, top left in Persian). It follows the writing direction, like the other logical properties. One or two values, as for the physical corners. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border start end radius = "36px 12px" content = "start-end" end |
border end start radiusگردی کادر انتها آغاز border-end-start-radius | Rounds the corner at the block end with the inline start (bottom left in English, bottom right in Persian). It follows the writing direction, like the other logical properties. One or two values, as for the physical corners. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border end start radius = "50%" content = "end-start" end |
border end end radiusگردی کادر انتها انتها border-end-end-radius | Rounds the corner at the block end with the inline end (bottom right in English, bottom left in Persian). It follows the writing direction, like the other logical properties. One or two values, as for the physical corners. [length / percentage; up to 2 values] | box: width = 120 height = 70 padding = 8 background = "#bae6fd" border end end radius = 40 content = "end-end" end |
Border image
| Property | What it does and what it accepts | Example |
|---|---|---|
border imageتصویر کادر border-image | The shorthand for the border image: a source, then a slice, then the width and outset after /, then the repeat, for example linear-gradient(#f59e0b, #db2777) 1 / 8px. The border itself must have a width, and a transparent color lets the image show. [CSS-wide keywords only] | box: padding = 12 border = "14px solid transparent" border image = "linear-gradient(135deg, #f59e0b, #db2777) 1" content = "gradient frame" end |
border image sourceمنبع تصویر کادر border-image-source | The image drawn as the border: a url(...) (a data URL works too), a gradient, or none. [image] | box: padding = 12 border = "14px solid transparent" border image source = "linear-gradient(90deg, #22d3ee, #6366f1)" border image slice = 1 content = "image source" end |
border image sliceبرش تصویر کادر border-image-slice | Where the image is cut into nine parts: up to four numbers or percentages measured from the top, right, bottom and left edges of the image. The corners are used as they are and the edges are repeated or stretched. The word fill keeps the middle part too. [number / percentage; up to 5 values] | box: padding = 12 border = "14px solid transparent" border image source = "repeating-linear-gradient(45deg, #0f766e 0 6px, #99f6e4 6px 12px)" border image slice = 2 content = "slice 2" end |
border image widthضخامت تصویر کادر border-image-width | The size of the area the image is drawn into, one to four values: a length, a percentage of the box, or a plain number that multiplies the border width. The default is 1. [length / percentage / number; up to 4 values] | box: padding = 12 border = "14px solid transparent" border image source = "linear-gradient(#f43f5e, #f59e0b)" border image slice = 1 border image width = 2 content = "twice the border width" end |
border image outsetبیرونزدگی تصویر کادر border-image-outset | How far the image is pushed outward past the border box, one to four values as a length or a plain number of border widths. It does not take any room in the layout. [length / number; up to 4 values] | box: margin = 16 padding = 12 border = "14px solid transparent" border image source = "linear-gradient(135deg, #16a34a, #0891b2)" border image slice = 1 border image outset = 8 content = "pushed out 8px" end |
border image repeatتکرار تصویر کادر border-image-repeat | How the edge pieces fill their sides, one value for both directions or two (horizontal, vertical): stretch (the default), repeat, round (repeat, resized to fit a whole number of times) and space (repeat with gaps). [up to 2 values] | box: padding = 12 border = "14px solid transparent" border image source = "repeating-linear-gradient(90deg, #7c3aed 0 10px, #ddd6fe 10px 20px)" border image slice = 1 border image repeat = round content = "round" end |
Outline
| Property | What it does and what it accepts | Example |
|---|---|---|
outlineدورخط outline | Draws a line around the outside of the element, in the same width style color form as border. It takes no room in the layout and can follow rounded corners in current browsers. Focus rings are outlines. [CSS-wide keywords only] | box: padding = 12 outline = "3px solid #2563eb" content = "outline" end |
outline widthضخامت دورخط outline-width | The thickness of the outline: a length, or thin, medium or thick. It has no effect while the style is none. [length / thin, medium, thick] | box: padding = 12 outline style = solid outline color = "#ea580c" outline width = 6 content = "6px outline" end |
outline styleسبک دورخط outline-style | The line style of the outline: the same values as border styles, and also auto, which asks the browser for its own native focus ring. [auto, none, hidden, dotted, dashed, solid, ...] | box: padding = 12 outline style = dotted outline width = 3 outline color = "#7c3aed" content = "dotted outline" end |
outline colorرنگ دورخط outline-color | The color of the outline. It takes any color. Keep a focus outline easy to see against both the element and the page behind it. [color] | box: padding = 12 outline style = solid outline width = 3 outline color = "#db2777" content = "pink outline" end |
outline offsetفاصله دورخط outline-offset | The gap between the outline and the edge of the border box, as a length. A positive value moves the outline away, a negative one pulls it inside. The default is 0. [length] | box: padding = 12 margin = 10 outline = "2px dashed #0f766e" outline offset = 8 content = "8px away" end |
Shadow, breaks and corner shapes
| Property | What it does and what it accepts | Example |
|---|---|---|
box decoration breakشکستن تزیین جعبه box-decoration-break | What happens to the padding, border and background of an element that breaks across lines or columns. slice (the default) cuts one piece into parts and clone gives every part its own full decoration. [slice, clone] | paragraph: width = 180 content = "A " span: box decoration break = clone background = "#fde68a" padding = "0 8px" border radius = 6 content = "highlight that wraps over two lines" end end |
box shadowسایه کادر box-shadow | Draws one or more shadows around the box. Each shadow is x y blur spread color: the horizontal and vertical offset, how soft the edge is, how much larger or smaller it is, and its color. The word inset draws it inside. Separate several shadows with commas; the first is on top. [comma list] | box: padding = 16 border radius = 10 box shadow = "0 6px 16px rgb(0 0 0 / 20%), inset 0 0 0 1px #cbd5e1" content = "two shadows" end |
corner shapeشکل گوشه corner-shape | Changes the shape of the corners that border radius rounds, one to four values: round (the default), squircle, bevel, scoop, notch, square or superellipse(). It is new and works only in Chromium browsers for now; elsewhere the corners stay round. [up to 4 of round, scoop, bevel, notch, square, squircle, superellipse()] | box: padding = 16 border radius = 24 corner shape = "squircle" background = "#0ea5e9" color = "white" content = "squircle" end |
corner top left shapeشکل گوشه بالا چپ corner-top-left-shape | The shape of the top left corner only: round, squircle, bevel, scoop, notch, square or superellipse(). It needs a border radius to show, and only Chromium browsers draw it for now. [a corner shape keyword or superellipse()] | box: padding = 16 border radius = 28 corner top left shape = scoop background = "#ea580c" color = "white" content = "top left: scoop" end |
corner top right shapeشکل گوشه بالا راست corner-top-right-shape | The shape of the top right corner only: round, squircle, bevel, scoop, notch, square or superellipse(). It needs a border radius to show, and only Chromium browsers draw it for now. [a corner shape keyword or superellipse()] | box: padding = 16 border radius = 28 corner top right shape = bevel background = "#16a34a" color = "white" content = "top right: bevel" end |
corner bottom left shapeشکل گوشه پایین چپ corner-bottom-left-shape | The shape of the bottom left corner only: round, squircle, bevel, scoop, notch, square or superellipse(). It needs a border radius to show, and only Chromium browsers draw it for now. [a corner shape keyword or superellipse()] | box: padding = 16 border radius = 28 corner bottom left shape = notch background = "#7c3aed" color = "white" content = "bottom left: notch" end |
corner bottom right shapeشکل گوشه پایین راست corner-bottom-right-shape | The shape of the bottom right corner only: round, squircle, bevel, scoop, notch, square or superellipse(). It needs a border radius to show, and only Chromium browsers draw it for now. [a corner shape keyword or superellipse()] | box: padding = 16 border radius = 28 corner bottom right shape = squircle background = "#db2777" color = "white" content = "bottom right: squircle" end |
Try it yourself
- Make a notification box with a thick
border inline startin red, then put it inside a box withdir = "rtl"and check that the stripe moves to the right by itself. - Build a button with a pill shape, a
box shadowthat gets smaller onactive, and a focus ring of a different color. - Make a gradient border with
border imageand a slice of 1, and try to round its corners. What happens, and what can you use instead? - Add a fourth slider to the shadow lab that changes the spread, and a checkbox that adds the word
inset.