dynamically show/hide content based on window width - html

I am building a website and I need it to behave so that if the window is fullscreen (or any size where width > X px) - it should show the sidebar. If the user resizes the window's width below a certain amount, the sidebar should disappear (display:none).
A prime example to look at is google's news page (news.google.com) - there is a right sidebar which is only visible when the width of the page is above a certain threshold.
I'm usually pretty good in searching google/stack exchange and finding the answer I need, but in this case, maybe it's because of the use of the word 'dynamic' but I can't think of any other way to phrase it, i'm getting a lot of hits which are not what I need.
If I were to think of a solution on my own, I would perhaps add a javascript listener which constantly monitors the x value of the 'viewable area' and have a function constantly running that would do something like, if viewable area X value is lower than my threshold, change the style of my sidbar div to display:none. I think that would work, but I don't know if it's the best way to do this.
Thank you.

What about max-width Media Queries?
#media screen and ( max-width: 768px ) {
/* When the viewport is 768px or less,
hide #sidebar */
#sidebar {
display: none;
}
}
Demo: http://jsfiddle.net/jonathansampson/6Pvyt/show/
For IE6-8, https://github.com/scottjehl/Respond

I believe CSS Media Queries is the best solution as answered already by Jonathan Sampson,
but as youve hinted at it in your question about using a javascript listener I thought I best explain a better (IMO) JS solution using jQuery's on event.
e.g.
jQuery(window).on({
"resize": function(){
if(jQuery(window).width() > 750) {
//code to show sidebar
jQuery(#sidebar).removeclass("hidden");
} else {
//code to hide sidebar e.g.
jQuery(#sidebar).addclass("hidden");
}
}
};
});

What you need is CSS Media queries. http://www.w3.org/TR/css3-mediaqueries/
I use Twitter's bootstrap framework which includes a whole slew of responsive screen functionality.

Related

How to apply CSS style based on parent element, similar to media queries [duplicate]

I would like to use media queries to resize elements based on the size of a div element they are in. I cannot use the screen size as the div is just used like a widget within the webpage, and its size can vary.
Yes, CSS Container Queries are what you're looking for. The CSS Containment Module is the specification that details this feature.
You can read more about the decade of work, including proposals, proofs-of-concept, discussions and other contributions by the broader web developer community here! For more details on how such a feature might work and be used, check out Miriam Suzanne's extensive explainer.
Currently only Chromium 105+ supports Container queries out of the box, though Safari 16 will include support as well. Hopefully it won't be much longer before we see a robust cross-browser implementation of such a system. It's been a grueling wait, but I'm glad that it's no longer something we simply have to accept as an insurmountable limitation of CSS due to cyclic dependencies or infinite loops or what have you (these are still a potential issue in some aspects of the proposed design, but I have faith that the CSSWG will find a way).
Media queries aren't designed to work based on elements in a page. They are designed to work based on devices or media types (hence why they are called media queries). width, height, and other dimension-based media features all refer to the dimensions of either the viewport or the device's screen in screen-based media. They cannot be used to refer to a certain element on a page.
If you need to apply styles depending on the size of a certain div element on your page, you'll have to use JavaScript to observe changes in the size of that div element instead of media queries.
Alternatively, with more modern layout techniques introduced since the original publication of this answer such as flexbox and standards such as custom properties, you may not need media or element queries after all. Djave provides an example.
I've just created a javascript shim to achieve this goal. Take a look if you want, it's a proof-of-concept, but take care: it's a early version and still needs some work.
https://github.com/marcj/css-element-queries
From a layout perspective, it is possible using modern techniques.
Its made up (I believe) by Heydon Pickering. He details the process here: http://www.heydonworks.com/article/the-flexbox-holy-albatross
Chris Coyier picks it up and works through a demo of it here: https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/
To restate the issue, below we see 3 of the same component, each made up of three orange divs labelled a, b and c.
The second two's blocks display vertically, because they are limited on horizontal room, while the top components 3 blocks are laid out horizontally.
It uses the flex-basis CSS property and CSS Variables to create this effect.
.panel{
display: flex;
flex-wrap: wrap;
border: 1px solid #f00;
$breakpoint: 600px;
--multiplier: calc( #{$breakpoint} - 100%);
.element{
min-width: 33%;
max-width: 100%;
flex-grow: 1;
flex-basis: calc( var(--multiplier) * 999 );
}
}
Demo
Heydon's article is 1000 words explaining it in detail, and I'd highly recommend reading it.
Update 2021/22
As mentioned in other answers, container queries are coming. There is a full spec for it, and its usage is detailed on MDN:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries
and there is a polyfill to get browsers that don't yet support it up to speed:
https://github.com/GoogleChromeLabs/container-query-polyfill
There is a nice little overview video of it here:
https://www.youtube.com/watch?v=gCNMyYr7F6w
This has now shipped to Chrome (05 September 2022)
https://caniuse.com/css-container-queries
A Media Query inside of an iframe can function as an element query. I've successfully implement this. The idea came from a recent post about Responsive Ads by Zurb. No Javascript!
This is currently not possible with CSS alone as #BoltClock wrote in the accepted answer, but you can work around that by using JavaScript.
I created a container query (aka element query) polyfill to solve this kind of issue. It works a bit different than other scripts, so you don’t have to edit the HTML code of your elements. All you have to do is include the script and use it in your CSS like so:
.element:container(width > 99px) {
/* If its container is at least 100px wide */
}
https://github.com/ausi/cq-prolyfill
I ran into the same problem a couple of years ago and funded the development of a plugin to help me in my work. I've released the plugin as open-source so others can benefit from it as well, and you can grab it on Github: https://github.com/eqcss/eqcss
There are a few ways we could apply different responsive styles based on what we can know about an element on the page. Here are a few element queries that the EQCSS plugin will let you write in CSS:
#element 'div' and (condition) {
$this {
/* Do something to the 'div' that meets the condition */
}
.other {
/* Also apply this CSS to .other when 'div' meets this condition */
}
}
So what conditions are supported for responsive styles with EQCSS?
Weight Queries
min-width in px
min-width in %
max-width in px
max-width in %
Height Queries
min-height in px
min-height in %
max-height in px
max-height in %
Count Queries
min-characters
max-characters
min-lines
max-lines
min-children
max-children
Special Selectors
Inside EQCSS element queries you can also use three special selectors that allow you to more specifically apply your styles:
$this (the element(s) matching the query)
$parent (the parent element(s) of the element(s) matching the query)
$root (the root element of the document, <html>)
Element queries allow you to compose your layout out of individually responsive design modules, each with a bit of 'self-awareness' of how they are being displayed on the page.
With EQCSS you can design one widget to look good from 150px wide all the way up to 1000px wide, then you can confidently drop that widget into any sidebar in any page using any template (on any site) and
The question is very vague. As BoltClock says, media queries only know the dimensions of the device. However, you can use media queries in combination with descender selectors to perform adjustments.
.wide_container { width: 50em }
.narrow_container { width: 20em }
.my_element { border: 1px solid }
#media (max-width: 30em) {
.wide_container .my_element {
color: blue;
}
.narrow_container .my_element {
color: red;
}
}
#media (max-width: 50em) {
.wide_container .my_element {
color: orange;
}
.narrow_container .my_element {
color: green;
}
}
The only other solution requires JS.
The only way I can think that you can accomplish what you want purely with css, is to use a fluid container for your widget. If your container's width is a percentage of the screen then you can use media queries to style depending on your container's width, as you will now know for each screen's dimensions what is your container's dimensions. For example, let's say you decide to make your container's 50% of the screen width. Then for a screen width of 1200px you know that your container is 600px
.myContainer {
width: 50%;
}
/* you know know that your container is 600px
* so you style accordingly
*/
#media (max-width: 1200px) {
/* your css for 600px container */
}
You can use the ResizeObserver API. It's still in it's early days so it's not supported by all browsers yet (but there's several polyfills that can help you with that).
This API allows you to attach an event listener when resizing a DOM element.
Demo 1 - Demo 2
I was also thinking of media queries, but then I found this:
http://www.mademyday.de/css-height-equals-width-with-pure-css.html
Maintain the aspect ratio of a div with CSS
Just create a wrapper <div> with a percentage value for padding-bottom, like this:
div {
width: 100%;
padding-bottom: 75%;
background:gold; /** <-- For the demo **/
}
<div></div>
It will result in a <div> with height equal to 75% of the width of its container (a 4:3 aspect ratio).
This technique can also be coupled with media queries and a bit of ad hoc knowledge about page layout for even more finer-grained control.
It's enough for my needs. Which might be enough for your needs too.
For mine I did it by setting the div's max width, hence for small widget won't get affected and the large widget is resized due to the max-width style.
// assuming your widget class is "widget"
.widget {
max-width: 100%;
height: auto;
}

