HTML, CSS, SVG, D3.js, style, attr

Hongtao Hao / 2021-03-23


I was very confused when styling HTML elements and SVG, so I decided to make things clearer for myself as well as for others through this post.

SVG is just an HTML element #

First of all, let’s think about the relationship between HTML and SVG.

Let’s first take a look at this example:

<div class = "demo1" style="text-align: center">
  <p style="color:red">This is a paragraph in red</p>
  <img src="example.jpg" alt="an explanation">
  <p>The above image is from <a href="https://www.example.com/"> Here</a>
  <svg id="demo" width="500" height="100" style="background-color">
      <rect x="200" y="30" width="100" height="70" style="fill: red"></rect>
    </svg>
</div>

In the above example, div, p, img, a, and svg are all HTML elements. For a complete list of HTML elements, see this reference by Mozilla Developer Network Web Docs. In this sense, svg is subordinate to HTML.

HTML elements can contain attributes . Quoting Jonathan Soma , “attributes are anything that gets an equal sign in the HTML”. In the above code chunk, class = "demo1", style="text-align: center", src="example.jpg", and href="https://www.example.com/" are all examples of attributes for HTML elements. The most frequently used attributes are class, id, and style. For a complete list of HTML attributes, see HTML Attribute Reference on w3schools.com .

According to Scott Murray (2017, p. 24), HTML element attributes have the following syntax:

<tagname property="value"></tagname>

A pair of property="value" is called an attribute. Here, propery is an HTML property, and value is an HTML value.

CSS #

However, there is an outlier: style.

According to w3schools.com , HTML style attribute has the following syntax:

<tagname style="property:value;">

Here, however, the property is a CSS property, and the value is a CSS value. To put it simply, HTML style is in the hands of CSS .

SVG is more than just an HTML element #

To make things more complicated, SVG is a more serious outlier! It has its own system similar to that of HTML.

Yes, svg can be seen merely as an HTML element, parallel to p, img, and div. However, different from other HTML elements, svg has its own elements: A lot of them . According to Shirley Wu , the most frequently used SVG elements are <rect>, <circle>, <path>, and <text>.

Similar to HTML elements, each SVG element can have attributes. For example:

<rect x="200" y="30" width="100" height="70" style="fill: red"></rect>

x, y, width, height, and style are all attributes for SVG elements.

The default style of SVG is “a black fill with no stroke” (Murray, 2017, p.56), so we need to apply styles to the SVG elements we created, through two ways:

Styling with SVG attributes #

We can use attributes such as fill, stroke, stroke-width, and opacity. These attributes are parallel to x, y, cx, cy, width, and height.

Similar to HTML attributes, SVG attributes has the following syntax:

<SVG-element property="value">

A pair of property="value" is called an attribute. Here, propery is an SVG property, and value is an SVG value.

For exmaple,

<svg width="550" height="100" style="background-color: lightblue; 
        margin-bottom: 20px;>
  <rect x="200" y="20" width="100" height="70" 
  fill="orange" stroke="blue" stroke-width="3px">
  </rect>
</svg>

which results in:

Please note that I didn’t see other people naming an SVG attribute pair as property="value". I “invented” it myself to compare it with HTML attributes.

For a complete list of SVG attributes, see SVG Attribute reference by Mozilla Developer Network Web Docs.

Styling with the style and/or class attribute #

To make things complicated, SVG elements have a style attribute , which, similar to HTML style attribute, has a different syntax:

<SVG-element style="property:value;">

Here, the property is an SVG property, and the value is an SVG value.

The above <rect> can be styled this way as well:

<svg width="550" height="100" style="background-color: lightblue; 
        margin-bottom: 20px;">
  <rect x="200" y="20" width="100" height="70" 
  style="fill:orange; stroke:blue; stroke-width: 3px;">
  </rect>
</svg>

To make things even more complicated, SVG has a class attribute .

If you have lots of styling for an SVG element, it’s more desirable to assign a class to this element, and then define this class using a CSS stylesheet.

The above <rect> can be created this way:

<style type="text/css">
      .rect-style {
        fill: orange;
        stroke: blue;
        stroke-width: 3px;
      }
</style>

<svg width="550" height="100" style="background-color: lightblue; 
        margin-bottom: 20px;">
  <rect x="200" y="20" width="100" height="70" class="rect-style"></rect>
</svg>

Here, two things might be worth mentioning:

  1. Even though you are styling the SVG element using CSS, you are supposed to use SVG attributes , rather than CSS properties . For example, in the above code chunk, we used fill, and stroke. These are not CSS properties; the closest CSS equivalents are background-color and border (Murray, 2017, p. 58).

  2. You should style <svg> using CSS properties, rather than SVG attributes. This is because the tag of <svg> is still an HTML element, not an SVG element.

D3.js #

We can create the above visualization with D3.js this way:

<script src="https://d3js.org/d3.v6.min.js"></script>

<div id="div"></div>

<script>
  const svg = d3.select("#div")
                .append("svg")
                .attr("width", "550")
                .attr("height", "100")
                .style("background-color", "lightblue")
                .attr("id", "demo1")

  let rect = d3.select("#demo1")
               .append("rect")
               .attr("x", "200")
               .attr("y", "20")
               .attr("width", "100")
               .attr("height", "70")
               .attr("fill", "orange")
               .attr("stroke", "blue")
               .attr("stroke-width", "3px")
</script>

Two things are worth mentioning in the above chunk of codes:

  1. Why do we have to use .style("background-color", "lightblue'') when styling the svg? Because svg here is still an HTML element. You are supposed to style with CSS attributes. background-color is not a CSS attribute.

  2. When styling the rect, you can use either attr("fill", "orange") or style("fill", "orange"). This is because <rect fill="orange"></rect> = <rect style="fill:orange".

Also, when using CSS stylesheet to define the style of an SVG element, keep in mind that the <font> attribute is being deprecated .

References #

Murray, S. (2017). Interactive data visualization for the web: an introduction to designing with D3 . " O’Reilly Media, Inc.".

Using .attr and .style , by Jonathan Soma

Ordinal Scales , from Using D3.js

Last modified on 2021-10-05