Use CSS for class and media query - css

I have a menu bar that slides opened and closed. Its closed state is also what it looks like when the screen is sufficiently small. So, I basically have the same styles twice: once as a class and once as a media query.
Is there any way to avoid this?
Edit ¹:
I want to avoid having a media query style AND a class. It would be nice if there was some clever way of applying the same style via both a class and media query.
Edit ²:
Code example (for illustrative purposes):
menu {
width: 100px;
}
menu.closed { /*triggered via class addition in javascript */
width:10px;
}
#media (max-width:1000px) {
menu { /*notice how this is the same as the closed class*/
width:10px;
}
}

You have achieved the most compact code using pure CSS.
To achieve an even more dry CSS code, you can use a CSS preprocessor.
They are tagged as dynamic-css. Some of them are less, and sass.
Less example:
#small-menu: 10px;
menu {
width: 100px;
}
menu.closed {
width: #small-menu;
}
#media (max-width:1000px) {
menu {
width: #small-menu;
}
}
Sass example:
$small-menu: 10px;
menu {
width: 100px;
}
menu.closed {
width: $small-menu;
}
#media (max-width:1000px) {
menu {
width: $small-menu;
}
}

Related

how to hide/show a div using a media query but not when it's within another div

I'm trying to hide a specific div using a media query which is working fine. However, I need it to show when that div is within another specific div. Is this possible. This is the CSS:
#media (min-width: 665px) {
.mrbcircle-ipad:not(.link-inside.mrbcircle-ipad) {
position:absolute;
display:none;
}
}
so .mrbcircle-ipad should be hidden over 665px unless it's within .link-inside.
Currently this is showing .mrbcircle everywhere so I know it's wrong. How can I fix this?
Thanks
Anthony
#media (min-width: 665px) {
.mrbcircle-ipad {
position:absolute;
display:none;
}
.link-inside .mrbcircle-ipad{
position relative;
display: block;
}
}
Use two rules inside the media query: The first to hide it when the viewport is wider than 665px, the second to make it visible if it's inside a certain parent:
#media (min-width: 666px) {
.mrbcircle-ipad {
position:absolute;
display:none;
}
.link-inside .mrbcircle-ipad{
display: block;
}
}

Deduplicating CSS rules when using #media queries

I've noticed more and more that my stylesheets generally have repeated rules as a normal selector as well as inside a #media ... {} query and generates quite a lot of CSS bloat.
Here's a simple use-case of the problem that I see popping up ad nauseam:
.big-red {
color:red;
font-size: 3em;
... lots of other stuff
}
.dynamic-uber-class {
color:green;
font-size:2em;
}
#media only screen and (min-width: 48em) {
.dynamic-uber-class {
color:red;
font-size: 3em;
... lots of other .big-red duplicated stuff
}
}
I notice that the problem becomes increasingly problematic when I use mixins in less or scss (because it's really easy to add), but what's really needed is mixins in CSS (for which I won't be holding my breath!). That said, I've noticed CSS-Properties, with some support and #apply that has no support.
Has anyone stumbled on a CSS only way of not having this duplication?
I'm aware that with a bit of Javascript I can simply add/remove classes, but I like my sites working properly with javascript disabled (as much as possible).
Edit:
For those struggling to understand the problem, take a real-world example from bootstrap's grid:
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
...
#media (min-width: 768px) {
.col-sm-12 {
width: 100%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-10 {
width: 83.33333333%;
}
}
If you've ever looked at the generated CSS of bootstrap it is very fat indeed due to the problem.
Why not something like this:
.uber-class, .dynamic-uber-class {
color:red;
font-size: 3em;
... lots of other duplicated stuff
}
#media only screen and (min-width: 48em) {
.dynamic-uber-class {
... only unique styles
}
}

Cakephp 3 Side Navigation resize

I am trying to change the layout so the side navigation is smaller which i have done by editing the cake.css
.top-bar.expanded .title-area {
background: #01545b;
width:350px;
}
#actions-sidebar {
background: #fafafa;
width:350px;
}
However the main content has not moved across not sure what i need to edit for it to align correctly
Thanks
Richard
Add a local.css file and add this. Set the percentages to your liking, but make sure they add up to 100%.
#media only screen and (min-width: 64.0625em) {
.large-3 {
width: 15%;
}
.large-9 {
width: 85%;
}
}
Or you could create a theme. See this post: http://www.sanisoft.com/blog/2014/07/21/themes-in-cakephp-3-howto/

