CSS: composing class names inside media queries - css

I have some styles inside a class which can be used standalone, but I would also like to apply these styles to another class when a media query condition is met. Below is an example.
I have two classes: light and dark.
.light {
border: 1px solid;
background-color: white;
}
.dark {
border: 1px solid black;
background-color: black;
color: white;
}
<h2>light</h2>
<div class="light">foo</div>
<h2>dark</h2>
<div class="dark">foo</div>
Now I want to compose these class names to create a new version: light on mobile (i.e. narrow screens), dark on desktop (i.e. wide screens).
The only way I'm aware of doing this is by duplicating my styles:
#media (max-width: 499px) {
.lightOnMobileAndDarkOnDesktop {
border: 1px solid;
background-color: white;
}
}
#media (min-width: 500px) {
.lightOnMobileAndDarkOnDesktop {
border: 1px solid black;
background-color: black;
color: white;
}
}
<h2>light on mobile, dark on desktop</h2>
<div class="lightOnMobileAndDarkOnDesktop">foo</div>
However I would like to achieve this without duplicating the styles for my classes, and without JavaScript.
Here is some pseudo code which illustrates what I would like to achieve:
#media (max-width: 499px) {
.lightOnMobileAndDarkOnDesktop {
#extend .light;
}
}
#media (min-width: 500px) {
.lightOnMobileAndDarkOnDesktop {
#extend .dark;
}
}
If there isn't any way to achieve something to this effect today, my next question would be: are there any proposals for CSS that would allow me to achieve this in the future?

Related

Can we nest media queries (SASS) that doesn't add to the overall size of the compiled output via Gulp?

Using Gulp: The idea is to write media queries inline and nest as needed but in the compiled source they are nested under a singular media query. Ideas on if this is currently possible?
Example:
.selector {
background-color: #efefef;
#media screen and (min-width: $break-tabletSmall) {
background-color: #000;
}
}
.selector-2 {
background-color: #ddd;
#media screen and (min-width: $break-tabletSmall) {
background-color: #fff;
}
}
This currently compiles into something like this:
.selector {
background-color: #efefef;
}
#media screen and (min-width: $break-tabletSmall) {
.selector {
background-color: #000;
}
}
.selector-2 {
background-color: #ddd;
}
#media screen and (min-width: $break-tabletSmall) {
.selector-2 {
background-color: #fff;
}
}
The desired outcome: Note the size is a bit smaller as there is a singular media query referenced.
.selector {
background-color: #efefef;
}
.selector-2 {
background-color: #ddd;
}
#media screen and (min-width: $break-tabletSmall) {
.selector {
background-color: #000;
}
.selector-2 {
background-color: #fff;
}
}
This issue in Sass Github is related to this problem. And you have this:
These optimizations are no longer planned. Sass does what it can to eliminate extra whitespace and choose the smallest possible representation for values, but it's primary focus is being the best preprocessing language it can be rather than the best CSS compressor.
So actually you should use PostCSS and maybe postcss-combine-media-query plugin. Or I found this gulp plugin. My recommendation for CSS optimizations and compression is PostCSS.
But if you want to solve this issue only with Sass, you can use output buffering as said by heygrady in the issue linked above.

hover is acting as a click in small size views

when I go to different views like 1024 X 768 then hover is acting as click. Buts its working fine in normal laptop size window.
when I hover over link it changes color to blue, but in small size screen it doesn't change color on hover, it change color on click
Below is HTML code
<div class="account-wrapper">
<ul>
<li>{{...}}
<span class="helpIcon icon-interface-question-mark" (click)="toggleHsaInfo()">
</span>
</li>
</ul>
<div>
Below is scss code
.account-wrapper {
border-bottom: 1px solid $border-color;
.icon-interface-question-mark {
position: relative;
cursor: pointer;
&:hover {
color:blue;
}
}
I tried to solve like this
#media only screen
and (min-device-width: 768px)
and (max-device-width: 1024px)
{
.account-wrapper{
.icon-interface-question-mark{
&:hover {
color: blue;
}
}
}
}
I believe your question is related to mobile devices without the ability to hover. You can accomplish this in various ways but I prefer CSS media queries.
.account-wrapper {
border-bottom: 1px solid green;
.icon-interface-question-mark {
position: relative;
cursor: pointer;
}
}
#media (hover: hover) {
.helpIcon:hover { color: blue; }
}
#media(hover:none){
*:hover { color: inherit !important; }
*:active {color: blue !important;}
}
You can also try #media(hover:on-demand)
Example: https://stackblitz.com/edit/angular-ou67ut?file=src%2Fapp%2Fapp.component.scss

