Css media

Responsive CSS templates without media queries

Let me start by saying that despite the title this article is not about removing media queries or denigrating media queries in any way. Media queries are incredibly useful and I use them all the time for all kinds of things. However, they don’t solve all of our responsive design issues.

It is often desirable to make changes to an item layout based on the dimensions of its container, rather than the viewport. To solve this problem, the concept of element queries was born. However, item queries are not really a problem. thing again, and Mat Marquis demonstrated some problems with the concept and reformulated them as container queries.
But this is not a thing neither, unfortunately.

I hope they will someday be, but in the meantime I have presented here some tips and techniques that you can use to solve some issues that container queries will one day resolve.

Flexbox with flex-wrap

Flex-wrap can solve a multitude of problems when it comes to meeting container dimensions. For example, it is common to want two items to appear side by side if there is enough space, but to stack them on top of each other if there is not. In the following demo, we can see this behavior in action:

See the pen Responsive module – flexbox by SitePoint (@PointSite) to Code pen.

No fancy stuff here, just flexbox with flex-wrap but it works a treat. Flexbox can be used for more than just creating two columns, of course, but I’ve kept it simple for this demo. The essential parts of this technique are simply:

<div class="container">
  <div class="img">...div>
  <div class="content">...div>
div>

...
.container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

.container .content,
.container .img {
  flex: 1 0 12em;
  
}

Comprehension flex-grow, flex-shrink and flex-basis is an important part of getting it right; I find this Zoe Gillenwater flexbox tip really useful for understanding the relationship between these properties.

“The Fab Four technique”

The use of width, min-width, max-width and calc to create a tie-off-based width switch – dubbed “the Fab Four technique” – was the original idea of Remi Parmentier. Originally created to help with responsive emails, it can easily be used for normal web pages and really opened up new possibilities in the creation of self-adaptive modules as shown Thierry. For example,

{
  min-width: 50%;
  width: calc((25em - 100%) * 1000);
  max-width: 100%;
  
}

It works because when width is a percentage, it is a percentage of the width of the element’s container. the calc The function then compares that value to the desired breakpoint, then generates a very large positive number (if the width is less than the breakpoint), or a very large negative number (if the width is greater than the breakpoint ), or zero if there is an exact match. A large positive width is capped by max-width and a negative or zero large width is set to the value of min-width.

So in the example above, we set a breakpoint of 25em. This resolves to 400px if the font size is 16px. If the container is 400px or higher (in other words equal to or greater than the breakpoint), the width resolves to 0 or a large negative number:
(400 - 400 = 0) * 1000 = 0 Where (400 - 401 = -1) * 1000 = -1000

With values ​​like these, min-width so starts the resulting width of the element in the example above will be 50%. However, if the container is 399px or below (in other words smaller as the breakpoint), the width resolves to a large positive number:
(400 - 399 = 1) * 1000 = 1000

In this case max-width comes into play and the resulting width is 100%. The following diagram should help visualize this process:

Diagram showing the Fab Four technique

The following four demos all use this technique in different ways to change the width of an element in response to the width of its container.

Floating image – full width / partial width

In this demo, I used the “Fab Four Technique” combined with float to toggle an image between full and half-width depending on the container width:

See the pen Reactive module – floating by SitePoint (@PointSite) to Code pen.

Similar to the flexbox In the example above, this technique allows the elements to switch between a stacked layout on small widths and a floating / wrapped layout if there is enough space.

Floating Image – Visible / Hidden

Adapted from the previous technique, I reversed the result of the calculation and deleted the min-width statement to create an on / off switch. This is useful for hiding decorative items in smaller containers where they can take up valuable space:

See the pen Responsive module – floating / hidden by SitePoint (@PointSite) to Code pen.

And for the sake of clarity:

{
  
  
  width: calc((25em - 100%) * -1000);
  max-width: 100%;
  
}

Text and image – overlaid / stacked

See the pen Responsive module – stacked / stacked by SitePoint (@PointSite) to Code pen.

