CSS Variables in Ionic 4 - ionic-framework

I am trying to change the color of the icon in the selected tab and am really struggling with how to overwrite the variable.
I'm doing the following:
ion-tabs {
--color-selected: #ff7800 !important;
--ion-color-contrast: #ff7800 !important;
}

I figured it out! It looks like --ion-color-contrast stems from the original them that you've applied to the component, in my case "dark". So I actually need to overwrite --ion-color-dark-contrast as follows:
ion-tabs {
--ion-color-dark-contrast: #ff7800 !important;
}

To set a CSS variable for a specific component, add the variable inside of its selector. See Ionic Variables for more information on the component-level variables Ionic provides.
/* Set the color on all ion-button elements */
ion-button {
--color: #222;
}
/* Set the background on an ion-button with the .fancy-button class */
.fancy-button {
--background: #00ff00;
}

Related

change font in ionic input

In an ionic app, I am trying to change the font family of input.
in global.css i'm specifing the global font
* {
font-family: 'FFMalmoom' !important;
}
I want the ion-input text in specific page to take another family
i tried:
ion-input {
font-family: 'verdana' !important;
}
ion-input {
--ion-font-family: 'verdana' !important;
}
with no success , It still takes 'FFMalmoom'.
Instead of specifying the global font in the global.scss move it to the :root selector in the variables.scss file with the --ion-font-family css variable
:root {
--ion-font-family: 'FFMalmoom';
}
After that the font will still be applied globally as ionic uses this as the base font for the entire app. You can then set the ion-input font-family as you normally would with
ion-input{
font-family: 'verdana';
}

Ionic 5 Modal over modal is missing ion-backdrop

