How do I apply part styling to a nested Vaadin component? Vaadin components expose "parts" for styling in their published APIs.
Specifically, the vaadin-upload component hosts another component, vaadin-upload-file. I can style the main vaadin-upload component alright, but how do I reach the parts of the nested vaadin-upload-file component?
E.g. for the "name" part of vaadin-upload-file I unsuccessfully tried CSS selectors like
[part="name"] { ... // plain, as if it were passed through
vaadin-upload-file[part="name"] { ... // qualified with the component name
[part="file-list"][part="name"] { ... // qualified by the part of vaadin-upload that hosts the file list
:host([part="file-list"]) [part="name"] { ... // same with :host() selector
This is all in the style of the component that deploys vaadin-upload.
As the answer made its way to me on a different path, here is the solution for SO:
You can only apply styles to Vaadin components and their sub-components using a custom theme.
Here is a slightly extended way to set this up using a parent theme.
Create a local custom theme in your app
path is frontend/themes/<my-theme-name>/
must contain a sub-directory components (to style Vaadin components)
must contain a styles.css (even empty)
must contain a theme.json with contents
{
"parent": "<my-parent-theme>"
}
but there are other keys for theme.json like importCss, documentCss or assets
the parent theme can be a pom dependency
Use the custom theme in your Application.java:
#Theme(value = "<my-theme-name>")
public class Application extends SpringBootServletInitializer ...
Then you can add style files locally to style Vaadin components, e.g.
add frontend/themes/<my-theme-name>/components/vaadin-upload.css:
[part=file-list]::before {
content: "These are the current files:";
}
frontend/themes/<my-theme-name>/components/vaadin-upload-file.css:
[part=name] {
background-color: yellow;
}
This applies to Vaadin21 (e.g. in Vaadin19 using a parent theme is not working this way).
Related
Is it possible to apply framework styles to nested lit-element? An idea is to disable shadow dom. I tried this.
createRenderRoot() {
return this;
}
It does not do what I need. I see that I can recompile styles into components. But right now I am looking for an easier solution.
There is a solution - Specify the render root. This solution rid of shadowRoot. Styles were applied but , does not work.
If you want to use global styles you'll have to disable Shadow DOM in the whole app tree: if a single component has a shadow root its whole subtree won't be affected by external styles.
Anyway, as you noticed, slots only work with shadow DOM enabled. In this case using a common style library/framework is still possible, see for example Sharing Styles, Using Bootstrap in Web Components, Importing external stylesheets.
Yes, but disabling shadow DOM is the wrong way to do it it.
LitElement used adopted stylesheets, which let you load/create the CSS once, but apply it to the shadow DOM of the component. You can create this globally, apply it in each component, and effectivly have styles that are shared by all your components, but (critically) don't apply to any external component you load or any external app that loads your component.
You can do something like:
// common-styles.js
export const styles = css`...`;
// any-component.js
import { styles } from 'common-styles.js';
...
static get styles () { return [styles]; }
As the styles object is shared it doesn't download or parse again - all your components get a reference to the same styles, rather than global styles cascading down.
It works as designed. The version above does not use ShadowDom. So styles are applied. In my case, all components while style bubbling has to disable ShadowDom.
But another issue appears.
createRenderRoot() {
/**
* Render template without shadow DOM. Note that shadow DOM features like
* encapsulated CSS and slots are unavailable.
*/
return this;
}
But I need slots.
It depends on what properties you want to share.
You can share these properties from the parent element:
color
font-family and other font-* properties
All CSS custom properties (--*)
Just you need to define these properties in the parent element's :root selector.
For more information: https://lit.dev/docs/components/styles/#inheritance
I'm trying to change the background color of a dialog element's backdrop using a custom CSS property but it won't take. Is this a bug in Chrome or is there a reason for this?
document.querySelector('dialog').showModal();
:root {
--color-backdrop: red;
}
dialog::backdrop {
background: var(--color-backdrop);
}
<dialog>
<p>This is a dialog. My backdrop should be red.</p>
</dialog>
The spec states the following about ::backdrop pseudo-element:
It does not inherit from any element and is not inherited from. No restrictions are made on what properties apply to this pseudo-element either.
And to quote Xindorn Quan, a member of WHATWG, regarding CSS Custom Properties:
CSS variables are propagated via inheritance into descendants, so if a pseudo-element doesn't inherit from anything, CSS variables which are not defined for the pseudo-element directly would have no effect on the pseudo-element.
Finally, this is one solution for this kind of problem:
document.querySelector('dialog').showModal();
::backdrop {
--color-backdrop: red;
}
dialog::backdrop {
background: var(--color-backdrop);
}
<dialog><p>This is a dialog. My backdrop should be red.</p></dialog>
It seems to be useful for multiple modals with ::backdrop, as a way of organizing their "root", so to speak.
I would like to define all our styles in a the custom Liferay theme we developed. I want to know if it is possible to use css classes defined in the theme in portlets project. We need to avoid duplicate css files in every portlet project. The aim is that the theme controls all look and feel aspects of our portlets and so if we change the theme (or deploy portlets in another portal container) portlet styles change.
You think this is possible ?
Thanks in advance ..
What you want to do is the recommended way to style both the theme and the Portlets.
Portlet styles should only be affect the layout within the Portlet it belongs. All other styles; colors, fonts, etc., should be defined in the theme's custom.css.
I would advise you to try styling the existing Portlet classes before introducing new ones. Then, if you're really stuck, edit portlet.vm.
Take a look at Liferay's Political Theme:
custom.css
...
.portlet {
margin-bottom: 10px;
.portlet-topper {
padding: 0;
.portlet-title {
...
I need do something like that:
I have theme "panel" in /themes/panel and there layout /themes/panel/views/layouts/main.php with example content
<a>$content</a>
I have module "admin" in /protected/modules/admin and there layout /protected/modules/admin/view/layouts/main.php with example content
<b>$content</b>
And on the end i want
<a><b>view</b></a>
Also in /themes/panel/views/layouts/main.php i need load css file from module.
In other explanation:
I have one template for all panels (header, css files, footer), but each of panels need separate layout (only the middle of content change like menu etc.) and one or more individual css file.
Also some images will be include from main theme, other will be individual for modules.
You can use the renderPartial function for load the parts of layout.
<?= $this->renderPartial('webroot.themes.' . Yii::app()->theme->name . '.views.layouts.' . Yii::app()->layout . '.<PART_OF_LAYOUT>') ?>
I disagree that in many help forums of the Internet, when someone asks abot theming a module, everyone suggests a path alias to the themes folder. I think this is wrong, because it implies modules to be splitted, and modules are supposed to be a black-box that can be used across projects. The advice given in such forums would only be valid if a theme is shared among several modules. If someone wants to "package" a theme inside a module, she can:
-add an init function to the controller of the module
-inside that init, use the class attribute layout and a path alias, like this, supose a module whose id is "Sample":
then you add, to SampleCOntroller.php:
public function init() {
//BELOW: it will use the layouts/main.php inside the module.
$this->layouts = "sample.views.layouts.main";
}
Yo can check about path alias here:
http://www.yiiframework.com/doc/guide/1.1/en/basics.namespace
I would like to put a custom icon in a p:menuButton, is this possible?
Yest it is possible. All you need to do is to override primefaces css classes generated for the p:menuButton.
Approach:
In the rendered web page you can right click on the generated p:menuButton and -> inspect element. There you can inspect all of the related css classes.
You can try to experiment with them (which I would advice, if you have time) for better understanding of css selectors and so on ...
The .ui-menubutton .ui-state-default .ui-icon are the classes that you need.
So now when you know which css classes are related to the icon you can override them :
Add .ui-menubutton .ui-state-default .ui-icon rule to your stylesheet (I assume you have one and it is sucesfully imported and working. If not check here.)
yourStyles.css :
.ui-menubutton .ui-state-default .ui-icon {
background: orange; /** insert your background image **/
}
This will override icons of all p:menuButtons used in your project. If you want to reduce it to some particular p:menuButton then add its ID to the style definition.
#menubID.ui-menubutton .ui-state-default .ui-icon {
background: orange; /** insert your background image **/
}