Using Vue.js: Is there a way to apply scoped CSS to dynamically generated HTML content?

Summary:

I'm struggling to apply scoped CSS styling to dynamically generated HTML in my Vue component. The generated HTML lacks the necessary data attribute for scoping, making it difficult to style with scoped CSS rules.

Details:

In a function called highlight, I create an HTML string that highlights occurrences of a search term by wrapping them in <span class="match"> tags. However, due to the manual nature of constructing this string, the <span> elements do not have the required data attribute needed for scoped CSS in Vue components. As a result, I am unable to style these matches using scoped CSS and resort to using unscoped CSS, which is not ideal. Is there a more Vue-specific approach to achieve this styling within the scoped environment? Here is the code snippet for the highlight function:

// Source: http://stackoverflow.com/a/280805/2874789
function highlight(data, search) {
    return data.replace(
      new RegExp("(" + preg_quote(search) + ")", 'gi'),
      "<span class=match>$1</span>"
    );
}

(preg_quote is simply a function used for escaping characters)

Appreciate any assistance!

Answer №1

Generating Content Dynamically When creating DOM content with v-html, scoped styles do not affect it, but you can still apply styles using deep selectors.

There doesn't seem to be a specific VueJS method for this. Your best bet might be to either inline styling within your highlight function's output or use a global class.

function highlight(data, search) {
  return data.replace(
    new RegExp("(" + preg_quote(search) + ")", 'gi'),
     "<span class=match>$1</span>"
    );
}


<style>
  .match {
    color: yellow;
  }
</style>

or

function highlight(data, search) {
  return data.replace(
    new RegExp("(" + preg_quote(search) + ")", 'gi'),
     "<span style="{ color: yellow }">$1</span>"
    );
}

You could also explore deep selectors, although I don't have much experience with them myself.

Check out more about scoped CSS in Vue.js here.

Answer №2

Recently encountered a similar situation. A simple solution is to avoid scoping it and instead, namespace your markup and CSS classes. This prevents them from being inherited by other modules, saving you unnecessary hassle of using JavaScript for this task.

Answer №3

This is a fascinating situation.

Although using only scoped styles may not be enough, we can work around it by adding an extra <style> element with css modules (which are also scoped).

My thought process went like this:

<style scoped>
  ...
</style>

<style module>
  .match {
    color: red;
  }
</style>

Then, in your replace function, you can use:

`<span class="${this.$style.match}">...</span>`

To learn more about vue-loader's CSS module support, check out:

Answer №4

Interesting inquiry! I encountered a similar issue and managed to find a creative solution. Excited to share it with you!

Imagine your template resembles the following:

<template>
  <div class="match">
    <div v-html="<span>hello world</span>"></div>
  </div>
</template>

Simply modify this segment:

<style scoped>
.match span {
    color: yellow;
}
</style>

compiled output: `.match span[data-v-f3f3eg9] { color: yellow; }`

to

<style scoped>
.match >>> span {
    color: yellow;
}
</style>

compiled output: `.match[data-v-f3f3eg9] span { color: yellow; }`

Observe the distinction between the two outputs. You'll understand better once you compare. For more information, refer to the Vue Loader documentation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to choose a single item from an array using jQuery?

Within an array, I have IDs and descriptions like: var tablica = [{"3":"asdasd asd"},{"19":"asddas fff"},{"111111":"adas asf asdff ff"},{"4":"re"},{"5":"asdasd"},{"6":"we"},{"7":"asdasdgg"},{"9":"asdasdasd"},{"16":"sdads"},{"10":"asdgg"},{"11":"ggg"}]; ...

A guide to retrieve data attributes in Vue.js

When my button is clicked, a modal pops up with data passed through data attributes. The button code looks like this: <button class="edit-modal btn btn-info" data-toggle="modal" data-target="#editModal" :data-id=item.id ...

Updating the $_GET parameter using JQuery when a button is clicked

I'm working on implementing a feature where a series of buttons can update the $_GET['year'] variable on my website. These buttons should function across different pages within my website, such as: example.com example.com/?search=foo exa ...

Attempting to retrieve currentScript is causing a typeError to be thrown

I'm attempting to access a custom attribute that I added to my script tag: <script type="text/javascript" src="https://.../mysource.js" customdata="some_value"></script> To make this work on Internet Explorer ...

