Responsiveness in MJML <mj-attributes> - mjml

When using MJML to create the email templates, it provides the carousel feature in email templates. Here is the code from the their sample. (icon-width and tb-width were added by me)
<mj-carousel icon-width="30px" tb-width="20px">
<mj-carousel-image src="https://www.mailjet.com/wp-content/uploads/2016/11/ecommerce-guide.jpg" />
<mj-carousel-image src="https://www.mailjet.com/wp-content/uploads/2016/09/3#1x.png" />
<mj-carousel-image src="https://www.mailjet.com/wp-content/uploads/2016/09/1#1x.png" />
</mj-carousel>
As you see, the attribute tb-width controls the width thumbnails of the carousel, I want to change the value of tb-width to be smaller when it goes into mobile screen, otherwise I will have to stick to one value cross all screen sizes.
I tried this:
#media all and (max-width: 480px) {
[tb-width] {
width: 50px !important;
} // this is not working
}
Then I tried this based on the official document
#media all and (max-width: 480px) {
div[style*="tb-width:20px;"] {
width: 300px !important;
}
}
None of above code works.
How do you guys solve this problem? Thanks in advance.

Thanks for #dermothghes from mjml slack channel, here is the solution:
All these mjml components will have a corresponded css class in the outputted HTML, what we need to do is to compile the .mjml file first and find the corresponded css class from the output.
In my question, this should work:
#media all and (max-width: 480px) {
.mj-carousel-thumbnail {
width: 50px !important;
}
}
.mj-carousel-thumbnail is the generated class from mj-carousel-thumbnail mjml component.

Related

sass variable not working in container query

SCSS variables don't seem to work when used in a container query. For example this code works just fine:
.parent {
container-type: inline-size;
background: yellow;
}
#container (max-width: 800px) {
.child {
background:green;
}
}
See pen: https://codepen.io/pwkip/pen/jOprKya
But when I try to use a sass-variable to define the breakpoint, it fails.
$width: 800px;
.parent {
container-type: inline-size;
background: yellow;
}
#container (max-width: $width) {
.child {
background:green;
}
}
See pen: https://codepen.io/pwkip/pen/BaPzVZW
What's the problem here? Any workaround?
I cannot find the definitive sass lang entry, but hash and curly brace is often used in #media queries.
#container (max-width: #{$width}) {
.child {
background:green;
}
}
In Brave it works in that codepen; and so do the following:
#container (max-width: ${width} ) {
As "A Boston" already pointed out the issue seems to be that you don't use the hash syntax like in his first example.
I use https://www.sassmeister.com/ quite often to check what it compiles to.
In your Codepen you forgot to add a semicolon after
$width: 800px;
^
According to: https://developer.mozilla.org/en-US/docs/Web/CSS/#container
#container queries are not supported for Firefox yet. Only Firefox Nightly supports it.
I've tested it in Chrome and it worked with the tweaks. Make sure your browser version is supported. My current Safari version did not work either (due to the version mismatch).

Angular primeng tabview style defined in one component is affecting the style in another component

I am not an expert with styling and encapsulation.
Need help with fixing style issue. Style used in a component is overriding the global style.
i am using primeng tabview component in component A for eg:
ComponentA.html:
<p-tabView styleClass="tab-view"></p-tabview>
ComponentA.scss:
.p-tabview {
padding: 0rem;
li.p-highlight span {
font-weight: $semibold-font-weight;
}
}
But this padding is applied to all primeng tabview setting in global style
Component B:
<p-tabView class="tab-view-scheduler"></p-tabview>
global style scss:
.p-tabview {
#media screen and (min-width: $tablet-break) {
padding: 0 4rem 2rem; //this is getting overridden
font-size: $desktop-small-font-size;
}
}

Dynamically displaying static images based on view port using Sass

I'm creating a React application that has a hero display on the landing page that displays one of three images: [hero-1.jpg, hero-2.png, hero-3.png] based on the users viewport screen size.
I have been unsuccessful trying to find resources online that show a DRY method for achieving this, for the sake of participation, I'll leave this code that I attempted that - in theory made sense to me.
N.B. I am extremely new to Sass/Scss
snippet.html
<section className="hero is-fullheight has-background-black">
<div className="hero-body">
<div className="container">
</div>
</div>
</section>
hero.scss
$i: 1;
$breakpoint-phone: 480px;
$breakpoint-tablet: 768px;
$breakpoint-desktop: 1024px;
#mixin modifier ($i:1) {
#content;
#media only screen and (max-width:$breakpoint-phone) { $i: 2; }
#media only screen and (max-width:$breakpoint-tablet) { $i: 3; }
#media only screen and (max-width:$breakpoint-desktop) { $i: 1; }
}
.hero {
background-position: center;
background-size: cover
}
#include modifier {.hero {background-image: url('../assets/hero-#{$i}.jpg');}}
Methodology:
Display content by default (which is pulled from #include).
Mixin modifier will modify the $i passed to the mixin, which is interpolated in the image path.
Expected Result:
Based on each breakpoint, $i will be set to the appropriate value and change the background image dynamically.
Actual Result:
The global $i is used, and the web page displays hero-1.jpg.
There are a few ways you can achieve this. If I was going about this, this is how I would do it.
Also, it would be very wise to practice mobile first development. Use min-width and go up instead of using max-width going down. The way you currently have it structured would mean you wouldn't have a valid URL if that $i variable wasn't set at 1 at the top of your document. Writing SASS or CSS will be much easier this way once you get used to it.
$tablet: 768px;
$desktop: 1024px;
#mixin hero-image() {
.hero {
background-position: center;
background-size: cover;
background-image: url('../assets/hero-2.jpg');
#media screen and (min-width: $tablet) {
background-image: url('../assets/hero-3.jpg');
}
#media screen and (min-width: $desktop) {
background-image: url('../assets/hero-1.jpg');
}
}
}
#include hero-image();
You're still going to have to write the background-image property 3 times. The way you were doing it was close, but you would have had to #include modifier() 3 times in your consuming scss file. At the end of the day SASS compiles to CSS. You could potentially use a SASS function or For Loop to achieve this, but mixins can get really complicated and powerful, but also incredibly difficult to read and understand. Here's what the mixin I just showed you compiles to in CSS.
.hero {
background-position: center;
background-size: cover;
background-image: url("../assets/hero-2.jpg");
}
#media screen and (min-width: 768px) {
.hero {
background-image: url("../assets/hero-3.jpg");
}
}
#media screen and (min-width: 1024px) {
.hero {
background-image: url("../assets/hero-1.jpg");
}
}
I recommend putting your SCSS/SASS into this compiler to see your results before compiling your actual project.
https://www.sassmeister.com/
Even though you are repeating background-image 3 times inside of the mixin this is very much still DRY code because you can include that one mixin everywhere your images will be shown and if you need to edit it, you can edit it in one place.

Syntax to combine media query with a qualifying selector

In our current design, form elements get styled differently on a mobile device:
#media screen and (max-width: 759px) {
form label {
display: block;
float: none;
}
/*There's more...*/
}
Given the limited screen space, we're basically forcing a vertical form layout (#3-4 in this classic uxmatters link).
Because some form labels have to be insanely verbose For sensible reasons, we now want to apply this style to some desktop forms, i.e. outside of scope of the media query. This, however, is invalid SASS syntax:
#media screen and (max-width: 759px), .vertical-form {
/*...*/
}
How can the ruleset be applied on output within the media query and to .vertical-form form label (or, ideally, form.vertical-form label) elements?
Media queries are not selectors, they are special language constructs. You can't combine them with anything other than media queries. You will have to use a mixin to do what you're asking for because extends don't work across media queries either.
#mixin vertical-form {
label {
display: block;
float: none;
}
}
#media screen and (max-width: 759px) {
form {
#include vertical-form;
}
}
.vertical-form {
#include vertical-form;
}

jqGrid Pager Area - Using Font Awesome Icons

