Use multiple conditions for CSS container queries - css

Important - this code only works on browsers with container queries enabled
How can I use multiple conditions at the same time for container queries? Using the syntax for #media queries doesn't seem to work.
In this example, the background changes to yellow based on the width and height of the element (resize it to see). But combining the conditions to make the background blue doesn't work.
.tile {
width: 100px;
height: 100px;
border: 1px solid black;
resize: both;
overflow: auto;
container-type: size;
container-name: tile;
}
.tile__inner {
width: 100%;
height: 100%;
}
#container tile (min-width: 100px) {
#container tile (min-height: 100px) {
.tile__inner {
background: yellow;
}
}
}
#container tile (min-width: 100px) and (min-height: 100px) {
.tile__inner {
background: blue !important;
}
}
<div class="tile">
<div class="tile__inner"></div>
</div>

The combined syntax is correct in your example, and works as expected in Chrome v105 as well as Safari Technology Preview v152. I'm seeing the blue background applied when both width and height are 100px or larger.
I would guess that you are using Safari TP v151 or earlier? There was a bug in Safari TP before v152 that required parenthesis around any combination/negation syntax. I expect this will work for you either by using parenthesis (which is also valid syntax):
#container tile ((min-width: 100px) and (min-height: 100px)) {
.tile__inner {
background: blue !important;
}
}
Or by upgrading Safari to the latest TP.
codepen: https://codepen.io/miriamsuzanne/pen/dyeYoBr/30d17f519afe57c5d88f2c281dcbb5e2

Related

Why do I need to add an extra pixel for a max height when using media queries?

I have this here code running on 3840x2160 at 225% zoom
#d1 {
height: 400px;
width: 275px;
background-color: hotpink;
}
#media (max-height: 850px) {
#d1 {
height: 400px;
width: 275px;
background-color: green;
}
}
#media (max-height: 818px) {
#d1 {
height: 400px;
width: 275px;
background-color: purple;
}
}
<div id="d1"></div>
When I don't have the bookmark bar open, the d1 will have background color of hotpink, but when I check the window height it shows 850px, when I show the bookmark bar, the window height is 818px and then d1 background color goes to green.
Now if I add 1 more pixel to the max height
#media (max-height: 851px) {
#d1 {
height: 400px;
width: 275px;
background-color: green;
}
}
#media (max-height: 819px) {
#d1 {
height: 400px;
width: 275px;
background-color: purple;
}
}
Then when I hide the bookmark bar, I get the background color of green and when I show the bookmark bar, the background color goes to purple.
So my question is, why do I need to add an extra pixel to the max height to get this to work properly?
Browsers tend to... not use whole numbers.
What's probably happening is even though dev tools SAYS your window is 850px tall, it's probably 850.25px tall.
As such, since 850.25px is bigger than 850px, the media query doesn't trigger.
(Keep in mind that your entire viewport is being divided by 225% since you're zoomed in, so it's very unlikely that the math will come out to a whole number...)

How Do I Properly Make An Image Respond To A Browser's Adjustment?

I have a simple question: How do I make an image properly respond to the viewport?
I have a 400 pixel (400px) wide and tall image, and I'd like it to become only 90% of the viewport width (90vw) when the browser is resized, so here is my current code:
img {
width: 400px;
height: 400px;
}
#media screen and (max-width: 400px) {
img {
width: 90vw;
height: 90vh;
}
}
But the problem is that the image doesn't adjust at all with this current code.
When I put max-width in place of width only the width of the image adjusts while the height does not leaving me with an elliptical and distorted image.
Is there an easy fix to my problem?
Setting both height and width in CSS for an <img> is prone to distorting it. If you don't want that to happen, you should just specify one dimension and set the other to auto. Considering your image is, in fact, 400px × 400px, here's what you should use:
#myImg {
width: 400px;
height: auto;
}
#media (max-width: 440px) {
#myImg {
width: 90vw;
}
}
/* optional, for centering */
#myImg {
display: block;
margin: 0 auto;
}
<img src="http://via.placeholder.com/400x400" id="myImg">
Play with it here. Note I used 440px so there wouldn't be a jump from 400px to 360px when crossing over the 400px device width limit. You can, of course, use 400px if that's what you want.
Try object fit.
img {
width: 400px;
height: 400px;
object-fit: cover;
}
#media screen and (max-width: 400px) {
img {
width: 90vw;
height: 90vh;
}
}
Or for better browser compatibility you can also use a background image instead.
For that you'd need to set two #media queries, one for horizontal, and one for vertical adjustment, both set to 400px. With the horizontal one, you only use the width, and with the vertical one, only the height:
body {margin: 0}
img {
display: block; /* removes bottom margin/whitespace */
}
#media (max-width: 400px) {
img {width: 90%}
}
#media (max-height: 400px) {
img {height: 90vh}
}
<img src="http://placehold.it/400x400" alt="">

Position: absolute behaving differently in safari