less :extend() with media queries

I am trying to extend a simple class
.positionAbsolute {
position: absolute;
}
My issue here is that I can extend it like:
#something:extend(.positionAbsolute) {
something else
}
But from inside the media query itself, If i try from outside no rule is extended at all.
Is this the normal behaviour?, why is doing that?, In such case I will have to create like four equal classes to extend in each media query case, is there some workaround?
Thank you
I'm not sure I understand it right (it's always hard to guess w/o seeing an exact CSS output you need to achieve), but it looks like you need something like:
.positionAbsolute {
position: absolute;
}
#something:extend(.positionAbsolute) {
#media only screen and (min-width: 1024px) {
something: else;
}
}
The other way around is:
.positionAbsolute {
position: absolute;
}
#class-1,
#class-2 {
&:extend(.positionAbsolute);
}
#media only screen and (min-width: 1024px) {
#class-1 {
something: else;
}
#class-2 {
something-even: more else;
}
}
That way you will have to repeat selectors instead of media queries.
I was trying to do this, and was quite disappointed I couldn't put the extend within a media query. Fortunately I was able to use a mixin for what I wanted. This may work for some situations. I can't really tell what you're actually doing with your case.
.centerVertically()
{
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em;
border: 2px solid red;
.content
{
display: inline-block;
vertical-align: middle;
}
}
used in media query
#media screen and (min-width: #break_tablet)
{
/* doesn't work
&:before:extend(.centerVertically_wrapper){}
.content:extend(.centerVertically_child){}
*/
.centerVertically();
The best I came up with I turned into a GIST here. Basically, I created an externalized reference mixin for the query and imported all the possible contexts into it. LESS sees through the query when you are referencing a class to extend but it will export it.
Reference:
.narrow {
#media screen and (max-aspect-ratio: 1/1) {
#import "position";
#import "z";
}
}
Export:
#import (reference) "narrow";
.style-1:extend(.position .abs, .narrow .position .rel) {
}
.style-2:extend(.narrow .position .rel) {
}
.style-3:extend(.narrow .z .index-1) {
}

Media Query Styles Not Overriding Original Styles

