admin 管理员组

文章数量: 1086019

How can I apply Tailwind CSS classes to SVG elements using D3.js?

I'm working on a web project where I need to use both Tailwind CSS and D3.js. However, I'm having trouble applying Tailwind CSS classes to SVG elements using the .attr() method in D3.js.

For example, when I try to apply the fill-red-500 class to a rectangle using d3.select('rect').attr('class', 'fill-red-500'), the class doesn't seem to be applied correctly, and the rectangle doesn't change color.

I have confirmed that my Tailwind configuration file is correct since I was able to use it successfully with tooltip.html("<div class="bg-red-500">hello world</div>"). However, I don't want to use .html() all the time because I am using D3.js to make coding charts easier.

I have also tried different approaches, but none of them seem to work. I have verified that the class is shown in devtools, but no styles appear on the screen.

My project uses Vite as the bundler, and I am writing vanilla JS with D3.js. I am using Tailwind CSS without any CSS applied to the entire project. The browser I am testing on is Chrome, and my operating system is Windows 11.

Is there a way to make Tailwind read the string inside the .attr("class", "tailwindclass") method in D3.js? I am open to any solution, even changing the configuration. Ideally, the solution should also work programmatically. For example, something like () => { if(num>60) {return "fill-green-500"} return "fill-red-500" } should work fine.

Please let me know if I need to provide any additional information.

How can I apply Tailwind CSS classes to SVG elements using D3.js?

I'm working on a web project where I need to use both Tailwind CSS and D3.js. However, I'm having trouble applying Tailwind CSS classes to SVG elements using the .attr() method in D3.js.

For example, when I try to apply the fill-red-500 class to a rectangle using d3.select('rect').attr('class', 'fill-red-500'), the class doesn't seem to be applied correctly, and the rectangle doesn't change color.

I have confirmed that my Tailwind configuration file is correct since I was able to use it successfully with tooltip.html("<div class="bg-red-500">hello world</div>"). However, I don't want to use .html() all the time because I am using D3.js to make coding charts easier.

I have also tried different approaches, but none of them seem to work. I have verified that the class is shown in devtools, but no styles appear on the screen.

My project uses Vite as the bundler, and I am writing vanilla JS with D3.js. I am using Tailwind CSS without any CSS applied to the entire project. The browser I am testing on is Chrome, and my operating system is Windows 11.

Is there a way to make Tailwind read the string inside the .attr("class", "tailwindclass") method in D3.js? I am open to any solution, even changing the configuration. Ideally, the solution should also work programmatically. For example, something like () => { if(num>60) {return "fill-green-500"} return "fill-red-500" } should work fine.

Please let me know if I need to provide any additional information.

Share Improve this question edited Mar 11, 2023 at 14:49 asked Mar 7, 2023 at 19:43 user19485937user19485937
Add a ment  | 

1 Answer 1

Reset to default 11

the same scenario happened also to me, here is a simple solution I found out:

TLDR:

To apply Tailwind CSS classes to SVG elements using D3.js,
you can use the .classed() method in D3.js
instead of the .attr() method.


DETAILED ANSWER:

The .classed() method adds classes to the selected D3.js elements.


Somehow seems that the tailwind's terminal mand read it fine,
in my case was:

npx tailwindcss -i ./input.css -o ./dist/output.css --watch

using Vite as a bundler like you, and Normal Javascript (Vanilla).


as for my tailwindcss configuration, here it is:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./*.{html,js}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

as you see, I made the .content object read also the javascript files present in the directory.
(using "./*.{html,js}" regex)

but as I read from your question, the problem isn't there... I just pointed out to the future devs that read this, maybe can be helpful


Here is an example code snippet that demonstrates how to use .classed() method to apply a Tailwind CSS class to an SVG rectangle element:

d3.select('svg')
  .append("rect")
  .classed('fill-red-500', true) // here the "class" working in tailwind
  .attr("x", 10)
  .attr("y", 10)
  .attr("height", 50)
  .attr("width", 50)

console.clear() // just for the snippet, you don't need it
<!-- don't use this script in production, this is only for stackoverflow snippet.... use npm instead -->
<script src="https://cdnjs.cloudflare./ajax/libs/d3/7.8.2/d3.min.js" integrity="sha512-oKI0pS1ut+mxQZdqnD3w9fqArLyILRsT3Dx0B+8RVEXzEk3aNK3J3pWlaGJ8MtTs1oiwyXDAH6hG6jy1sY0YqA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss."></script>

<svg height="300" width="300"></svg>

as you see in the snippet before, this method .classed('fill-red-500', true) needs two parameters:

  1. a string with the name of the tailwind class (similar to the .attr() you already know well)
  2. a boolean.
    • if you pass true then the class is applied to the svg element
      (for get you the idea: is like using the .classList.add() in vanilla JS)
    • if you pass false then the class isn't applied to the svg element
      (for get you the idea: is like using the .classList.remove() in vanilla JS)

Isn't Cool?

if you have some experience with d3js,
you definitely know that it is mon to use callback functions,
like this () => {}.


and if you use the .data(dataset).enter() methods to the SVG elements (you should do it to gain the advantages of D3js),
then you can also use (d) => {}, so then you can do some calculations and return something
(in this case, can be true or false... if you return something else like a string or numbers, from what I know javascript tend to behave like is returned a true unless is an empty string "" or null or undefined)

The data() method is used to attach the data to those elements. The dataset array is passed as an argument to the method.


Here is an example where you can also use a function to dynamically set the class based on some condition:

  .classed('fill-green-500', (num) => num > 50) // if num is greater than 50 then add green
  .classed('fill-red-500', (num) => num <= 50); // if num is less or equal to 50 then add the class red.

IDE Intellisense

and what about the IntelliSense?

it won't show the popup of suggestions by default.


and for this reason, I tried to open an issue on the tailwind GitHub page for you...
In the end everything is possible :) , and I got a solution for you!


and what it is?

you need to change the tailwind configuration by following the ment in this other issue written by one the experts there: configuring the tailwindCSS.experimental.classRegex option.


how I can find this option in my VSCODE?

  • You just have to first open your IDE on any file (it doesn't matter the type of the file)
  • CTRL+SHIFT+P

    and as you see it will open a list of shortcuts
  • search for "setting" and then ENTER
  • you will see an interface with a search bar at the top.
    type "TailwindCSS"
  • in the list below scroll until you find an item with text TailwindCSS > Experimental: Class Regex.
  • now you can add your regex here inside the brackets following the instructions here configuring the tailwindCSS.experimental.classRegex option.

Here is the config created for you:

"tailwindCSS.experimental.classRegex": [
   "classed\\(\"([^)]*)\"\\)"
]

as you see here, is an array of regexes.


result on the IDE:

本文标签: javascriptHow can I apply Tailwind CSS classes to SVG elements using D3js (in VSCODE)Stack Overflow