How to style slot elements in Astro with Tailwind - css

How can i style the injected elements in an Astro layout using plain css with tailwind.
Minimum Reproducible example:
/src/layouts/PostLayout.astro
<div class="prose text-white">
<slot/>
</div>
/pages/somepage.mdx
---
layout: ../layouts/PostLayout.astro
---
# Header 1
Some text
How can i target the markdown elements that are injected into the slot?
I can easily target any of the defined elements that are in the layout using a style block like this:
<style>
div {
border: 1px solid black;
}
</style>
However any styles applied to elements in the slot are ignored.

<style> elements are scoped by default, to opt out of scoping in the <style> tag you can use Global Styling or the is:global directive. (Reccomended)
Since markdown HTML is generated programmatically the only way to style your markdown using tailwind classes would be
(Reccomended) Tailwind's typography plugin
Remove the default tailwind base using this config option and add your own that includes the #layer and #apply directives
A markdown plugin like rehype-add-classes which allows you to add classes by selector to elements inside your markdown HTML
It is generally recommended to use Global Styling or the typography plugin to style markdown in Astro

Related

How to effectivly break line of the content inside a vuetify component?

Hi i'm triying to break line at the content inside a vuetify component but I haven't success. I need help to understand why, see the code below
<v-list-item-content style="word-break: break-word" class="kbDarkBlueText--text d-block" v-else>
{{ longText}}
</v-list-item-content>
I also try to apply the class text-wrap and the style break-all but none success.
pd: html element is setted to word-break:normal
The issue is that v-list-item-title and v-list-item-subtitle avoid line breaks and cut overflowing text with an ellipsis instead. This hides long texts.
To change this behavior, you can manipulate the CSS like this:
<style scoped>
* /deep/ .v-list-item__subtitle {
white-space: normal;
}
</style>
Source: wrap-word does not work on v-list-item-title/subtitle
I'm using scoped CSS here to apply this only to the component you use it in. As the CSS is scoped, the /deep/ selector is required. See docs on scoped CSS in Vue.
If you want to apply the behavior globally, you can remove the scoped property and the /deep/ selector.

How to style the placeholder text of an Ionic <ion-select> component?