I'm attempting to use some media queries for a website I'm building. The problem I'm having however, is while the media query styles are actually being applied, they're being overridden. I can't for the life of me tell why because I'm using the same exact selectors. Can anyone point out something that I'm not seeing?
ORIGINAL CSS
#global-wrapper-outer > #global-wrapper-inner {
width: 85%;
height: 100%;
margin: 0 auto;
position: relative;
}
#global-wrapper-outer > #global-wrapper-inner > nav {
background: #fff;
padding-bottom: 20px;
box-shadow: 0 4px 2px -2px gray;
}
MEDIA QUERY CSS
#media screen and (max-width:1024px) {
#global-wrapper-outer > #global-wrapper-inner {
width: 100%;
}
#global-wrapper-outer > #global-wrapper-inner > nav {
display: none;
}
}
The second media query is working fine, where I set the nav to have a display of none. However, when I try to set the width of #global-wrapper-inner to 100% it doesn't apply. I can see the style being "applied" when I press F12 and select that element. However, the style itself is crossed out and not actually applied and it still has the original width of 85%.
The selectors in your original CSS have the same specificity as the selectors within your media queries (the first declarations are also targeting the same property - width) and because the media query rule set is being overridden I'm going to assume that it appears before the original rule set.
The second media query selector works because it's targeting a property that wasn't set in your original CSS, so specificity isn't relevant.
To have the first media query selector take precedence, prepend an ancestor element to it:
#media screen and (max-width:1024px) {
body #global-wrapper-outer > #global-wrapper-inner {
width: 100%;
}
#global-wrapper-outer > #global-wrapper-inner > nav {
display: none;
}
}
You need to link the media query file (queries.css) later than the normal css file (style.css). That way the rules in the queries.css will override those in style.css.
I have been at least 2 hours trying to find the override CSS problem till I found that my line comments where wrong... And the second definition of CSS wasn't working:
So, don't be so stupid as I !:
/* LITTLE SCREENS */
#media screen and (max-width: 990px) {
... whatever ...
}
/* BIG SCREENS */
#media screen and (min-width: 990px) {
... whatever more ...
}
never use: Double bar as I did:
// This is not a comment in CSS!
/* This is a comment in CSS! */
Here is the answer. (at least what worked for me)
I've had this problem before, and it took me a while to realize what I did, but once I figured it out it's actually pretty easy.
Ok so imagine I have this as the html
<main>
<div class = "child1"> </div>
<div class = "child2"> </div>
</main>
and then this as the CSS
main .child1{
height: 50px;
}
/* now let's try to use media quaries */
#media only screen and (max-width: 768px) {
.child1{
width: 75%;
}
}
The code above won't affect the .child. Just like someone mentioned above, the main .child1 overrides .child1. So the way you make it work is to select the element just like we did at the very beginning of the CSS above.
/* this will work */
#media only screen and (max-width: 768px) {
main .child1{
width: 75%;
}
}
So as a conclusion... select the elements the same way every time.
Meaning ... for example in the above code, in your CSS, you should either select it as main .child1throughout the whole CSS or .child1 or else they get mixed up, one ends up overriding the other.
From the code you submitted, this probably won't resolve your issue. However, in your CSS if you are nesting styles inside of one another:
.main-container {
.main {
background: blue;
}
}
A media query for .main won't work because of the nesting. Take .main out of .main-container and then the media query will work as assumed:
.main-container {
}
.main {
background: blue;
}
Check if your media query braces are equal.
Sometimes it is very subtle but when you miss a single brace the rest of the media queries mentioned for certain break points will not work
example:
#media(min-width: 768px) and (max-width: 991px){
#media (max-width: 767px){
.navbar-brand p {
font-size: .6em;
margin-top: 12px;}
.navbar-brand img {height: 20px;}
#collapsable-nav a {
font-size: 1.2em;
}
#collapsable-nav a span {
font-size: 1.2em;}
}
Here you can see i have started the braces for max-width:991px but forgot to end so the next set of codes in media query for max-width:767px will not work.
It is a very simple mistake but took hours because of lot of braces in the codes.
Hope it helps. Happy Coding!
What about using !important? If you range your media query from ( min-width: 176px ) and ( max-width: 736px ) or even up to 980px?
There can be some reasons because of which this type of error may occur.
I myself faced this issue where I was not able to understand what I am needed to do and was confused that, does media query just overrides the elements.
Here's what I understood:
MEDIA QUERY CSS:
#media screen and (max-width:1024px) {
#global-wrapper-outer > #global-wrapper-inner {
width: 100%;
}
#global-wrapper-outer > #global-wrapper-inner > nav {
display: none;
}
}
here you were able to override #global-wrapper-inner > nav i.e., 2nd media query selector, by display: none;
because you never added the display line in the original css, because of which there was nothing to override you just have given that display type should be none.
Whereas just in the 1st media query selector you already had given width:80%;
Basically media query doesn't override as far as I have understood but it take precedence, like already explained by one of them
by which media query comes to work:
https://stackoverflow.com/a/19038303/15394464
also if still did not get your doubt clear, https://www.youtube.com/watch?v=acqN6atXVAE&t=288s
then this might help.

Resources