Can I set a global variable using a media query?

I have a code smell that looks like this:
$mobile-bg-color: #ddddff;
$desktop-bg-color: #ffdddd;
$mobile-border: solid 2px black;
$desktop-border: solid 2px red;
div {
margin: 50px;
#media screen and (max-width: $mobile_threshold){
background-color: $mobile-bg-color;
border: $mobile-border;
}
#media screen and (min-width: $mobile_threshold + $threshold_step){
background-color: $desktop-bg-color;
border: $desktop-border;
}
}
And I'm having to do this anywhere where details might be different between mobile and desktop.
What I'd really like to do is:
div {
margin: 50px;
border: $responsive-border;
background-color: $responsive-bg-color;
}
This is possible using Sass?
You can achieve this with a mixin. Define a mixin like so:
#mixin responsive-border {
#media screen and (max-width: $mobile_threshold){
background-color: $mobile-bg-color;
border: $mobile-border;
}
#media screen and (min-width: $mobile_threshold + $threshold_step){
background-color: $desktop-bg-color;
border: $desktop-border;
}
}
Then call it like this:
div {
margin: 50px;
#include responsive-border;
}
You can do the same for any set of rules you will use often. Mixins help keep your code DRY.
Expanding on jmargolisvt's answer - you can also pass in the name of a property to the mixin, and have it resolve that.
eg.
#mixin responsive-bg-color ($prop){
#media screen and (max-width: $mobile_threshold){
#{$prop} : #ddddff;
}
#media screen and (min-width: $mobile_threshold + $threshold_step){
#{$prop} : #ffffdd;
}
}
#mixin responsive-margin-value($prop) {
#media screen and (max-width: $mobile_threshold){
#{$prop} : 2px
}
#media screen and (min-width: $mobile_threshold + $threshold_step){
#{$prop} : 20px
}
}
div {
margin: 50px;
border: solid 2px;
#include responsive-bg-color ("background-color");
#include responsive-margin-value("padding-top");
}
p {
#include responsive-margin-value("padding-bottom");
background-color: #ddeedd;
}
This is a little limited, as you won't be able to use shorthand css for example, but it works.

responsive design - which type of css does it use?

when i have this Code
HTML
<div id = 'bl'>
</div>
CSS
#bl {
font-size: 12px;
Color: #ff0000;
......
}
#media only screen and (min-width: 0px) and (max-width: 799px)
{
#bl {
border: 1px solid #ff0000;
}
}
it's only an example.
which type of Code does it use when the Screen size is between 0 and 799? both or only the one in media query without the other "bl" (font-size...)?
The styles get applied from a top down approach. So, the first style would be read and computed, then the media query styles would overwrite the styles above if the screen is within 0 and 799px.
Both.
but if you had :-
#bl {
font-size: 12px;
Color: #ff0000;
...
border: 2px solid red;
Then the border in media query would then override.

Resizing Bootstrap NavBar

I am creating a website using Bootstrap and want to resize the Navbar height when the browser screen is min-width: 268, I am using a media query to do this but for some reason the media query changes the height of the Navbar before the screen has been made smaller, can someone please help, code is below.
.navbar-inverse {
background-color: #fff;
border-color: transparent;
height: 105px;
}
#media only screen and (min-width: 268px) {
.navbar-inverse {
background-color: #fff;
border-color: transparent;
height: 50px;
}
}
If you want this style to apply when the width is LESS than 286px, use max-width. Try this:
#media only screen and (max-width: 268px) {
.navbar-inverse {
background-color: #fff;
border-color: transparent;
height: 50px;
}
}

Resources