I am building a responsive website ( http://dev.searsdavies.co.uk/quadrant-new/ )
With a layout that requires a set of buttons to sit in the dead centre of the screen for portrait tablets, this layout is triggered at a screen width of 768px and stays in place down to 414px. The buttons are position:absolute on top of all the other content as they need to snap to the bottom on the larger and smaller versions of the site.
The boxes behave perfectly in Chrome and Firefox but safari positions them too high up the page.
Full site is above, here is the relevant CSS
.row.footer {
bottom: 49%;
transform: translate(0, 50%);
position: absolute;
padding: 0 50px;
}
.row.full-width {
width: 100%;
margin-left: auto;
margin-right: auto;
max-width: 100%;
}
There is also a conditional query that stops the layout becoming too shallow on landscape phones and similar devices:
#media screen and (max-height: 800px) and (max-width:768px) and (min-width:415px) {
.row.footer {
top:352px ;
bottom:auto ;
transform:none
}
}
.side-img {
height: 50vh;
min-height: 400px;
background-size: cover;
position: relative;
}
.main-content {
height: 50vh;
min-height: 400px;
}
A few things here.
Firstly, prefix your properties; you are using transform but you are not prefixing; they will not work in Safari.
webkit-transform: translate(x,x);
Secondly, you have this in your #media query - max-height: 800px. That means do this stuff when the browser is **less than** 800px in height - demo.
Is that really what you want to say for a #media rule targeting a portrait tablet (an iPad for example, has is 768 widthby 1024 height)?
To fix your issues:
1) prefix your transforms
2) fix your #media rules
3) remove the bottom: auto rule
4) remove/adjust the bottom: 49% rule

Floating thumbnails with :nth-child CSS skipping a column

I have a gallery of floated thumbnails which I'd like flush against both sides of the containing div, but with whitespace between them.
JSfiddle of the desired behaviour.
Relevant CSS:
.thumb {
display: block;
float: left;
width: calc((100% - 72px)/3);
margin-top: 18px;
margin-right: 36px;
transition: opacity 750ms ease-in-out;
}
#media screen and (max-width: 1553px) {
.thumb:nth-child(3n+3) {
margin-right: 0;
}
}
#media screen and (min-width: 1554px) and (max-width: 2059px) {
.thumb {
width: calc((100% - 108px)/4);
}
.thumb:nth-child(4n+4) {
margin-right: 0;
}
}
#media screen and (min-width: 2060px) {
.thumb {
width: calc((100% - 144px)/5);
}
.thumb:nth-child(5n+5) {
margin-right: 0;
}
}
In Chrome and Firefox on OSX, at some resolutions (such as 1024px), the thirteenth thumbnail centres itself in the container and puts all the :nth-child styles out of whack, breaking the layout below. I've changed the order of the thumbnails, but it's always the thirteenth one. Thinking it may have something to do with fractions of pixels resulting from the calc() division, I subtracted 1px from the width of the thumbnails, with no luck either.
I don't see any relevant difference between what I've done in the JSfiddle and the WIP site. What am I doing wrong?
Well it's not your real answer, but i think you are getting hard to your self!
There are very cool and easy ways to create what you want.
I recommend you to read more about Foundation Block Grid and FlexBox.
don't try to reinvent the wheel.

Using em for responsive styles on things other than type

Sometimes I wish I could just change a single variable in a media query and
HTML:
<div id="wrap">
<div class="child1"></div>
<div class="child2"></div>
</div>
LESS (does not work):
#base: 1000px;
#media all and (max-width: 768px) {
#base: 600px;
}
.child1 {
// 500px normally, 300px on small screens
height: 0.5 * #base;
}
.child2 {
// 250px normally, 150px on small screens
height: 0.25 * #base;
}
That of course doesn't work because at compilation time, #base is set and applied to all classes. However, I came across this dirty workaround:
LESS:
#wrap
{
font-size: 1000px;
#media all and (max-width: 768px) {
font-size: 600px;
}
.child1 {
// 500px normally, 300px on small screens
height: 0.5em;
}
.child2 {
// 250px normally, 150px on small screens
height: 0.25em;
}
}
Assuming I don't actually have any text in my elements (or text only occurs in leaf nodes and sets their font-size explicitly), are there any serious downsides of using this approach?
I cannot attest for certain, but the proposed em method just seems too hacky for my taste (and it does not make the heights of the elements easily determined by the coder). I would recommend using the media queries as they are intended to be used, and just build a mixin to get the values, like so:
LESS
#base: 1000px;
#smallBase: 600px;
.childHeights(#base) {
// 500px normally, 300px on small screens
.child1 {
height: 0.5 * #base;
}
// 250px normally, 150px on small screens
.child2 {
height: 0.25 * #base;
}
}
#media all and (max-width: 768px) {
.childHeights(#smallBase);
}
.childHeights(#base);
CSS Output
#media all and (max-width: 768px) {
.child1 {
height: 300px;
}
.child2 {
height: 150px;
}
}
.child1 {
height: 500px;
}
.child2 {
height: 250px;
}

Resources