In the same vein as the previous techniques, I used a div to pull the text over the image, but when the image is too small and would otherwise be obscured by the text, the text snaps below instead. This part of the technique is a bit complicated, so I will try to clarify it.

.pull {
  
  margin-bottom: -10em;
}

Here, the negative margin pulls the next content up so that it overlaps the image. However, we need to disable this option when the container width crosses the breakpoint, but since there is no min/max-margin property, we cannot use the “Fab Four Technique” here to achieve this.

Luckily, however, if the padding is given a percentage, it is a percentage of the width of the container, and padding-top and -bottom will affect the size of an element. With this knowledge we can use calc to create a padding-bottom value that toggles between zero or “really large” depending on the width of the container:

padding-bottom: calc((30em - 100%) * 1000);

We cannot apply this to .pull div directly because there is no min/max-padding property to restrict these values; the solution is to put the padding switch on a pseudo-element to force the change of height and use max-height on the .pull element to restrict the height to the same value as the negative margin so that we effectively override that margin.

.pull {
  
  margin-bottom: -10em;
  
  max-height: 10em;
  
  overflow: hidden;
}

.pull::before {
  content: "";
  display: block;
  padding-bottom: calc((30em - 100%) * 1000);
  
}

The overlay gradient effect is achieved by applying an “on / off” switch as previously described to a pseudo element to which the background gradient has been applied:

.image::after {
  content: "";
  display: block;
  position: absolute;
  left: 0;
  top: 0;

  
  background-image: linear-gradient(to bottom, rgba(0,20,30,0) 0%,rgba(0,20,30,0) 50%,rgba(0,20,30,1) 100%);

  
  height: 100.5%;
  
  width: calc((30em - 100%) * -1000);
  
  max-width: 100%;
}

Truncation list

The final technique I developed was inspired by a version of Priority Plus template on CSS tips. While not that fancy, this one doesn’t require any JavaScript:

See the pen Truncation list by SitePoint (@PointSite) to Code pen.

Again, this uses the “Fab Four technique”, but this time based on the height of the container rather than the width.

<div class="outer">
  <div class="inner">
    <div class="item">...div>
    ...
    <div class="control">...div>
  div>
div>
...
.outer {
  height: 2.25em;
  overflow: hidden;
}

.outer:target {
  height: auto;
}

The outer container has a fixed height and hides any overflow unless the element is :target-ed.

.inner {
  display: flex;
  flex-wrap: wrap;
}

The inner container is a flexible container with flex-wrap activated, it will therefore increase in height as the elements roll up, but the elements below the first row will be masked by the .outer the container overflow:hidden, creating the truncation effect.

.control {
  height: calc((2.25em - 100%) * -1000);
  max-height: 2.25em;
}

:target .control--open {
  display: none;
}

:target .control--close {
  display: block;
}

The ‘more less‘controls are only made visible if the container height exceeds the breakpoint (which is the same as the height of the main links), and the :target The state determines which control is visible.

Align text intelligently in CSS

See the pen Responsive text alignment by SitePoint (@PointSite) to Code pen.

Aligning the text in the center or left depending on the space available in the container relative to the length of the text is a really useful thing to be able to do. This technique was created by Vijay sharma makes this very easy.

Bonus: Flex-grow 9999 Hack

A good tip from Joren Van Hee that fits well in this collection is the flex-grow hack 9999.

Speech by Vasilis van Gemert Listen, no media queries gave me the impetus to study the design with no response to media queries, which led me to write this article. His talk is worth watching and includes other ideas which, while very useful, did not quite fit into the theme of what I have presented here.

Conclusion

There are a lot of things that cannot be done without element / container requests. Things like color values, font size and line height, box borders and shadows, margins and fills – the list goes on. Adjusting all of these things in response to the state of a parent container should be possible with item / container requests, but, alas, there doesn’t seem to be any sign of this becoming a reality any time soon. However, I hope that in the meantime some of what I have presented here will be of use to you.

If you want to know what design with element queries is could be able be like, Writing item queries today using EQCSS will get you started.

If you’re interested in learning more about element / container requests, here are some helpful resources: