I am trying to make a basic layout with CSS grid and the responsive part with the new specification of CSS level 4 , but it is not working for me when compiling the content of the sass, Am I failing in something? Do I miss any detail?
custom-media.scss
*{ margin: 0 ; padding: 0}
#custom-media --phone ( 320px < width < 480px);
#custom-media --tablets (481px < width < 767px);
#custom-media --ipad-landscape (768px < width < 1024px) and (orientation: landscape);
#custom-media --ipad-normal (768px < width < 1024px);
#custom-media --desktop (1025px < width < 1280px);
#custom-media --large (width > 1281px);
app.scss
#import 'custom-media';
/**
*
* Login Page
*
*/
.container{
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 60% 1fr;
grid-row: 1fr;
.presentation{
background:#CB3BBF;
}
.loginsection{
}
#media (--desktop) {
.container {
grid-template-columns: 1fr;
}
.presentation{
background:blue;
}
}
}
I try to have the width between 1025px and 1280 px the blue background color and it does not work in Chrome Versión 64.0.3282.186
you can use
#mixin responsive($size) { #if $size == large { /* 1920px / #media (max-width: 120em) { #content; } } #if $size == small { / 1199px */ #media (max-width: 74.938em) { #content; } } } #include responsive(large){ font-size: 42px; } #include responsive(small){ font-size: 22px; }
this will work.
As of now (Dec 2021), it appears that, while in the spec, #custom-media has not been implemented anywhere yet. Neither caniuse nor MDN know about #custom-media.
Related
Recently I am trying to use sass to create a mixin/function that help me with my responsive design, but I got stuck on a problem for the past three days and I have tried many different kinds of approach but nothing works.
The problem I am facing is when sass compiled, it outputs something like this, with one style per selector, which I don't want:
#media only screen and (min-width: 1920px) {
h1 {
font-size: 4rem;
}
}
#media only screen and (min-width: 2560px) {
h1 {
font-size: 6rem;
}
}
#media only screen and (min-width: 3840px) {
h1 {
font-size: 7rem;
}
}
#media only screen and (min-width: 1920px) {
h1 {
margin-top: 0.8rem;
}
}
#media only screen and (min-width: 2560px) {
h1 {
margin-top: 1rem;
}
}
#media only screen and (min-width: 3840px) {
h1 {
margin-top: 1.8rem;
}
}
I want the output to be like this:
#media only screen and (min-width: 1920px) {
h1 {
font-size: 4rem;
margin-top: 0.8rem;
}
}
#media only screen and (min-width: 2560px) {
h1 {
font-size: 6rem;
margin-top: 1rem;
}
}
#media only screen and (min-width: 3840px) {
h1 {
font-size: 7rem;
margin-top: 1.8rem;
}
}
This is my Sass file:
// function
#function size-number($base-size, $new-size) {
#if $new-size != 0 {
#return $new-size;
} #else {
#return $base-size;
}
}
// mixin
#mixin break-points-size ($properties) {
$PROPERTIES: $properties;
#each $PROPERTY-KEY, $PROPERTY-VALUE in $PROPERTIES {
$SIZE-NUMBERS: map-get($PROPERTY-VALUE, "size" );
$BREAK-POINTS: (
"screen1080": (
"break-point": "1920px",
"base-size": size-number(1,nth($SIZE-NUMBERS, 1))
),
"screen1440": (
"break-point": "2560px",
"base-size": size-number(2,nth($SIZE-NUMBERS, 2))
),
"screen2160": (
"break-point": "3840px",
"base-size": size-number(3,nth($SIZE-NUMBERS, 3))
)
);
$INDIV-PROPERTY-KEY: $PROPERTY-KEY;
$VALUE-NUMBERS: map-get($PROPERTY-VALUE, "value" );
#each $BREAK-POINT-KEY, $BREAK-POINT-VALUE in $BREAK-POINTS {
$INDIV-BREAK-POINT: map-get($BREAK-POINT-VALUE, "break-point");
$INDIV-BASE-SIZE: map-get($BREAK-POINT-VALUE, "base-size");
#media only screen and (min-width:$INDIV-BREAK-POINT) {
#{$INDIV-PROPERTY-KEY}: $VALUE-NUMBERS * $INDIV-BASE-SIZE;
}
}
}
};
*{
margin:0;
padding:0;
}
h1{
#include break-points-size(("font-size":("value": 2rem,"size": (2,3,3.5)),"margin-top":("value": 1rem,"size": (0.8,1,1.8))));
}
I just can't find which part I am doing wrong.
Here is a mixin for breakpoints you may find useful. It solves the problem of having multiple copies of the same media query for every different property.
#mixin breakpoint($map) {
$query: '';
#if map-has-key($map, media) {$query: append($query, '#{map-get($map, media)} and');}
#if map-has-key($map, min-width) {$query: append($query, '(min-width: #{map-get($map, min-width)})');}
#if map-has-key($map, min-width) and map-has-key($map, max-width) {$query: append($query, "and");}
#if map-has-key($map, max-width) {$query: append($query, '(max-width: #{map-get($map, max-width)})');}
#media #{$query} {#content;}
}
Use it like this:
h1 {
font-size: 20px;
color: #000;
#include breakpoint((min-width: 860px)) {
some-property: someValue;
some-other-property: soneValue;
}
}
p {
margin: 0;
#include breakpoint((min-width: 860px, max-width: 1000px)) {
some-property: someValue;
}
}
I wrote this mixin and I'm really not sure why is it not working as intended.
#mixin responsive($breakpoint){
#if $breakpoint == xs {
#media only screen and (max-width:35.99875em ) {
#content
}
}
#if $breakpoint == sm {
#media only screen and (min-width:35.99876em) and (max-width:47.99875em) {
#content
}
}
#if $breakpoint == md {
#media only screen and (min-width:47.99876em) and (max-width:61.99875em) {
#content
}
}
#if $breakpoint == lg {
#media only screen and (min-width:61.99876em) and (max-width:74.99875em) {
#content
}
}
#if $breakpoint == xl {
#media only screen and (min-width:74.99876em) and (max-width:85.37375em) {
#content
}
}
#if $breakpoint == xxl {
#media only screen and (min-width:85.37376em) {
#content
}
}
}
Here everything seems fine, but in VSC some "ems" are not highlighted and those "ems" that are not highlighted are not working correctly. (see image 1)
image 1
When I compile sass, it is not showing any errors, but the "ems" remain grey even in CSS code.
Below code is example usage of mixin.
body {
#include responsive(xxl){
background: rgb(147, 48, 228);
}
#include responsive(xl){
background: rgb(44, 255, 150);
}
#include responsive(lg){
background: rgb(255, 245, 100);
}
#include responsive(md){
background: rgb(255, 146, 146);
}
#include responsive(sm){
background: rgb(145, 145, 145);
}
#include responsive(xs){
background: #000;
}
}
Below code is compiled sass in CSS file.
#media only screen and (min-width: 85.37376em) {
body {
background: #9330e4; } }
#media only screen and (min-width: 74.99876em) and (max-width: 85.37375em) {
body {
background: #2cff96; } }
#media only screen and (min-width: 61.99876em) and (max-width: 74.99875em) {
body {
background: #fff564; } }
#media only screen and (min-width: 47.99876em) and (max-width: 61.99875em) {
body {
background: #ff9292; } }
#media only screen and (min-width: 35.99876em) and (max-width: 47.99875em) {
body {
background: #919191; } }
#media only screen and (max-width: 35.99875em) {
body {
background: #000; } }
image 2
At first I thought those "em" highlighting is just in VSC , but when i open browser and look in debugger I get the same result, still those "ems" are not highlighted as intended. (see image 3)
image 3
Now when i comment "ems" that are not highlighted and just rewrite the same thing in CSS file, it works without any problems. (see image 4)
image 4
Here is an example with sass compiled CSS file. (see gif 1)
gif 1
And here is an example with same breakpoints and values just written in CSS from start. (see gif 2)
gif 2
Looking at the posted question, it seems that those "ems" that are not working, are not highlighted in stack overflow as well.
I forgot to mention that rewriting the same breakpoint fixes the issue, but can anyone explain why was this happening at first place?
You have (Pop Directional Formatting) characters in your SASS code between some of the numeric values and "em". Values such 85.37376em are actually in your code as 85.37376em .
Please inspect the generate CSS in Chrome's dev tools. I attached a screenshot.
Syntax highlighting in VSCode is further corrected when you add semicolons after each of the content rules: #content;
I wrote navbar which works fine, but one strange behavior I can't understand. Why when I'm changing the width in point 631px menu appear, after 600px it disappear?? and it works in vice versa. Why it happened?? I can't find any position in media where is used this range or value which could have an influence on this behavior.
My HTML code doesn't have any special logic. I display here part of code which I changed for myself. Without toolbar.
<mat-sidenav-container class="sidenav-container">
<mat-sidenav
#drawer
class="sidenav"
disableClose="false"
fixedInViewport="non-fixed"
[ngClass] = "{hidden: (isHandset$ | async)!.matches}"
[attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
[mode]="isLargeScreen() ? 'side' : 'over'"
[opened]="!(isHandset$ | async)">
css style
.sidenav-container {
height: 100vh;
background: rgb(224,234,252);
background: linear-gradient(118deg, rgba(224,234,252,1) 0%, rgba(255,255,255,1) 100%);
}
.sidenav {
width: 200px;
box-shadow: 3px 0 6px rgba(0, 0, 0, 0.24);
}
.hidden {
display: none;
}
.mat-toolbar.mat-primary {
position: sticky;
top: 0;
}
::ng-deep .mat-toolbar.mat-primary{
width: 100% !important;
padding: 0px 0px 0px 15px ;
}
::ng-deep .mat-list-item-content {
width: 100% !important;
padding: 0px !important;
}
::ng-deep .mat-list-item-content a {
width: 100% !important;
padding: 0px 15px;
}
#media (max-width: 599px) {}
.mat-toolbar-row, .mat-toolbar-single-row {
height: 64px;
}
.title-description {
margin-left: 4px;
}
#button-icon-menu {
margin-left: 10px;
}
and ts file
export class NavBarComponent {
isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
.pipe(
map(result => result.matches)
);
constructor(
private breakpointObserver: BreakpointObserver,
) {}
isLargeScreen() {
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
if (width > 720) {
return true;
} else {
return false;
}
}
}
1st thing I noticed in your code:
[ngClass] = "{hidden: (isHandset$ | async)!.matches}"
Why are you accessing matches property if you already map in your code to the boolean variable?
2nd The Breakpoints.Handset you are effectively saying the following:
The breakpoint you are adding is returning true, for all widths above 600px. Check the angular code for this:
Handset: '(max-width: 599.99px) and (orientation: portrait),
/**
* #license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// PascalCase is being used as Breakpoints is used like an enum.
// tslint:disable-next-line:variable-name
export const Breakpoints = {
XSmall: '(max-width: 599.99px)',
Small: '(min-width: 600px) and (max-width: 959.99px)',
Medium: '(min-width: 960px) and (max-width: 1279.99px)',
Large: '(min-width: 1280px) and (max-width: 1919.99px)',
XLarge: '(min-width: 1920px)',
Handset: '(max-width: 599.99px) and (orientation: portrait), ' +
'(max-width: 959.99px) and (orientation: landscape)',
Tablet: '(min-width: 600px) and (max-width: 839.99px) and (orientation: portrait), ' +
'(min-width: 960px) and (max-width: 1279.99px) and (orientation: landscape)',
Web: '(min-width: 840px) and (orientation: portrait), ' +
'(min-width: 1280px) and (orientation: landscape)',
That is why your ng class hidden matches this case.
In an effort to better understand the use of Sass mixins I am trying to learn to use them for my media query breakpoints and it only seems to be processing them above and below 37.5em. So, if you look at the SCSS code I have posted below, it will render the styles for mobileonly(below 37.5em on the viewport window) and phablet(above 37.5em on the viewport window), but not for laptop or desktop. When the viewport window is stretched larger it will not change past my $firefly hexidecimal variable I declared. According to Chrome dev tools, the media queries appear to be working, but the #media (min-width: 37.5em) seems to be overwriting the styles still because the styles that I want are crossed out in dev tools. So, even at the full viewport window size,#media (min-width: 37.5em) is the only style being applied. Why would this be?
Here is a jsfiddle of my exact issue.
And, for further clarification, here's my code:
HTML:
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/build/main.css">
</head>
<body>
<header>
</header>
</body>
</html>
SCSS:
$azure: #f3f4f4;
$chateau-green: #2bb656;
$firefly: #364141;
$fern: #59cb59;
$pastel-green: #75dd66;
$pigment-green: #0ca750;
#mixin breakpoint($point) {
#if $point == desktop {
#media (min-width: 70em) { #content ; }
}
#else if $point == laptop {
#media (min-width: 64em) { #content ; }
}
#else if $point == tablet {
#media (min-width: 50em) { #content ; }
}
#else if $point == phablet {
#media (min-width: 37.5em) { #content ; }
}
#else if $point == mobileonly {
#media (max-width: 37.5em) { #content ; }
}
}
header {
height: 600px;
width:100%;
#include breakpoint(desktop) {
background-color:$azure;
}
#include breakpoint(laptop) {
background-color:$chateau-green;
}
#include breakpoint(phablet) {
background-color:$firefly;
}
#include breakpoint(mobileonly) {
background-color:$pastel-green;
}
}
EDIT: Added Outputed CSS:
header {
height: 600px;
width: 100%;
}
#media (min-width: 70em) {
header {
background-color: #f3f4f4;
}
}
#media (min-width: 64em) {
header {
background-color: #2bb656;
}
}
#media (min-width: 37.5em) {
header {
background-color: #364141;
}
}
#media (max-width: 37.5em) {
header {
background-color: #75dd66;
}
}
The issue here is that the style written for min-width: 37.5em overwrites the style written for min-width: 64em and similarly for other cases as well. For this, try to set the min-width as well as max-width both, so that the style is specific.
Here is the js fiddle.
I've added a <br> into my h1 tag visible only on xl screens (>1600px).
The <br> however is showing all the time, when I want it to respond to the XL class (visible-xl).
Live URL: http://185.123.96.102/~kidsdrum/moneynest.co.uk/
CSS:
#screen-xl: 1600px;
#screen-xl-min: #screen-xl;
#screen-xl-desktop: #screen-xl-min;
#screen-lg-max: (#screen-xl-min - 1);
#container-xl-desktop: ((1560px + #grid-gutter-width));
#container-xl: #container-large-desktop;
#media (min-width: #screen-xl-min) {
.make-grid(xl);
}
.container {
#media (min-width: #screen-xl-min) {
width: #container-xl;
}
}
.make-xl-column(#columns; #gutter: #grid-gutter-width) {
position: relative;
min-height: 1px;
padding-left: (#gutter / 2);
padding-right: (#gutter / 2);
#media (min-width: #screen-xl-min) {
float: left;
width: percentage((#columns / #grid-columns));
}
}
.make-xl-column-offset(#columns) {
#media (min-width: #screen-xl-min) {
margin-left: percentage((#columns / #grid-columns));
}
}
.make-xl-column-push(#columns) {
#media (min-width: #screen-xl-min) {
left: percentage((#columns / #grid-columns));
}
}
.make-xl-column-pull(#columns) {
#media (min-width: #screen-xl-min) {
right: percentage((#columns / #grid-columns));
}
}
.visible-xl {
.responsive-invisibility();
#media (min-width: #screen-xl-min) {
.responsive-visibility();
}
}
.hidden-xl {
#media (min-width: #screen-xl-min) {
.responsive-invisibility();
}
}
.make-grid-columns() {
// Common styles for all sizes of grid columns, widths 1-12
.col(#index) when (#index = 1) { // initial
#item: ~".col-xs-#{index}, .col-sm-#{index}, .col-md-#{index}, .col-lg-#{index}, .col-xl-#{index}";
.col((#index + 1), #item);
}
.col(#index, #list) when (#index =< #grid-columns) { // general; "=<" isn't a typo
#item: ~".col-xs-#{index}, .col-sm-#{index}, .col-md-#{index}, .col-lg-#{index}, .col-xl-#{index}";
.col((#index + 1), ~"#{list}, #{item}");
}
.col(#index, #list) when (#index > #grid-columns) { // terminal
#{list} {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (#grid-gutter-width / 2);
padding-right: (#grid-gutter-width / 2);
}
}
.col(1); // kickstart it
}
HTML:
<h1 class="boldme hidden-xs hidden-sm hidden-xl" id="homepage-headline">Wish you were taught personal finance at school?<br class="visible-xl"/>We do too</h1>
**Notes:**I'm using Bootstrap
Using two <h1> tags may be harmful for SEO purposes.
Both <h1> elements have the same ID, which is invalid markup; each ID in a document must be unique.
My solution:
HTML
<div class="text-center">
<h1 class="boldme hidden-xs hidden-sm hidden-xl" id="homepage-headline">Wish you were taught personal finance at school? We do too</h1>
<h1 class="boldme visible-xl" id="homepage-headline2">Wish you were taught personal finance at school?<br>We do too</h1>
</div>
CSS:
.hidden-xs .hidden-sm {
display: none;
}
#media all and (max-width: 1600px) {
.hidden-xs .hidden-sm {
display: block;
}
.visible-xl {
display: none;
}
}
Note: change your property or value as you want! and think about remove second <h1>