How to style the default/placeholder text of an <ion-select> component in the Ionic framework? The default text is inside the shadow root, so therefore the HTML element has a class of "select-placeholder" it cannot be accessed via traditional CSS.
framework.com/docs/api/select#css-custom-properties
The docs for ion-select mention to use custom properties but there are only two custom properties:
--placeholder-color
--placeholder-opacity
Both work fine for updating the color and opacity, but I would really like to specifically update font-weight and font-style, and there aren't custom properties for those.
The Ionic team mentions that if there are not custom properties, to "access the shadow root of the element and apply the styles yourself in JS." But they don't expand on how to do that.
How, specifically, can I add styles in the shadow root of Ionic components where a custom property is not supplied?
TLDR; Add the part attribute to the placeholder element inside the shadow dom and then style using ::part(thePartName) in css.
Here was my solution (I didn't love it). And by the way I am on Ionic 4.
So ultimately, the problem with styling elements inside the shadow DOM of certain ionic components, is that traditional CSS selectors from an outside* style stylesheet have zero affect on elements inside the shadow dom. This is one of the main points of the shadow DOM: to create encapsulated components where CSS doesn't leak in and doesn't leak out. There are two exceptions that I'm aware of:
1 - Use one of Ionic's CSS variables (aka CSS Custom Properties). These are limited to --placeholder-color in Ionic 4 and adding --placeholder-opacity in ionic 5. I happened to be on ionic 4 so i couldn't take advantage of the opacity variable. However to use these custom properties you would do so like this:
ion-select {
--placeholder-color: 'hotpink';
}
I needed to style font-weight, font-style, and opacity so I needed another solution other than CSS Custom Properties.
There is a second way to style elements inside the shadow dom and that is using the ::part() pseudo element.
html that lives in the shadow dom provided by Ionic:
<div part="SorryIonicDoesntAddThisAttribute" class="select-text select-placeholder>my text</div>
Your css:
::part(thePartName) {
opacity: 1;
font-style: italic;
font-weight: normal;
}
If the "part" HTML attribute exists on the element inside the shadow dom its like a portal into the shadow dom.
However in Ionic 4, Ionic doesn't add the part attribute to the ion-select component's elements in the shadow dom.
I used javascript to add it (inspired by #ivanreutkers comment) to add the part attribute so I could thus style it in CSS.
document.getElementById("the-id").shadowRoot.querySelector(".select-placeholder").setAttribute("part", "myPartName");
*Outside, meaning the stylesheet for my website/application and not the specific styles provided by Ionic that live inside the web component.
Try to add the following line in your app.scss file like this:
::ng-deep {
.select-text {
color: white;
...
}
}

How to refer to an Angular component's full template setting CSS without referring to any tags?

My usual setup for each view is an outer DIV that I style as the base background etc.
<div class="outer">
<!-- Actual stuff in here -->
</div>
Then, in the SASS, I refer to it like so.
div.outer { ... }
That adds one lever of indent and seems like an unnecessary (though minor) increment in complexity. So I wonder if it's possible to add a style to the template itself. Partly, to lower the complexity. Partly, because I'm going to have text-only elements with no tags at all.
Is it possible to set the style of template from SASS files if there are no tags, only text in it?
You can apply styling to the component host element with the :host selector:
:host {
color: red;
}
See this stackblitz for a demo.

Can i apply an external css file only to a div and its children?

I don't think it is possible, but I will ask anyway:
Can I apply an external css file (Bootstrap for instance) to a div and its children without affecting the rest of the page.
For example, I need to migrate a footer written with Bootstrap over to an existing page. That page does not use bootstrap. If I link Bootstraps css at the top of the page, the css is applied to the whole page which ruins existing css. How can I just apply the bootstrap styles to the footer section without having to rewrite most of the page's css?
Any suggestions?
I ended up using LESS to compile a new css of bootstrap with a prefix of .bootstrap as seen below. It works, but i wonder if there is a more traditional way of handling this problem.
file: bootstrap-only.less
.bootstrap {
#import 'bootstrap.css'
}
file: bootstrap-only.css
.bootstrap .container {
width: 100%;
}
file: page.html
<style>
.container { width: 20px; }
</style>
<link rel="stylesheet" type="text/css" href="bootstrap-only.css">
<div class="not-bootstrap">
<div class="container">I am 20px</div>
</div>
<div class="bootstrap">
<div class="container">I am 100%</div>
</div>
You can try usig scooped css.Please do refer the following sample code.
<div>
<style scoped>
#import "filename.css";
</style>
//your div with its children will come here
</div>
Your inline styles should not be affected by adding Bootstrap as inline styles take precedence over styles from external resources. The only elements that should be affected are the ones in the page that share class names with bootstrap classes.
You can try referencing the Bootstrap css before your own css and your stylesheet will take precedence over the Bootstrap css. Unfortunately this may add styles additional styles to some of your classes which that you didn't explicitly reference in your stylesheet and may still change the look of your page.
For those classes that exist in both bootstrap and your stylesheet it's probably best to just change the names of those classes in your stylesheet and page. A quick way to do this is to use "replace" search for the class name and replace it with the new class name most IDEs have a way to "replace all" so it's often just a bit of typing and a few clicks to change a bunch of styles.
You can try using the Angular 2+, where you can simply create an component and us it anywhere irrespective of the page css. Basically it will create a shadow DOM and will not be accessible outside that component.

Angular-cli build generated CSS not working

I have an angular-cli app and using webpack.
When I try to run it the component specific css doesn't work
styles.css
/* You can add global styles to this file, and also import other style files*/
#import 'http://something/v4/dist/css/bootstrap.min.css';
Component
#Component({
selector: 'app-carousel',
templateUrl: './carousel.component.html',
styleUrls: ['./carousel.component.css']
})
export class CarouselComponent implements OnInit {
Component CSS
.carousel-indicators { display: none; }
angular-cli.config
"styles": [
"styles.css",
"../node_modules/roboto-fontface/css/roboto/sass/roboto-fontface-bold.scss",
"../node_modules/roboto-fontface/css/roboto/sass/roboto-fontface-light.scss",
"../node_modules/roboto-fontface/css/roboto/sass/roboto-fontface-regular.scss"
],
The rendered html
<style type="text/css">#import url(http://something/v4/dist/css/bootstrap.min.css);</style>
<style type="text/css">/* You can add global styles to this file, and also import other style files */
</style><style></style><style>.carousel-indicators[_ngcontent-c5] { display: none; }</style>
but this is not applied to my html element 'carousel-indicators'
If I import the carousel.component.cssinto the styles.css then it works but it appears twice in the generated html
I'm looking for the right way of doing this
By default(as in your case) angular using ViewEncapsulation.Emulated that scopes your css. However there is 3 view encapsulation options in Angular:
Native view encapsulation uses the browser's native shadow DOM implementation (see Shadow DOM on the MDN site) to attach a shadow DOM to the component's host element, and then puts the component view inside that shadow DOM. The component's styles are included within the shadow DOM.
Emulated view encapsulation (the default) emulates the behavior of shadow DOM by preprocessing (and renaming) the CSS code to effectively scope the CSS to the component's view. For details, see Appendix 1.
None means that Angular does no view encapsulation. Angular adds the CSS to the global styles. The scoping rules, isolations, and protections discussed earlier don't apply. This is essentially the same as pasting the component's styles into the HTML.
So when you applying any styles to your component in component.css(with default ViewEncapsulation.Emulated) the styles will be applied just for that particular component, it won't be leaked outside the component and always have a priority above the global styles unless global style has !important.
So as a result you have the style in the head of your html file like:
<style>.carousel-indicators[_ngcontent-c5] { display: none; }</style>
If you referencing your component.css in styles.css then it will became a global style rendered in html head like so:
<style type="text/css">/* You can add global styles to this file, and also import other style files */
.carousel-indicators {
display: none; }
</style>
As you declared you style in competent and then referenced your component.css in styles.css that competent styles just gets doubled in your html: one copy is a global style and other copy is scoped component styles.
I was tried to replicate you issue but my compentnt.css is always gets applied. I am using the latest stable angular cli 1.3.2. If you are using older cli try to update. Otherwise push your code on github or create a plunker so I can take a look.
UPDATE: You might have your custom css gets overridden by some of your global stylesheets you are referencing. You can use chrome dev tools to debug the styles also you can try to put !important to your custom css and see if it does help.
For everybody landing here :
The issue was with the ViewEncapsulation.Emulated I changed it to ViewEncapsulation.None as describe in this stackoverflow answer :
how to hide ngb-carousel indicators and prev-next control
Thanks for your help

Resources