If else statements in CSS? - html

I know that this question sounds similar to this one but it is different. I have two articles in a section and I want to render them side by side if the width of the window is big enough and underneath if the window width is too small.
The width of the first article is always 800 pixel and the second articles width is defined as the rest of the windows width minus all the paddings etc. So if the calculated width of the second article is too small, I just want to set it to a higher value, which will place the second article under the first article. This shouldn't be too hard if there are ifs like in other programming languages. From the question above I created this demo code for an if else statement but it doesn't work:
#if 1 == 1 {
border-color: #fff;
}
#else {
border-color: #000;
}
Setting to 1 == 2 which should trigger the else part still does the if part. So how can I get real if else statements?

There are no real if/else statements in CSS, you can just use media queries and define your css depending on the width of the window like this:
#media only screen and (max-width: 600px) {
body {
background-color: lightblue;
}
}
if the window is smaller than 600px, the background color is set to lightblue. You can use several queries like min-width and max-width to define your CSS. Just have a look at:
https://www.w3schools.com/css/css_rwd_mediaqueries.asp

CSS statements overwrite each other. So if you take this example:
body {
background-color: green;
background-color: red;
}
will result in the background beeing red, because it is defined later.
Now you can use this with the already mentioned media queries:
body { // your default case, if the condition is not met --> the else block
background-color: green;
}
#media(min-width: 800px){ // here the condition is met --> if block
body {
background-color: red;
}
}
Tip: you can use SCSS to make the queries way more readable.

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;
}

Resize text, but only if there's not enough room

I am creating a chart that shows keyboard commands overlaid on top of an image of a keyboard. I would like the text to shrink to the size of the container if it is too long to fit inside a key, but remain the default size otherwise. How would I accomplish this in HTML? The solutions I've seen seem to always alter the text size, versus only when the container is too small. Thanks.
Here's an example of what the result might look like:
You can use something like word-wrap or overflow-wrap or adding a variable with css(i.e: a font-size that fits your needs) and only change it when a media queries (that you established) returns true;
Media Queries explanation:
Let's say I established this variable
:root {
--font-size: 16px;
/* this is your regular font size that you will use in your entire document */
}
So in a given screen size like so:
#media screen and (device-width: 320px) and (orientation: portrait) {
:root {
--font-size: 12px;
}
}
You just change the value of the variable and it will change where ever you used that specific variable
If you don't know how this works you can use this css variables like this
.someClass {
font-size: var(--font-size); */ and that's it :) */
/* You can also make calculations like this */
font-size: calc(var(--font-size) - 40%);
}
Reference:
overflow-wrap: https://css-tricks.com/almanac/properties/o/overflow-wrap/
word-wrap: https://css-tricks.com/almanac/properties/w/word-break/
css variables: https://www.madebymike.com.au/writing/using-css-variables/
media queries: https://www.uxpin.com/studio/blog/media-queries-responsive-web-design/

Multiple dynamic background image urls based on screen size

I want to use two different background-image:url() values based on screen size. This is fairly simple to do if the urls are known ahead of time:
#media (max-width: 400px) {
.element {
background-image:url("/Images/1.png");
}
}
#media (min-width: 401px) {
.element {
background-image:url("/Images/2.png");
}
}
However, I do not know my image urls ahead of time - they are based on information from the user. I can set a single background-image:url() dynamically in the code behind like so:
string backgroundStyle = "background-image: url(\""+loginImagePath+"\"); ";
sBodyWrapper.Attributes.Add("style", backgroundStyle);
But I'm not sure how I might go about setting two different background images which alternatively show based on screen width. I could set the two background images on different elements and hide one of those elements, but I really would like this background image to be on a single body wrapping element.
Is there any way to set values inside of media queries? Can conditional css be applied on the element's style attribute?
You could add the conditional CSS via a style tag appended to the document:
var rules = '<style>
#media(max-width: 400px){
background-image:url("Images/1.png");
}
#media(min-width: 401px){
background-image:url("Images/2.png");
}
</style>';

HTML5 tables - I want only certain columns to adjust width when browser is resized

Title says it all, but here are more details. I have a table with 8 columns. 2 of these columns contain information that I wouldn't mind truncating if the table is resized, but the other columns contain information that should be shown in full. So I when the table is resized and made narrower, I would like all the narrowing to occur only in those two columns, not in the others.
Give the cells that you don't want to wrap a class (.nowrap), Then add the following CSS:
td.nowrap {
white-space: nowrap;
}
WORKING DEMO
I would use a media query to achieve this. Once the table element gets to a certain width, hide or shrink the columns. Something like this, you will have to tweak it and possibly add more. Also check out Twitter Bootstrap. You can easily achieve this using their framework.
#media (min-width: 1200px) {
#tableColumn {
display:block;
}
}
#media (min-width: 700px) {
#tableColumn {
display:none;
}
}

changing content depending on different media queries

This is the second attempt at this question as I have worked on this since I last asked so hopefully I'll make more sense this time.
I'm creating a responsive layout for my coming soon page. The main body header changes depending on the size of the browser and the device.
<h1><span class="main__header--changer">COMING SOON</span></h1>
... and the CSS
#media (max-width: 75em) {
h1:before {
content: "HOLD ONTO YOUR HATS";
}
.main__header--changer {
display: none;
}
}
#media (max-width: 64em) {
h1:before {
content: "NOT LONG TO GO";
}
.main__header--charger {
display: none;
}
}
... and so on and son on, the different variations of coming soon contains less letters as the size goes down, right down to 'nigh'.
The only thing my way of doing this means that screen readers wont read the heading because of the display:none. Is there a different way to hide the heading but not from screen readers but that the content is shown from the css?
Thanks
You can create a hidden effect by bumping the content way outside the screen display area using margins or the text-indent property. These methods aren't what I'd call 100% clean, but they at least keep your HTML markup tidy.
Check out this helpful thread that explains screen reader interactions with CSS-hidden elements.
I also assume that in the second reference in your CSS you mean --changer not --charger.
On a side note, if the statement: .main__header--changer {display: none;} is the same across all your media queries, you should consider just writing it once outside of any queries so it applies universally without duplication in your code.
Hope this has been helpful!