AI websites that design themselves

Join the evolution

Become a founding member

Conditionals

Responsive to any prop w/o Media Queries

The age of “Responsive Web Design” is upon us and its mandate for designs that elegantly adapt to the user’s viewing context has made web dev “hard, really hard, actually” as Mr Jeff Croft lamented. Conceptualizing Responsive layouts is difficult enough, but implementing such layouts with CSS Media Queries is an awkward affair because, as Ian Taylor illuminated, Media Queries are a hack.

Element Queries

Media Queries allow layouts to adapt to the size of the viewport, but if you want to adapt to anything else, tough luck. W3C members have received an onslaught of requests for “Element Queries” - because web designers are desperate to achieve higher levels of adaptiveness with their layouts. The idea with Element Queries is simple - individual elements can be responsive to their own size, which would allow for richer designs & more modular Style Sheets. W3C have started a discussion about element queries but at this point they still don’t have official endorsement of element queries.

Yet, even with the hypothetical Element Query, elements could only be adaptive to their size. Why not allow elements to be adaptive to any property like col-count or even to a custom variable?

Arbitrary Property Conditionals

Which brings us to @if and @else directives. Think of them as a more expressive replacement for Media Queries and the much desired Element Query, that allow CSS rules to be adaptive to any arbitrary property or custom constraint variable. Live example.

Instead of continuing the tradition of the Query types (min-width, max-width, min-height & max-height) for every available CSS property, @if @else directives use the conditional operators: <, <=, >, >=, !=, ==, or, and and.

For example, if we want a set of CSS rules to kick-in when the viewport is narrower than 960px:

/* GSS: */
@if ::window[width] < 960 {
  /* ... */
}

/* Old-school Media Queries: */
@media screen and (max-width: 960px) {
  /* ... */
}

But, any property can be used within an @if, @else conditional. So, if you want a layout to be responsive to a section’s width:

section {
  article {
    @if ^[width] <= 400 {
      width: == ^[width];
      height: == ^[height] / 2;
    }
    @else  {
      width: == ^[width] / 2;
      height: == ^[height];
    }
  }
}

When the width of the section element goes below 400px, the article elements will be constrained by the @if block, otherwise by the @else block.

Constraint evaluation within conditionals

In order to determine if a conditional holds, GSS needs to evaluate every constraint outside of the conditional before evaluating if it is met. This includes constraints appearing after the conditional’s declaration.

As explained in the CCSS guide, the constraint declaration order can affect the resulting solution.

In the following example, if the conditional is true, the constraint within it will be added to the solver after the outer constraints. This causes the constraint within the conditional to overcome the constraints of equal strength when the conditional evaluates as true.

#elm[width] == ::window[width];

@if elm[width] < 400 {
  #elm[height] == 300;
}

#elm[height] == 500;

In this example, if the width of the screen is smaller than 400px, the height of the element will be constrained to 300px even though there’s a height constraint defined after the condition.

Condition looping

As described in the CCSS guide, constraints are two-way. This should be carefully considered when using conditionals. Although GSS has been designed to detect and prevent cases when looping could occur, complex nesting of conditionals can still cause infinite loops.

For example, since the conditional below changes a variable that is being checked, it would appear that it will lead to an infinite loop. However, the underlying constraint solver in GSS can determine a solution that satisfies constraints without looping.

#elm[width] == 800;
.someElm[width] == #elm[width];

@if #elm[width] <= 400 {
  .someElm[width] == 600;
}

With only CCSS constraints at your disposal, constraining common layout scenarios quickly becomes tedious. Read our VFL guide to learn how to more efficiently constraint your layout.

privacy policy