Assigning different classes on different screen sizes with css - html

Let I have 2 classes named class1 and class2. Also I have an element with id="responsive_element". What I want is to assign class1 to this element when screen size is below 768px and class2 otherwise.
I can do this in Less like:
#media screen and (max-width:768px){
#responsive_element{
.class1()
}
}
#media screen and (min-width:769px){
#responsive_element{
.class2()
}
}
Is there any "CSS only" way to achieve this?
Edit: I think I couldn't explain my question clear enough. I am already able to do this by compiling less, but the size of css file grows for the long class definitions and using them too much. I want to handle it with simply changing class of the element .

Except for the .class1() and .class2() calls, your Less code already is CSS. Specifically, the #media queries that apply styling based on screen size aren't Less-specific. So, for example, the following is pure CSS:
#media screen and (max-width:768px){
#responsive_element{
color: blue;
}
}
#media screen and (min-width:769px){
#responsive_element{
color: red;
}
}
If you want to convert your Less into CSS, all you need to do is copy the CSS code from .class1 and .class2 into the place of the .class1() and .class2() calls. In fact, since Less is implemented as a converter to CSS, you can just use the online converter at LESS2CSS to do the conversion for you.
If you're asking if there's a way in plain CSS to write these queries so that they use an existing .class1 and .class2 style definition without copying, then I believe the answer is no. The main reason Less was invented was because CSS doesn't support this kind of reuse of styling information.

If you mean, is there a way to use CSS alone to change the class of an element in response to changing screen sizes (literally, adding or removing new classnames to the element's HTML "class" attribute so CSS for different classes will take effect on that element), then the answer is simply "no, you cannot do this with CSS alone".
(Less can't do this either. Your original Less code doesn't change the class attribute of the element, as you can plainly see by looking at the generated CSS. It just uses classes as a handy trick to name sections of shareable CSS.)
The only way to change the element's class in the manner you seem to want is to make changes to the DOM, which you can obviously do via JavaScript but not with CSS alone.

Related

How to apply different class styles to element for different screen sizes?

So in my project I have included Sass styles from a third party library (trough node modules). Normally nobody touches such code as it is subject to updates etc. However the design from artist requires to apply class x styles when its desktop and y class styles when its mobile to same element. I tried something like:
.z {
#extend .x;
}
#include media-breakpoint-down(sm) {
.z {
#extend .y;
}
}
But SASS doesn't allow this. You may not #extend an outer selector from within #media.
Another way is to duplicate the element. One has class x another y. And then show/hide them according to screen size, but that's bad for SEO and also code looks ugly.
I wonder if there is a graceful solution to this problem!?

Why is my media query rule not being prioritized?

I'm using media queries to make my site resposnive. In my CSS doc, the media queries are below all other styles. I'm am using diplay: none; which works perfectly but on another div the original width is taking priority even when I reduce the browser size.
Image of dev console:
Do I really have to add !important to every media rule?
CSS:
#media screen and (max-width: 930px) {
/* INDEX */
nav ul {
display: none;
}
#sliderContainer {
width: 80%;
height: auto;
}
}
The rule at line #112 in index.css is also applied by #sliderContainer and not by nav li, as you state in your question (it can be seen in the image you posted). Because it is met later and has same specificity, it applies.
If you place !important on a rule, you'll probably need to use !important when trying to override it, and before you know it, half your rules will be !important and fixing responsiveness is going to be a nightmare. Either slightly increase specificity of your rule or change their order.
Very important note: #media queries do not add any specificity to CSS rules. They just make them apply (when conditions are true) or not (when not true).
Useful note: A very good technique to always keep specificity of your selectors as low as possible is to place your custom stylesheets last inside <head>, after any theme/libraries/plugins stylesheets. Whenever you need to override anything, you just copy-paste the selector from where it is currently defined, and only placing it in your custom stylesheet will make it have priority without higher specificity.
Adding !important tags to your media queries may be necessary, should you need to override styles provided by a pre-set template or development platform. For example I work with Squarespace, and have to override their default styles from time to time in this way - however, as with myself, I can understand your aversion towards doing so.
I know I'm not supposed to "ask for clarification" here, but my lack of rep prevents me from simply making a comment: are you working on a web develop platform similar to Squarespace, Weebly, etc., and does applying the !important tag in fact achieve the desired result?
Best,
Tyler

Should the order of CSS files in a HTML page matter?

