question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[SOLVED] Import only the Tooltip component/directive with scoped CSS

See original GitHub issue

First of all, congrats to everyone involved in this project, it’s awesome.

I see the library supports importing only the desired components/directives. By that I mean it’s officially supported to import just the v-b-tooltip directive (https://bootstrap-vue.js.org/docs/components/tooltip/#importing-individual-directives):

import { VBTooltip } from 'bootstrap-vue'
// Note: Vue automatically prefixes the directive name with 'v-'
Vue.directive('b-tooltip', VBTooltip)

Of course, for this to work you also need CSS:

import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";

But it’s overkill to import the entire bootstrap AND bootstrap-vue CSS files just for tooltips to work. Also, even if that was not an issue, importing CSS like that means it will pollute the global space. So I tried using scoped styles in my component:

<style scoped src="bootstrap/dist/css/bootstrap.css" />
<style scoped src="bootstrap-vue/dist/bootstrap-vue.css" />

For this to work with the Tooltip, you have to pass an element for it to mount to, because otherwise it will be mounted on body, which will be outside the scope of the component.

But even if doing so, I get a broken tooltip like this (note the white text on the right, that’s the tooltip):

image

Debugging this further, I noticed that even tough my page is loading the correct styles AND it’s scoping them, the tooltip element in itself doesn’t have the data-* attribute to make it work with the scoped CSS… (note the outer element has the data- attribute, but the tooltip div doesn’t):

image

So, this is the CSS being included in the page (note it’s scoped):

.tooltip[data-v-c2ed4f50] {
  position: absolute;
  z-index: 1070;
  display: block;
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  font-style: normal;
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  text-align: start;
  text-decoration: none;
  text-shadow: none;
  text-transform: none;
  letter-spacing: normal;
  word-break: normal;
  word-spacing: normal;
  white-space: normal;
  line-break: auto;
  font-size: 14px;
  font-size: 0.875rem;
  word-wrap: break-word;
  opacity: 0;
}
.tooltip.show[data-v-c2ed4f50] {
  opacity: 0.9;
}
.tooltip .arrow[data-v-c2ed4f50] {
  position: absolute;
  display: block;
  width: 12.8px;
  width: 0.8rem;
  height: 6.4px;
  height: 0.4rem;
}
.tooltip .arrow[data-v-c2ed4f50]::before {
  position: absolute;
  content: "";
  border-color: transparent;
  border-style: solid;
}
.bs-tooltip-top[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="top"][data-v-c2ed4f50] {
  padding: 6.4px 0;
  padding: 0.4rem 0;
}
.bs-tooltip-top .arrow[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="top"] .arrow[data-v-c2ed4f50] {
  bottom: 0;
}
.bs-tooltip-top .arrow[data-v-c2ed4f50]::before, .bs-tooltip-auto[x-placement^="top"] .arrow[data-v-c2ed4f50]::before {
  top: 0;
  border-width: 6.4px 6.4px 0;
  border-width: 0.4rem 0.4rem 0;
  border-top-color: #000;
}
.bs-tooltip-right[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="right"][data-v-c2ed4f50] {
  padding: 0 6.4px;
  padding: 0 0.4rem;
}
.bs-tooltip-right .arrow[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="right"] .arrow[data-v-c2ed4f50] {
  left: 0;
  width: 6.4px;
  width: 0.4rem;
  height: 12.8px;
  height: 0.8rem;
}
.bs-tooltip-right .arrow[data-v-c2ed4f50]::before, .bs-tooltip-auto[x-placement^="right"] .arrow[data-v-c2ed4f50]::before {
  right: 0;
  border-width: 6.4px 6.4px 6.4px 0;
  border-width: 0.4rem 0.4rem 0.4rem 0;
  border-right-color: #000;
}
.bs-tooltip-bottom[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="bottom"][data-v-c2ed4f50] {
  padding: 6.4px 0;
  padding: 0.4rem 0;
}
.bs-tooltip-bottom .arrow[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="bottom"] .arrow[data-v-c2ed4f50] {
  top: 0;
}
.bs-tooltip-bottom .arrow[data-v-c2ed4f50]::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow[data-v-c2ed4f50]::before {
  bottom: 0;
  border-width: 0 6.4px 6.4px;
  border-width: 0 0.4rem 0.4rem;
  border-bottom-color: #000;
}
.bs-tooltip-left[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="left"][data-v-c2ed4f50] {
  padding: 0 6.4px;
  padding: 0 0.4rem;
}
.bs-tooltip-left .arrow[data-v-c2ed4f50], .bs-tooltip-auto[x-placement^="left"] .arrow[data-v-c2ed4f50] {
  right: 0;
  width: 6.4px;
  width: 0.4rem;
  height: 12.8px;
  height: 0.8rem;
}
.bs-tooltip-left .arrow[data-v-c2ed4f50]::before, .bs-tooltip-auto[x-placement^="left"] .arrow[data-v-c2ed4f50]::before {
  left: 0;
  border-width: 6.4px 0 6.4px 6.4px;
  border-width: 0.4rem 0 0.4rem 0.4rem;
  border-left-color: #000;
}
.tooltip-inner[data-v-c2ed4f50] {
  max-width: 200px;
  padding: 4px 8px;
  padding: 0.25rem 0.5rem;
  color: #fff;
  text-align: center;
  background-color: #000;
  border-radius: 0.25rem;
}
```

But the dom elements of the tooltip itself, as you saw before, even if specifically targeting an mount element inside the component (and not `body`), lack the `data-*` attribute to make them a target for the scoped css. 

It would be nice if this could work out of the box. If the library already has support for importing individual components or directives, it would be great if we could load only the necessary CSS for those components, AND even better if that worked with the scoped CSS so it doesn't pollute the global CSS namespace. 

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

4reactions
feliperaulcommented, Jul 26, 2019

Worked flawlessly. Thank you so much.

For anyone reading this in the future, using Rails / Webpacker, this is what I did:

VueTooltip.scss

@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";

@import "~bootstrap/scss/tooltip";

@import "~bootstrap-vue/src/variables";
@import "~bootstrap-vue/src/components/tooltip/index";

In my component.vue:

import './VueTooltip.scss';
import { VBTooltip } from 'bootstrap-vue';

export default {
  ...
  directives: {
    'b-tooltip': VBTooltip,
  },

The css imports didn’t change the layout of my page, which was happening before when I was imported the entire bootstrap CSS file.

Thank you again @tmorehouse

1reaction
tmorehousecommented, Jul 26, 2019
// custom.scss file

// This order is important
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/mixins";

// Import Bootstrap Tooltip SCSS
@import "bootstrap/scss/tooltip"

// Import Bootstrap Vue custom Tooltip SCSS
@import "bootstrap-vue/src/variables"
@import "bootstrap-vue/src/components/tooltip/index"
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to make React CSS import component-scoped?
I was expecting CSS to be: Component-scoped in a way that the style is only applied to things that are only rendered within...
Read more >
Getting Started - BootstrapVue
When using a module bundler you can optionally import only specific components groups (plugins), components and/or directives. Note that tree shaking only ......
Read more >
How to create your own Angular Tooltip Directive - Accesto
1 component - to define a template and a style of our tooltip;; 1 directive - to attach tooltips to HTML elements;; 1...
Read more >
Ninja Squad: Le Blog
The solution is to simply remove the tilde: @import 'font-awesome/scss/font-awesome'; . This was dictated by the migration to the modern Sass ...
Read more >
Building a simple tooltip component that never goes off screen
To reach a simple solution, I scoped down what I needed to the most basic option ... The only remaining situation where the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found