Dynamic Theming Ionic Issue - html

I'm using Ionic with Angular to develop an App. I intruduced dynamic theming adding two .scss files into my theme folder. I've got app.scss where I define only the layout of my components without colors. All colors are in the theme-*.scss files. To apply a theme I use a class over <ion-nav> element into my app.html. Something like this:
<div [class]="selectedTheme">
<ion-nav [root]="rootPage" ></ion-nav>
</div>
The selectedTheme is a string that assume the name of my theme so when I change it with an event such (click) or (ionChange) I can change the colours of my app.
A file theme-*.scss has the following structure:
.dark-theme {
ion-header {
//colors
}
ion-content {
//colors
}
}
This way works like a charm, but I've got a little issue I want to avoid. I set the default theme in constructor of app-components.ts file, before the famous platform.ready().then(...) that hides the splashscreen. My issue is that when the splashscreen hides I can see my app with its layout but without the correct theme applied. I see all white backgrounds and all black colors for a small amount of time, then the default theme is applied. I'm importing my custom themes in variables.scss, I tried to import them also in app.scss but the behaviour remain the same. It seem that before import the themes it applies the layout in app.scss and only after it applies the imported theme with all its colours. Someone has already see something like this?

I think that your issue is caused by timing of first paint which is an attribute on browsers. The webview where ionic runs can be consider as a sort of browser. So, same issue occurs.
why-first-paint-is-happening-before-domcontentloaded is a great explanation related to your question.
This page talks about first paint can start before DOM is fully loaded.
Especially, the below cited paragraph from the link describes same phenomenon of your app.
E.g. the parser obviously cannot emit Element nodes before processing
all of its attributes, but it can emit the node while still processing
its child tree. And the renderer may render the node without its
children. And it may be rendered with incomplete styles only to
undergo a reflow later, e.g. when javascript inserts another style
sheet or simply because the child nodes which have yet to be inserted
affect how it will be rendered.
In conclusion, you can not guarantee DOM is loaded before painting. So, I think that practical solution is hiding your splash screen a little bit later.

Related

add react component to existing webpage and avoid CSS conflicts

I'm developing a React/MaterialUI component that will be embedded in existing websites.
In order to minimise the work needed on the existing page to embed my component, I'm bundling my component into an app.js and the only change requested to the existing page is something like:
<div id="embedded-component"></div>
<script type="text/javascript" src="https://example.com/app.js"></script>
my component finds the div by ID and then mounts on that element.
Things are mostly working but I'm having issues with CSS conflicts between the CSS files on the original page (which I can't modify) and the elements of my application.
For example the original page uses text input elements with a border/padding/color that I don't want my component to "inherit".
I want my component to display the same way regardless of which page is embedded on.
Is there any strategy/tool to use in this case, so CSS classes on existing page do not affect the elements of my embedded component?
Trying to find a solution to this I've come across the Shadow DOM (e.g. https://medium.com/rate-engineering/winning-the-war-of-css-conflicts-through-the-shadow-dom-de6c797b5cba) but I'm not sure how widely supported this is in different browsers.
Is there any solution to this, that is widely supported by all major browsers?
I cannot use iframes and have full control of my js/css files but no control over the existing page other than the "mounting" div.

Visible colored content shows transparent in Chrome

Lately, I've noticed something strange, happening only in Chrome (my current version is 58).
It is a little bit difficult to explain, so I made sure to include clear animations besides my text explanation to show what is really happening:
The <h1> text is visible, notice how the computed color is #222, the content is above (I mean, it doesn't look like any z-index fault). But still, the text is not readable unless I resize the page or do some modification using devtools. It can be selected/highlighted though.
The application is built with Angular if that can help in any way, and I'm not using any sort of DOM encapsulation such as Shadow DOM.
I am using a set of shared styles (for example -- colors.scss), which I import in most of my modules.
home.module.ts -> home.component.ts -> home.component.scss
#import "../shared/colors.scss";
One of this shared stylesheets was typography.scss, which had the following (only relevant bits shown):
#font-face {
font-family: "Sawasdee";
src: url("/assets/fonts/sawasdee.ttf") format("truetype");
}
Repetitively importing the font was causing that screen flickering, so all I had to do was to make sure it was only being loaded once (and at the beginning of the app).
So I just moved the font import into the main module scss -> app.component.scss

Angular 2 routing from one component to another then CSS is not applied

When I route from one component to another then CSS is not applied for that new component. But when I inspect the element it shows css properties are applied to the element but not rendered. But when I refresh the page or even close the dev tools then that element is displayed on screen immediately without making any changes.
So not sure how to go about resolving this issue.
This issue was related to fonts.
As we are using angular-cli which uses webpack to bundling.
Webpack was unable to bundle fonts properly which was causing it to not render the elements correctly.
Its a known issue in angular-cli
https://github.com/angular/angular-cli/issues/1463

Styling a Twitter feed - CSS won't target .timeline-Tweet-text