Matter of Representing Nested For Loops in Javascript Arrays

When I have two arrays that intersect at certain elements, the resulting function should ideally output A, B, Y. However, in this case, it displays all possible combinations of lista.length * listb.length. <script> window.onload = function(){ ...

What could be causing the value of response.name to be undefined in this situation?

Despite extensively searching through various StackOverflow threads, none of the suggested solutions seemed to work for my specific scenario. Upon analyzing the response using console.log(response), I received an "Object Object" message. I am puzzled as to ...

Attaching a click event to an input field

Seeking to serve html files from the server without relying on template engines. Below is the script used to start the server. // script.js const express = require("express"); const bodyParser = require("body-parser"); const app = express(); app.use(expr ...

Caution: A duplicate key was found in ReactJS when attempting to flatten children

Currently, I am utilizing Tabs from Material UI to showcase a List component that is filtered by the tab. Take a look at the code snippet below from my Container Component: <Tabs className="DrawerTabs" ...

Incorporating Content-Disposition headers to enable the file to be both downloaded and opened

I'm having trouble allowing users to both view and download files on a web page. I've tried setting headers and using JavaScript, but can't seem to get it right. My goal is to have an HTML page with two links for each file - one to open in ...

Utilizing component data in Vue.js to configure the router-link attribute

Is there a way to pass component data in <router-link to="...">? Here's an example: var data = { files: [{ name: "test", path: "/test" }] }; var component = { data: function() { return data; ...

What exactly does Container-Based Authorization entail?

Did you know that the "XMLHttpRequest" object includes a method called "open," which has the option to supply a username and password? These parameters can be used for requests that require container-based authentication. Here is the method signature: op ...

NodeJs encountered an issue due to the absence of defined username and data

I am facing an issue while trying to open the places.ejs file by clicking the submit button on the show.js page. Similar to how the show.ejs page opens upon clicking the submit button on the new.ejs file, I am encountering a reference error. Any assistance ...

Steps for running the function saved in variable `x`, with the value `function(){alert('a')}` assigned to it

How can I achieve this using javascript? var x = 'function(){ ... }' x = x.toFunction(); x(); Previously, I used var x = '...'; eval(x), but I have learned that this method is inefficient and slow. To provide some context, my goal is ...

Step-by-step guide on reactivating an inactive text-field with just one click

I am working with Vuetify and have a scenario where I have two text fields. When one field is clicked, I want the other field to be disabled. I have successfully implemented this functionality so far. However, I now need to make it so that when the disable ...

What is the best way to conceal an element in jQuery by utilizing a JavaScript variable?

I have encountered a challenge in concealing this specific page element in the provided html code <table cellspacing=5 cellpadding=3> <tr> <td id="lst2"><h4>Apple Ipad for sale N70,000 (negotiable)</h4></td> & ...

When attempting to render 2 components based on the results of 2 fetch calls using Promise.allSettled(), I encounter difficulties if one of them throws an error

I have encountered an issue while using Promise.allSettled() in sending two fetch calls. I am rendering components based on the result - a component with data if it is fulfilled and an error component if rejected. However, when one of the fetch calls throw ...

Need help resolving the issue of "Type Property '' does not exist on type 'IntrinsicAttributes & Function'? Let's find a solution together

Looking at my parent component below: import FilterComponent from 'filter/filterComponent' const handleReload = useCallback( (event: MouseEvent) => { event.preventDefault(); // implement logic here }, [Reload, Fetch ...

Unable to attach event listener within Shadcn Vue component in the latest version of Jhipster 8

My company's requirements dictate that I use the Vue 3 and Jhipster 8.0.0 framework. I have successfully installed the Shadcn Vue and it displays properly, but I am unable to assign any event listeners. <script setup lang="ts"> im ...

Creating background color animations with Jquery hover

<div class="post_each"> <h1 class="post_title">Single Room Apartments</h1> <img class="thumb" src="1.jpg"/> <img class="thumb" src="1.jpg"/> <img class="thumb" src="1.jpg"/> <img class="thumb last" ...

What is the method for inserting form control values into a QueryString within HTML code?

Struggling with passing HTML form control values into a QueryString for page redirection. While I can easily input static values into a QueryString and retrieve them using PHP's GET method, I am encountering difficulties when it comes to dynamic valu ...