I have a basic HTML page and three CSS files on each. The first CSS file (core.css) is for a very generic set of rules common to all pages. The second file (additional.css) contains rules specific to items on a page (homepage, blog page and so on). The third CSS file (mobile.css) contains all media queries for mobile display. I'm also using Bootstrap.
When the files are loaded in this order:-
core.css
mobile.css
additional.css
The following media query contained in mobile.css does not get picked up by the browser.
When the files are loaded in this order:-
- core.css
- additional.css
- mobile.css
the following media query contained in mobile.css works fine.
additional.css CSS Query
.blog .blog-item.right h4, .blog .blog-item.right .item-date, .blog .blog-item.right p {
text-align: right;
}
mobile.css CSS Query
#media (min-width:768px) and (max-width:992px) {
.blog .blog-item h4, .blog .blog-item .item-date, .blog .blog-item p, .blog .blog-item.right h4, .blog .blog-item.right .item-date, .blog .blog-item.right p {
text-align: center;
}
}
Is there any reason why the top style rule has to be loaded first before the #media query is run after? What takes precedence, as I assumed that if the screen width is between 768px and 992px, that this rule would be run, over the original rule?
I'm a reasonable newbie to CSS, I'm a .NET guy, so apologies for what might be a very basic question.
Thanks
The order does matter because CSS rules can be overridden. If multiple rules match something with the same priority (the same specificity; more specific rules have higher priority), the last rule will prevail. It is not specific to multiple files, though. The same would happen if those two rules were in the same file.
In your example, loading the more general rule (without media query) would make the rule with a query obsolete, because it would be always overridden. The other way round makes sense, because the general rule will be only overridden in specific circumstances.
Short answer: Yes.
This is actually a subject I taught just last week, and I'll tell you a brief version of a one-hour class I told my students:
Bootstrap first to establish the framework
Follow with any supporting stylesheet (Owl.css, plugins.css, etc)
Next is your custom stylesheet. This is to override all of the above.
Lastly, the responsive stylesheet. This one will override all of the above systematically and programatically according to the media queries conditions being satisfied in the browser.
Doing this type of architecture will reduce the amount of (important!) drastically.
You want to be aware of a very important CSS concept known as Specificity.
If the elements affecting your media queries have the same specificity between your CSS files, then there could be conflicts.
Example:
<header class="header">Some header and stuff here</header>
additional.css could have a specific style for a <header> element, where it specifies the header selector like so:
header { background-color: red; }
However mobile.css could contain a selector for the .header class instead, in which it tries to do the following:
.header { background-color: blue; }
Due to specificity rules, guess which one will apply? The rule in additional.css
That is where thinking on your CSS structure from an architectural point of view is critical. I highly recommend you look at the differences between your files to better understand how your elements are being modified by your media queries and why.
Here is also a short discussion on contradictory CSS files asked on Stack Overflow that you might find helpful: Order of prioritization when using multiple contradictory css files.
Unless your stylesheet additional.css has a mediaquery specifying screens that are NOT between 768 and 992 pixels, there is no reason why it won't be loaded (meaning: yes, they would load normally unless you specifically cancel it out).
Media queries don't affect specificity. Therefore, a rule of thumb is to put all media queries last because you're left with specificity and order (last rules overriding all the previous ones with the same specificity).
Look:
#media (min-width:0px) {
div {background: green}
}
div {height: 20px; background: red}
<div>Nope, I won't be green</div>

Is there a way to make form fields and buttons fonts and heights responsive?

I'm working on a site which has to be compatible with many kind of devices, so I've chosen to use Bootstrap. My problem is that while I have a nice responsive grid layout, I don't see an out-of-the-box solution for making other visual parts of my site responsive. I mean for example font sizes, form field sizes, button sizes, etc.
What I want for example is to have normal button sizes for desktop, and large button sizes (.btn-lg class) for mobile. Similarly with form inputs. Is there a nice, global level solution for this way of responsiveness?
Thank for the answers.
EDIT: I would like to reuse the existing bootstrap classes as much as possible, with minimal added media-query or other code. I'm looking for something like "conditional classes" on elements based on resolution, like the following: if there is "sm" or smaller screen, add "btn-lg" to "btn"-s. If there is "md" or bigger, don't add anything, just use pure "btn". And something similar with form inputs.
Font-sizes and paddings are more simple with simple media-queries of course. My problems are mostly with form fields and buttons, just as I note in the corrected title.
I would like to avoid copying and duplicating more complex (like buttons and form fields) Bootstrap CSS code into my css
They are responsive to some extent. To add this level of responsiveness you must write your own media queries.
It's very easy. It's even easier if you are using SASS or Less.
See starting at line 260 in the variables file. Here's an excerpt.
#screen-xs: 480px;
#screen-xs-min: #screen-xs;
#screen-phone: #screen-xs-min;
A phone example:
#media (max-width: $screen-xs) {
// Change h1 size
h1 {
font-size: 20px;
}
// Change .btn font size.
.btn {
font-size: 10px;
}
}
If you are not using Sass or Less, just swap the variable $screen-xs with the value that you want--480px, for example.
use % rather than px.
Or use media queries within your css

show hidden element with css

I have a div like this:
<div class="mobile">Some mobile content</div>
This content is hidden by default (core.css):
.mobile{display: none;}
Now, I want to show this div, when browser resolution is lower than 1024px and it doesn't work:
#media (max-width: 1024px) {
.mobile{display: block;}
}
How can I show this div? Opposite way works fine - showing and then hiding when resolution changes.
Since you use the same selector, it will always use the last called selector.
See this fiddle : http://jsfiddle.net/9KtHg/
It is working perfectly since the media query is called last (so it override the CSS when the condition are met).
But here : http://jsfiddle.net/9KtHg/1/
It is not working since the display:none is last and will override the other CSS.
To avoid that, you need to use greater specificity selector in the media query like :
div.mobile <-the tag name containing class='mobile'
[.][#][tag]parent .mobile <- use the parent in the selector
.mobile{display:block!important}<- using important is a bad pratice, avoid it.
You could also include the core.css before your CSS files containing your mediaqueries.
In conclusion, welcome to the fabulous world of CSS override!
By the way, CSS mean "cascading style sheets". As it said in its name, it work as a cascade where the last declared CSS will be used!