I'm bringing a Twitter feed through to my site using the following code which is described on https://publish.twitter.com/
<a class="twitter-timeline" href="https://twitter.com/ACCOUNT-HERE" data-tweet-limit="3">Tweets by</a>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
The feed is displayed correctly. However it uses CSS which is provided via Twitter.
When I inspect it using Chrome dev tools I can see the following classes around the Tweets:
<p class="timeline-Tweet-text" lang="en" dir="ltr">
So I thought it would be a simple case of targetting this in CSS, e.g.
.timeline-Tweet-text {
}
However, this doesn't apply any styles to the Tweets. Why not?
I have also referred to Twitters guidance on this here https://dev.twitter.com/web/overview/css but that also doesn't work.
The only reason I want to do this is so the font used within the widget matches the font used by the rest of the body text on my website.
Simply adding a style rule to your top-level page won't work, because they are two different and isolated documents as far as the browser is concerned.
However, with the use of kevinburke's Customize Twitter 1.1 project, you should be able to embed CSS into a timeline. It does this by injecting a link to an external CSS file directly into the contents of the document within that frame.
In Kevin's published example, It makes all the text white, which looks a bit broken, but when I took this example and adjusted it to also turn the background red, we can see it's working as intended and you can therefore make any adjustments you like, provided you have a CSS file for it.
Note that this is only possible because Twitter have configured platform.twitter.com so that it can be embedded in frames. For security reasons, many websites will nowadays send a HTTP response header to prevent framing of the content, to avoid people meddling with their contents.
From https://dev.twitter.com/docs/embedded-timelines
Customization Options
Embedded timelines are available in light and dark themes for customization. The light theme is for pages that use a white or light colored background and follows the twitter.com aesthetic, while the dark theme is for pages that use a black or dark color background and looks more like Tweetdeck.
As with your twitter.com profile, you may choose a custom link color for your embedded timelines so that the content matches the links of your website and feels integrated into the color palette of your site.
For sites where the theme and link color do not provide enough customization to make the Tweets feel like they’re a part of the page, we offer a set of additional client side customization features. These settings allow you to control the background color, borders, header, and footer of the timeline, and are detailed in the “Client Side Options” section below
You Can Use CSS * Property for Setting the Fonts for all the Pages...
Example:(this might be useful for you)
#twitterFeed * {
font-family: "Lato" !important;
}
Reference Link for Twitter Widget Style :
https://dev.twitter.com/web/overview/css
https://www.solodev.com/blog/web-design/styling-your-websites-twitter-feed.stml
Unfortunately (Unless it has been changed recently) you can't manipulate CSS inside of an iframe
https://jsfiddle.net/tm94g9n4/5/
.timeline-Tweet-text {color: red;}
I added the color red to the text but as you can see when you inspect it doesn't even appear as overwritten. It's not referenced at all.
I think you'll need to look in to custom libraries for this. I can't recommend any as I've not done this before.
https://stackoverflow.com/a/6495816/1379450
Hope it helps
EDIT
It seems it is possible (Duplicate question)
How to apply CSS to iframe?
I have implemented a simple solution in my project recently, you can customize all kinds of styles to have it fit in seamlessly with your website branding.
jQuery('.twitter-block').delegate('#twitter-widget-0','DOMSubtreeModified propertychange', function() {
//function call to override the base twitter styles
customizeTweetMedia();
});
var customizeTweetMedia = function() {
// overrides font styles and removes the profile picture and media from twitter feed
jQuery('.twitter-block').find('.twitter-timeline').contents().find('.timeline-Tweet-media').css('display', 'none');
jQuery('.twitter-block').find('.twitter-timeline').contents().find('img.Avatar').css('display', 'none');
jQuery('.twitter-block').find('.twitter-timeline').contents().find('span.TweetAuthor-avatar.Identity-avatar').remove();
jQuery('.twitter-block').find('.twitter-timeline').contents().find('.timeline-Tweet-text').css('font-size', '12px');
jQuery('.twitter-block').find('.twitter-timeline').contents().find('.timeline-Tweet-text').css('font-family', "'Proxima Nova', lato, sans-serif");
jQuery('.twitter-block').find('.twitter-timeline').contents().find('span.TweetAuthor-screenName').css('font-size', '12px');
jQuery('.twitter-block').find('.twitter-timeline').contents().find('span.TweetAuthor-screenName').css('font-family', "'Proxima Nova', lato, sans-serif");
// also call the function on dynamic updates in addition to page load
jQuery('.twitter-block').find('.twitter-timeline').contents().find('.timeline-TweetList').bind('DOMSubtreeModified propertychange', function() {
customizeTweetMedia(this);
});
}
Link to my complete example

My custom element is not working in Polymer shop app, but working in Polymer starter kit?

PROBLEM:
I've created a custom "properties" grid system to use universally on any element. In every project thus far, I've had no problem using it...But when I try to use it in the Polymer Shop App Demo, it doesn't work. Here's my custom property system that I'm importing in: https://github.com/oneezy/steel-properties
In Chrome dev tools network tab, it says that it's loading normally, however when I inspect an element it doesn't show up in the css and has no effect! It's got me scratching my head because it works completely fine w/ Polymer Starter Kit and in other projects...
I've included a short video showing my problem:
https://www.youtube.com/watch?v=tpyYxXTMdkU
Is there something I'm missing or doing wrong???
UPDATE:
By changing shadow to shady in the shop app's index.html file, everything seems to work as expected:
Polymer = {lazyRegister: true, dom: 'shadow'};
becomes...
Polymer = {lazyRegister: true, dom: 'shady'};
But what are the ramifications of this?
Steel-Properties is meant to be used as a "universal" way for initial layout so you can quickly use it on any element. When I include steel-properties into a file, it goes in and calls other files that have specific style properties written out, and you then can write these properties directly into your markup.
EXAMPLE:
HTML Markup:
<body mobile-bg="blue" tablet-bg="green" desktop-bg="yellow"></body>
Output:
The Code:
As you can see, steel-properties is not your typical <custom-element>. It's really just importing in style sheets with [attribute="property"]'s.
So my questions now are:
Should I be doing it this way or am I going about it wrong?
What would be the proper way to write my "steel-properties" so that it can work with both shadow and shady DOM universally?
What are the ramifications of switching shadow to shady DOM in the shop app?
What is the main reason for using shadow DOM instead of shady DOM in the shop app but not the Polymer Starter Kit? (performance?)