Is there a way to NOT repeat styles when using #media?

I'm not sure if I'm asking this question right, but couldn't think of a better wording. I am playing with a new responsive bootstrap layout, one with a fixed collapsable side menu. You know, because it's the new black.
Anyway, I setup an #media (max-width: 767px) {...} in my css and threw in some stuff to adjust the workspace around when the screen is resized. That works. Then I decided to add a button to manually toggle even if the screen was over 767px, cause... choice.
But I found myself having to repeat all the styles I put in the #media block. And that seems dumb to me, because if I tweak some numbers I'll have to tweak in several places. But I can't seem to come up with how to organize it to not repeat.
Am I missing something? Or is this where I need to relent and start using LESS or some such?
Here is a fiddle: http://jsfiddle.net/yn5n9/
(note: to get the fiddle working the 'result' pane needs to be bigger than 767px).
notice in the #media there is this:
aside {...}
.main-container {...}
#sidebar-header {...}
but then to get the toggle button working I have these (with the same definitions):
.hide-it aside {...}
.hide-it .main-container {...}
.hide-it #sidebar-header {...}
triggered by $('body').toggleClass("hide-it")
Thanks.
No way to do this with current CSS3 specs, although the upcoming CSS variables might do the trick in the near future. You're stuck with LESS/SASS/etc.
BTW, I'm assuming JavaScript is not an option.

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

Html css layouts- Web Mobile suppoort

I have a page set out similar to this:
My question is about mobile support and how should I go about doing the following:
When the user resizes the window to about the size of a smartphone screen, I want to remove the main content, which is everything below the header area/login, and keep only the header, the login form and the footer. So I have been using css media queries to do this. My problem is that my login form markup resides within the header area.
<div id = "header">
<div id= "logo"><img src =""/> </div>
+-------form markup here------+
|<div id= "login-form">..... </div>|
+ ----------------------------+
</div>
<div id= "main-content">
This is where I want to put the login form
</div>
So my question is, How should I do this?
should I just create another css file and link/apply that when the screen width-height is detected to be smartphone size ?
Should I create the markup block inside main-content, and set its css style display to none UNTIL the screen is resized to smartphone size, where a media query is set to change display attribute ?
What is the best way to accomplish this? I greatly appreciate any help and at least, some little explanation to justify that answer. Also links and other references are very welcome !
Cheers..
Use Media Queries to hide and show content based on device or device width/height.
Here's a good Media Queries Cheat-sheet:
http://stephen.io/mediaqueries/
I wouldn't position the form as 'absolute' and put it outside the header as another poster suggested. This is super sloppy and bad practice. What's the 'absolute' form going to be positioned too? The body? Aghh. You'd need a wrapper - and that's just more code. You can do it all via CSS. Just use Media Queries to change the CSS styles for the header, show/hide elements, and reposition.
OR
JQUERY (Not the best route, but for what you want you're a limited without a redesign). I kept it simple for easy explanation. Note, I haven't tested this:
$(window).resize(function(){
var maxwidth = $(window).width(); // get device window width
var form = $('#login-form'); // form
if(maxwidth <= 320) { // 320 px or whatever you want
form.clone().appendTo('#main-content'); // clone form and append to main content
form.eq(0).hide(); // hide first form, the one in the header
}
else {
form.eq(0).show(); // show initial form
form.eq(1).remove(); // remove cloned form, if set
}
});
I can see two ways you could go about accomplishing your goal:
Take your login-form out of the header div, put it in the main-content div and absolutely position it to make it appear inside the header when on a desktop screen, then use a media query to move it to below the header for viewing on mobile devices.
Use your idea of having two login-forms: one in the header, and one in the main-content area. Use media queries to change the display attribute so that the correct login-form is showing at the right time depending on the screen size. I'm not sure if duplicating the login-form is good practice, so I would try option 1 to start.
Let me know if this works out!

Responsive Web Design + SCSS site organization

For me HTML + CSS is quite complex. HTML + CSS + #media is nightmare. Now my HTML + CCS looks like spagetti. Pls help me with questions:
How should I organize my SCSS includes: by function (header/footer)
or by dimension (0_480)?
How should I use #media limits:
max-width only: 0-420, 0-870, no limit
min-width + max-width: 0-420, 421-870, 871+
min-width only: 870+, 420+, 0+
To test site for Adaptability can be easily and quickly!
http://plastilin5.com/tools/
here's a good example (check in the lower part of the site)
http://m.alistapart.com/articles/responsive-web-design/
you can place all your stylesheet imports in the header.
On how to use #media max and min widths, some developers would argue strongly for “mobile first”, e.g. focus on styles for small screens first, and then override those styles for larger screens.
http://stuffandnonsense.co.uk/blog/about/320_and_up/
I think that would match most closely with your “max-width only: 0-420, 0-870, no limit” option.
Here is what I do:
write CSS for maximum size only
at the end of the CSS file (or as #import if the project is to big) add "#media screen and (max-width: 1700px)" and write all the changes for that resolution
repeat previous step for every needed resolution
The main reason I think this is the best approach is that for the smaller screens you can (and most probably will) decide not to show some of the elements, and you'll be able to do that by simply adding display:none; to those elements on the first (biggest) resolution they are to be hidden on. While when you're building your CSS the other way around, adding elements becomes a bit harder to follow.
Sass has what they call "media query bubbling", which means that no matter what nesting level your media queries are placed at, they will bubble up to the top. This is both a good thing and a bad thing if you aren't using it responsibly (good that you can keep your media queries grouped with related styles, bad if used excessively since you end up with 100s of media queries all over the place).
What I've found that works for my workflow is to group together media queries as much as possible with the block of content that its for. Each major block of styles is broken up into its own file (master layout, image gallery, clients, etc), and each file will have as few numbers of media queries as possible (typically only 1 or 2, 3 or more for more complex blocks).
$x-small-device: 25em; // smallest
$small-device: 35em; // larger mobile
$medium-device: 55em; // tablet or really small desktop
.clients {
// no matter what resolution, these styles are always applied
#media (min-width: $small-device) {
// have our clients display in a 2-col layout
}
#media (min-width: $medium-device) {
// have our clients display in a 3-col layout
}
}
If you try to break it up based on the width of the device you're targeting, it is more difficult to find where the styles are located when it comes time to change it.
Ok, first of all I think that you should read more about CSS architecture. The first question is kinda complex and involves different concepts. I'll suggest to check OOCSS, SMACSS or Atomic design. There are some really great ideas. What I usually do is to use a mixture between all those things. I guess that you will find what it fits in your project.
Media queries should not be based on the devices or on some popular resolutions. You should set your break points based on the content that you have. Try to follow the Mobile First concept and see where the content needs updating. Very often the different break points are related to different parts of your site. I mean one media query may refer only the header of the application. Another only the footer and so on. I'll also suggest to use media queries bubbling. I.e. to place those parts inside the container that you want to change, not in a separate file or at the end of the current one.