I would like to use Font Awesome icons:
<i class="icon-edit"></i>
in the jqGrid pager area instead of the physical images by default.
.navButtonAdd('#vw_ComplaintSearchGridPager', { caption: '', buttonicon: 'ui-icon-disk', title: 'Save Grid Settings', onClickButton: function () { $(this).SaveGridSetting(); } })
Does anyone know how to achieve this?
It's very interesting question! I never used Font Awesome icons before, but it seems very interesting project.
jqGrid has currently no direct support of Font Awesome icons, but I prepared the simple demo which shows how to replace the standard jQuery UI navigator icons with the corresponding icons from Font Awesome.
One can see mostly clear the difference to the original navigator icons after zoom of the page. I included below the navigator displayed with zoom 400%:
The original navigator using jQuery UI icons
The navigator with Font Awesome icons:
The code which I used is very simple. Instead of usage
$grid.jqGrid("navGrid", "#pager", {view: true});
I used
$grid.jqGrid("navGrid", "#pager", {editicon: "icon-pencil",
addicon: "icon-plus", delicon: "icon-trash", searchicon: "icon-search",
refreshicon: "icon-refresh", viewicon: "icon-file",view: true});
$("#pager .navtable .ui-pg-div>span").removeClass("ui-icon");
I added the CSS
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div>span { margin: 0 5px; font-size: 12px; }
I think it's possible to replace more jQuery UI icons to Font Awesome icons, but it's not very simple. I will think about the problem more and will contact the developer of jqGrid (Tony Tomov) to consider to make jqGrid more friendly to Font Awesome icons, so that it could be possible very simple switch to Font Awesome icons.
UPDATED: I added the code which allows top replace more icons from the pager:
var $pager = $grid.closest(".ui-jqgrid").find(".ui-pg-table");
$pager.find(".ui-pg-button>span.ui-icon-seek-first")
.removeClass("ui-icon ui-icon-seek-first")
.addClass("icon-step-backward");
$pager.find(".ui-pg-button>span.ui-icon-seek-prev")
.removeClass("ui-icon ui-icon-seek-prev")
.addClass("icon-backward");
$pager.find(".ui-pg-button>span.ui-icon-seek-next")
.removeClass("ui-icon ui-icon-seek-next")
.addClass("icon-forward");
$pager.find(".ui-pg-button>span.ui-icon-seek-end")
.removeClass("ui-icon ui-icon-seek-end")
.addClass("icon-step-forward");
As the result one get the following pager:
instead of
UPDATED 2: The code for changing minimizing icon looks a little completer. One should first change the icon initially
$grid.closest(".ui-jqgrid")
.find(".ui-jqgrid-titlebar>.ui-jqgrid-titlebar-close>.ui-icon-circle-triangle-n")
.removeClass("ui-icon ui-icon-circle-triangle-n")
.addClass("icon-circle-arrow-down");
and then change it after every click on the icon:
onHeaderClick: function (gridstate) {
if (gridstate === "visible") {
$(this.grid.cDiv).find(">.ui-jqgrid-titlebar-close>span")
.removeClass("icon-circle-arrow-up ui-icon-circle-triangle-n")
.addClass("icon-circle-arrow-down");
} else if (gridstate === "hidden") {
$(this.grid.cDiv).find(">.ui-jqgrid-titlebar-close>span")
.removeClass("icon-circle-arrow-down ui-icon-circle-triangle-s")
.addClass("icon-circle-arrow-up");
}
}
Additionally one need to add the CSS
.ui-jqgrid .ui-jqgrid-titlebar-close>span { margin: 0 3px; font-size: 16px; }
.ui-jqgrid .ui-jqgrid-titlebar-close { text-decoration: none; }
To fix the sorting icons I used the code
var $sortables = $grid.closest(".ui-jqgrid")
.find(".ui-jqgrid-htable .ui-jqgrid-labels .ui-jqgrid-sortable span.s-ico");
$sortables.find(">span.ui-icon-triangle-1-s")
.removeClass("ui-icon ui-icon-triangle-1-s")
.addClass("icon-sort-down");
$sortables.find(">span.ui-icon-triangle-1-n")
.removeClass("ui-icon ui-icon-triangle-1-n")
.addClass("icon-sort-up");
and the CSS
.ui-jqgrid .ui-icon-asc { height: auto; margin-top: 0; }
.ui-jqgrid .ui-icon-asc, .ui-jqgrid .ui-icon-desc {
height: auto; margin-top: 0; margin-left: 5px;
}
.ui-jqgrid .s-ico>.ui-state-disabled, .s-ico>.ui-state-disabled { padding: 0; }
As the result one will get the following:
UPDATED 3: In the next demo one can find more full replacement of jQuery UI icons to Font Awesome icons.
UPDATED 4: The answer provides solution for Font Awesome version 4.x.
Figured I would put a CSS alternative answer for those interested. One of our developers implemented a JS option, which did functionally work, however, there was a delay before it rendered correctly (not ideal).
We used font-awesome icons for our paging options, and here is how we implemented it.
Found the four classes that jqGrid was using for the paging icons we desired to customize and created the following css to apply base font awesome styles
.ui-icon-seek-next, .ui-icon-seek-prev, .ui-icon-seek-end, .ui-icon-seek-first
{
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
Then it is simply a matter of grabbing the content from font-family icon and using them as your own.
.ui-icon-seek-next:before
{
content: "\f105";
}
.ui-icon-seek-prev:before
{
content: "\f104";
}
.ui-icon-seek-end:before
{
content: "\f101";
}
.ui-icon-seek-first:before
{
content: "\f100";
}
So the entire CSS together looks like this
.ui-icon-seek-next, .ui-icon-seek-prev, .ui-icon-seek-end, .ui-icon-seek-first
{
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
.ui-icon-seek-next:before
{
content: "\f105";
}
.ui-icon-seek-prev:before
{
content: "\f104";
}
.ui-icon-seek-end:before
{
content: "\f101";
}
.ui-icon-seek-first:before
{
content: "\f100";
}
And the output on our grid without JS and without delay
By looking at answer from Oleg above, I did the following to simplify things.
Additional CSS
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div>span.fntawsm { margin: 0 5px; font-size: 12px; padding-left:2px;padding-right:2px;}
** padding-left:2px;padding-right:2px; is optional
And this only works with icons only with no caption ...
And then just start adding fontawesome icons in navButtonAdd like
caption:"", // important for above
title:"Give any",
buttonicon:"fntawsm icon-remove"
buttonicon:"fntawsm icon-eject icon-rotate-90"
etc .. You can use all extra functionality from font-awesome like icon-rotate-XX too.
Thisway i did`nt have to remove ui-icon class from spans.
Inspired by #afreeland answer, I created a css available on github which allows you to convert your icons to Font-Awesome icons.
The performance advantage of this over the jquery method that #Oleg described is important in my opinion.
It is also a very elegant solution in my opinion.
You are welcome to use it: https://github.com/guylando/ToAF
Note: you must give priority for this ToAF.css file styles over your other icons styles so that can be achieved for example by copying the css content into a tag in your document.

Resources