Why is my ion-backdrop + modal shadow styling not working when I open a modal on top of another modal?
PREFACE: This was working fine with V4, but broken on the upgrade to V5. I don’t want to change my page approach, just fix the CSS/whatever is actually causing the issue below.
My app opens a modal page with custom css to make it full screen.
I can then open another normal modal (but not full screen) over the
top. This 2nd modal is missing the ion-backdrop and its border shadow
styling.
I can see the ion-backdrop is definitely in the DOM, but it’s
obviously not showing.
Step1 Fine
enter image description here
Step 2 - broken ion-backdrop:
enter image description here
Showing my custom modal:
async showClipboard() {
const modal = await this._ModalController.create({
component: ClipboardPage,
cssClass: 'custom-round-modal',
componentProps: {
user: this.user
},
showBackdrop: true
});
await modal.present();
}
The CSS:
#media only screen and (min-width: 768px) {
.custom-round-modal {
.modal-wrapper {
border-radius: 15px !important;
-moz-border-radius: 15px !important;
-webkit-border-radius: 15px !important;
.ion-page {
border-radius: 15px !important;
-moz-border-radius: 15px !important;
-webkit-border-radius: 15px !important;
}
}
}
}
First off, I think you pasted the same screenshot twice by mistake. But I'm having the same issue, so I know what you mean.
It looks like Ionic 5 introduced this css for the modals:
.sc-ion-modal-ios-h:first-of-type {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
}
Which means when you show multiple modals at the same time, only the first one will get the backdrop.
A possible workaround is to add the backdrop yourself to your global css using something like this:
ion-modal {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
}
Or use the css class Ionic is using (but note that this one is iOS specific, so you'd likely need to do the same with the Android-equivalent class):
.sc-ion-modal-ios-h {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
}
NOTE: This will likely not look good if you are showing multiple modals on top of each other that are not fullscreen, since you'll be getting multiple backdrops on top of each other (so they'll get increasingly darker). But since your issue is a non-fullscreen modal on top of a fullscreen one, I think it will work in your case.
Hopefully the Ionic team will come up with a more elegant solution to this issue.
Thank you krisloekkegaard for your code, that helped me really out.
I want to add that it will only work if placed in the global sass or css files! You cannot do that from a component's style-file, because the modal will be created outside of it.
The following lines are a bit more precise, because they will activate the backdrop only on the last modal. Even if you have 10 stacked modals, there will be only the backdrop of the first and the backdrop of the last element overlaying each other.
.sc-ion-modal-md-h:last-of-type {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
.sc-ion-modal-ios-h:last-of-type {
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
This is addressed now in the Ionic Documentation.
Please see under 'Customization' section for ion-modal : https://ionicframework.com/docs/api/modal
Add the following CSS to your modal class -
ion-modal.stack-modal {
--box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
}
I solved the issue adding the following css into variables.css file in Ionic v5. Give a chance.
.backdrop-no-scroll {
ion-router-outlet {
background: white;
}

Ionic 4: How to overflow div from Ionic Header or Toolbar?

I want create a drop down menu or popover within ionic toolbar. I tried with several ways but can not solve. Its always hidden like bellow,
I trying css like bellow,
.popover{
border: 1px solid black;
height: 350px;
width: 150px;
position: absolute;
z-index: 99999999;
background: yellow;
}
ion-header{
contain: none;
}
ion-toolbar{
contain: none;
}
Please give me a suggestion or an alternative idea. Please do not give any predictive answer if you are not familiar with ionic.
I don't know about Ionic 4 but on Ionic 5, a solution would be this when you debug on the console :
ion-toolbar {
contain: none;
.toolbar-container {
overflow: visible;
contain: none;
}
}
However, the .toolbar-container is an element in the shadow dom of the <ion-toolbar> component and its overflow and contain properties are not css variables and there is no part attribute on this element neither. So there is actually no way to override those properties.
I'm considering using this package, but for me it seems like overkill to use js and timeout for setting a pretty simple style... :
https://www.npmjs.com/package/shadow-dom-inject-styles
I had a similar problem when I had to make a searchbar overflow underneath the header (design thing). I was struggling a while and it popped in place suddenly when I place the searchbar outside of the toolbar and gave it position absolute:
<ion-head>
<ion-toolbar>
<!-- My stuff here -->
</ion-toolbar>
<ion-searchbar></ion-searchbar>
<ion-header>
My css looks like this:
ion-toolbar {
display: flex; // I need this for something else, but maybe has an influence
}
ion-searchbar {
padding: 0 1em .5em 1em;
transform: translateY(-50%);
z-index: 99999;
position: absolute;
}
Hope it helps somebody.
In case anyone is still looking for the solution. Here is how I managed to fixed it in react. It's a bit hacky solution, but most likely the only one ATM.
First we need to style the toolbar (pass a className or style to component:
.your-toolbar-classname {
overflow: visible!important;
contain: none!important;
}
Then we have to also style the shadow-root parts. Se we can use the useEffect after the header is mounted and set the style
// Header.tsx
...
useEffect(() => {
const style = document.createElement('style');
style.innerHTML =
'.toolbar-container { overflow: visible!important; contain: none!important; }';
toolbarRef.current.shadowRoot.appendChild(style);
}, []);
...
Just use ion-menu, its a build in ionic component
https://ionicframework.com/docs/api/menu
There is also ion-popover
You should look at the ionic docs before posting on stack

class overrule when two classes assigned to one div

I was creating a <div> tag in which I wanted to apply two classes for a <div> tag which would be a thumbnail gallery. One class for its position and the other class for its style. This way I could apply the style, I was having some strange results which brought me to a question.
Can two classes be assigned to a <div> tag? If so, which one overrules the other one or which one has priority?
Multiple classes can be assigned to a div. Just separate them in the class name with spaces like this:
<div class="rule1 rule2 rule3">Content</div>
This div will then match any style rules for three different class selectors: .rule1, .rule2 and .rule3.
CSS rules are applied to objects in the page that match their selectors in the order they are encountered in the style sheet and if there is a conflict between two rules (more than one rule trying to set the same attribute), then CSS specificity determines which rule takes precedence.
If the CSS specificity is the same for the conflicting rules, then the later one (the one defined later in the stylesheet or in the later stylesheet) takes precedence. The order of the class names on the object itself does not matter. It is the order of the style rules in the style sheet that matters if the CSS specificity is the same.
So, if you had styles like this:
.rule1 {
background-color: green;
}
.rule2 {
background-color: red;
}
Then, since both rules match the div and have exactly the same CSS specificity, then the second rule comes later so it would have precedence and the background would be red.
If one rule had a higher CSS specificity (div.rule1 scores higher than .rule2):
div.rule1 {
background-color: green;
}
.rule2 {
background-color: red;
}
Then, it would take precedence and the background color here would be green.
If the two rules don't conflict:
.rule1 {
background-color: green;
}
.rule2 {
margin-top: 50px;
}
Then, both rules will be applied.
Actually, the class that defined last in the css - is applied on your div.
check it out:
red last in css
.blue{ color: blue; }
.red { color: red; }
<div class="blue red">blue red</div>
<div class="red blue">red blue</div>
vs
blue last in css
.red { color: red; }
.blue{ color: blue; }
<div class="blue red">blue red</div>
<div class="red blue">red blue</div>
If you asking about they have same property then as per the CSS rule it's take the last statement.
<div class="red green"></div>
CSS
.red{
color:red;
}
.green{
color:green;
}
As per the above example it's take the last statement as per css tree which is .green.
The class that is defined last in the CSS have priority, if nothing else applies.
Read up on CSS priority to see how it works.
Many classes can be assigned to an element, you just separate them with a space
<div class="myClass aSecondClass keepOnClassing stayClassySanDiego"></div>
Because of the cascade in CSS, the overwriting rules closest the to bottom of the document will be applied to the element.
So if you have
.myClass
{
background: white;
color: blue;
}
.keepOnClassing
{
color: red;
}
The red color will be used, but not the background color as it was not overwritten.
You must also take into account CSS specificity, if you have a more specific selector, this one will be used:
.myClass
{
background: white;
color: blue;
}
div.myClass.keepOnClassing
{
background: purple;
color: red;
}
.stayClassySanDiego
{
background: black;
}
The second selector here will be used as it is more specific.
You can take a look at it all here.

GWT MenuBar.Resources... ignored?

I'm creating a MenuBar, and I want to have it display a little icon when there are sub-elements to be displayed. I thought I could achieve this like so:
interface ActionHeroResources extends ClientBundle, MenuBar.Resources
{
#Source("actionhero.css")
public ActionHeroCSS css();
#Override
#Source("agw-dropdown.png")
ImageResource menuBarSubMenuIcon();
}
private static final ActionHeroResources RESOURCES = GWT.create(ActionHeroResources.class);
MenuBar actionMenu = new MenuBar(true, RESOURCES);
public ActionHero()
{
actionMenu.addItem("Select", aSelectMenuFullOfOptions);
}
But the menu appears with the word "Select" an no icon! I'm positive my ImageResource is working correctly because I use menuBarSubMenuIcon().getURL() from the same resource later, and my image shows up just as you'd expect. In the HTML generated by GWT, there is absolutely no distinction between the items with MenuBars as children and the items with Commands. My CSS is working fine.
Any thoughts?
Try overriding the CSS style for .gwt-MenuBar-vertical .subMenuIcon-selected, like this:
.gwt-MenuBar-vertical .subMenuIcon-selected {
background: none;
}
I use this for my own selected items and it works great:
.gwt-MenuBar-vertical .subMenuIcon-selected {
background: url(images/hand_pointer.png) no-repeat 0px 0px;
}
The problem was ultimately that the popup panels that form the submenus take their stylename from the parent, but append a dependent stylename. I don't know of a way to predict what that dependent stylename will be, since the original stylename is obfuscated. I worked around this problem by using the more generic .gwt-MenuBar popup stylename. This only works because I only have one style of popup menu in my program - I'm not sure what I would do if I wanted two popups to look different!
Hopefully, in later gwt releases, the MenuBar styles will come more closely from the resources passed to the menubar and make less use of dependent style names.
You can simply set a css rule for the that appears in the sub menu like this:
.subMenuIcon > img {
/* override gwt sub menu icon */
width: 6px !important;
height: 11px !important;
background: url('your-image-relative-path.png') no-repeat 0px 0px !important;
}