Canvas Fill and Stroke
fillStyle and strokeStyle set the paint canvas uses, while fill() paints a shape's interior and stroke() paints only its outline.
Two Ways to Paint a Shape
Every path you build with moveTo()/lineTo()/arc() and similar methods can be rendered in two different ways. fill() treats the path as the boundary of a shape and paints every pixel inside that boundary using the current fillStyle. stroke() instead paints a line that traces the path itself using strokeStyle and lineWidth, leaving the interior untouched. Nothing stops you from calling both on the same path to get a filled shape with a visible outline.
fillStyle and strokeStyle
fillStyle and strokeStyle are context properties, not method arguments - you set them once and they apply to every fill() or stroke() call made afterward, until you change them again. Both properties accept anything CSS accepts for a color: keywords like "tomato", hex codes like "#ff6347", rgb()/rgba() functions, hsl() functions, and even gradient or pattern objects created with createLinearGradient(), createRadialGradient(), or createPattern().
- fillStyle / strokeStyle accept hex codes, named colors, rgb()/rgba(), hsl(), gradients, and patterns.
- fill() paints the inside of the current path using fillStyle; it treats an open path as closed for this purpose.
- stroke() paints a line following the current path using strokeStyle and lineWidth.
- Calling both fill() and stroke() on the same path draws a filled shape with an outline.
- The default fillStyle and strokeStyle are both solid black ("#000000").
Example
<!DOCTYPE html>
<html>
<body>
<canvas id="fillVsStroke" width="320" height="140"></canvas>
<script>
const ctx = document.getElementById("fillVsStroke").getContext("2d");
ctx.beginPath();
ctx.rect(20, 20, 100, 100);
ctx.fillStyle = "mediumseagreen";
ctx.fill();
ctx.beginPath();
ctx.rect(160, 20, 100, 100);
ctx.strokeStyle = "mediumseagreen";
ctx.lineWidth = 4;
ctx.stroke();
</script>
</body>
</html>Layering Fill and Stroke
Example
<!DOCTYPE html>
<html>
<body>
<canvas id="gradientFill" width="300" height="120"></canvas>
<script>
const ctx = document.getElementById("gradientFill").getContext("2d");
const gradient = ctx.createLinearGradient(0, 0, 300, 0);
gradient.addColorStop(0, "#ff7e5f");
gradient.addColorStop(1, "#feb47b");
ctx.beginPath();
ctx.rect(10, 10, 280, 100);
ctx.fillStyle = gradient;
ctx.fill();
</script>
</body>
</html>Example
<!DOCTYPE html>
<html>
<body>
<canvas id="filledCircle" width="200" height="200"></canvas>
<script>
const ctx = document.getElementById("filledCircle").getContext("2d");
ctx.beginPath();
ctx.arc(100, 100, 70, 0, Math.PI * 2);
ctx.fillStyle = "lightskyblue";
ctx.fill();
ctx.strokeStyle = "navy";
ctx.lineWidth = 6;
ctx.stroke();
</script>
</body>
</html>Exercise: Canvas Fill and Stroke
What is the default fillStyle color if none has been set?