Tuesday, June 25, 2024
HomeCSSConditional CSS

Conditional CSS


I like to consider CSS as a conditional design language. Through the years, CSS was often called a option to type net pages. Now, nonetheless, CSS has developed quite a bit to the purpose you possibly can see conditional guidelines. The attention-grabbing bit is that these CSS guidelines aren’t direct (i.e: there’s nonetheless no if/else in CSS), however the way in which options in CSS work is conditional.

Design instruments like Figma, Sketch, and Adobe XD made an enormous enchancment for us designers, however they nonetheless lack numerous the flexibleness that CSS has.

On this article, I’ll go over a couple of CSS options that we use daily, and present you ways conditional they’re. Along with that, I’ll evaluate a couple of examples the place CSS is far more highly effective than design instruments.

{{TOC}}

What’s conditional CSS?

In easy phrases, it’s about design that has sure situations. When a number of situations are met, the design is topic to alter because of that.

For instance, including a brand new part to a design should push the opposite parts beneath it. Within the following determine, we’ve a stack of things on the left. When including a brand new one, the opposite objects under it should transfer down.

Logically, that sounds anticipated and regular. In design instruments, we acquired this a couple of years in the past. In Figma, we’ve “Auto Format” options that do the above. On the net, we’ve had that from day 1, even with out CSS in any respect.

Conditional CSS

You is likely to be excited about what the heck conditional CSS is. Is that even a factor? No, there hasn’t been a direct “if” assertion in CSS.

The principle factor to differentiate is that some CSS properties work in particular situations or eventualities. For instance, when utilizing the CSS :emtpy selector to verify if a component is empty or not, it’s a conditional pseudo selector.

.alert p:empty {
  show: none;
}

If I wish to clarify the above to my 2 years previous daughter, I’ll do it like this:

If there’s nothing right here, it’s going to disappear.

Did you discover the if assertion right here? That is conditional design not directly. Within the following part, I’m going to discover a couple of CSS options which work equally to an if/else assertion.

The purpose? To have a stronger concept and expectation concerning the CSS you wrote. I imply, it is possible for you to to identify conditional CSS by simply wanting on the CSS for a element, a piece, or a web page.

CSS versus Figma

Why Figma? Nicely, I take into account it as the usual for UX design as of late, I believed it’s a good suggestion to do my comparability based mostly on it. I wish to share a easy instance. There may be checklist of tags which can be displayed horizontally.

Once you assume deeply about it, you’ll spot some main variations. For instance, the CSS model:

  • Can wrap into a brand new strains if there isn’t a sufficient house.
  • Works with each LTR and RTL instructions.
  • The hole might be used for rows when the objects wrap.

Figma doesn’t have any of the above.

In CSS, there are three conditional guidelines occurring:

  • If flex-wrap is about to wrap, then the objects can wrap when there isn’t a out there house.
  • When the objects wrap into a brand new line, the hole will work for the horizontal and vertical areas.
  • If the web page route is RTL (right-to-left), the objects will swap their order (e.g: design would be the first one from the proper).

This is only one instance, and I can write a e book like that. Let’s discover a couple of circumstances the place CSS might be conditional.

Conditional CSS examples

Media question

We are able to’t speak about conditional CSS with out mentioning CSS media queries. The CSS spec is known as CSS Conditional Guidelines Module. To be sincere, that is the primary time that I study that title.

After I did my analysis about who asks or mentions “Conditional CSS”, I discovered multiple time that media queries are the closest factor to an “if” assertion in CSS.

.part {
  show: flex;
  flex-direction: column;
}

@media (min-width: 700px) {
  .part {
    flex-direction: row;
  }
}

If the viewport width is 700px or bigger, change the flex-direction of .part to row. That’s express if assertion, isn’t it?

The identical factor can apply to media queries like @media (hover: hover). Within the following CSS, the hover type might be utilized provided that the consumer is utilizing a mouse or a trackpad.

@media (hover: hover) {
  .card:hover {
    
  }
}

Measurement container question

With container queries, we are able to verify if the mother or father of a element has a particular dimension and elegance the kid element accordingly.

.card-wrapper {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card {
    show: flex;
    align-items: middle;
  }
}

I’ve written about container queries a number of occasions, and have a spot the place I share demos about it.

Fashion container question

On the time of writing this text, that is behind a flag in Chrome Canary and is meant to ship in Chrome steady.

With a mode question, we are able to verify if a element is positioned inside a wrapper that has a particular CSS variable and if sure, we type it accordingly.

Within the following determine, we’ve an article physique that’s coming from a CMS. We now have a default type for the determine and one other type that appears featured.

To implement that with type queries, we are able to type the default one, after which verify if the determine has a particular CSS variable to permit the customized styling.

determine {
  container-name: determine;
  --featured: true;
}


@container determine type(--featured: true) {
  img {
    
  }

  figcaption {
    
  }
}

And if --featured: true isn’t there, we’ll default to the bottom determine design. We are able to use the not key phrase to verify when the determine doesn’t have that CSS variable.


@container determine not type(--featured: true) {
  figcaption {
    
  }
}

That’s an if assertion, however it’s implicit.

One other instance is having a element styled otherwise based mostly on its mother or father. Contemplate the next determine:

The cardboard type can swap to darkish if it’s positioned inside a container that has the --theme: darkish CSS variable.

.special-wrapper {
  --theme: darkish;
  container-name: stats;
}

@container stats type(--theme: darkish) {
  .stat {
    
  }
}

If we learn the above, it appears like:

If the container stats have the variable --theme: darkish, add the next CSS.

CSS @helps

The @helps characteristic lets us check if a sure CSS characteristic is supported in a browser or not.

@helps (aspect-ratio: 1) {
  .card-thumb {
    aspect-ratio: 1;
  }
}

We are able to additionally check for the help of a selector, like :has.

@helps selector(:has(p)) {
  .card-thumb {
    aspect-ratio: 1;
  }
}

Flexbox wrapping

In response to MDN:

The flex-wrap CSS property units whether or not flex objects are compelled onto one line or can wrap onto a number of strains. If wrapping is allowed, it units the route in that strains are stacked.

The flex-wrap property permits flex objects to wrap into a brand new line in case there’s not sufficient house out there.

Contemplate the next instance. We now have a card that accommodates a title and a hyperlink. When the house is small, every little one merchandise ought to wrap into a brand new line.

.card {
  show: flex;
  flex-wrap: wrap;
  align-items: middle;
}

.card__title {
  margin-right: 12px;
}

That appears like a conditional factor to me. If no out there house, wrap into a brand new line(s).

When every flex merchandise wraps right into a line, how do I handle the spacing between the flex objects, you requested? At present, there’s a margin-right on the heading, and when they’re stacked, that ought to be changed by margin-bottom. The issue is we don’t know when the objects will wrap as a result of it depends upon the content material.

The great factor is that the spacing might be conditional with the hole property. When they’re in the identical line, the spacing is horizontal, and with a number of, the spacing is vertical.

.card {
  show: flex;
  flex-wrap: wrap;
  align-items: middle;
  hole: 1rem;
}

That is certainly one of my favourite flexbox options. Here’s a visible of how hole switches the spacing.

By the way in which, I take into account flex-wrap as defensive CSS. I nearly add it to any flex container to keep away from any sudden points.

The flex property

Much more, the flex property can work conditionally, too. Contemplating the next instance. I added flex: 1 to the cardboard title to make it fill the out there house.

.card__title {
  flex-grow: 1;
}

That works nice, however when the width of the cardboard is just too small, the cardboard title will wrap into a brand new line.

Nothing too dangerous, however can we do higher? For instance, I wish to inform the title: “Hey, in case your width is lower than X, then wrap into a brand new line”. We are able to do this by setting the flex-basis property.

Within the following CSS, I set the utmost width of the title to 190px. If it’s lower than that, it’s going to wrap into a brand new line.

.card__title {
  flex-grow: 1;
  flex-basis: 190px;
}

To study extra concerning the flex property in CSS, I wrote an in depth article on that.

Take issues additional, and clarify about including flex-grow, string.. and so forth alongside the way in which.

The :has selector

For me, that is the closest factor to an “if” assertion in CSS proper now. It really works in a approach that mimics an if/else assertion.

Altering a card type

On this instance, we have to have two completely different kinds, relying on if the cardboard has a picture or not.

If the cardboard has a picture:

.card:has(.card__image) {
  show: flex;
  align-items: middle;
}

And if it doesn’t have a picture:

.card:not(:has(.card__image)) {
  border-top: 3px stable #7c93e9;
}

That’s an if assertion, and I strongly assume so. Sorry, I acquired too excited.

Hiding or displaying type objects conditionally

In kinds, it’s widespread to have an enter area or a bunch of inputs hidden by default, and it will likely be proven as soon as the consumer prompts an choice from a <choose> menu.

With CSS :has, we are able to verify if the different choice is chosen and if sure, present the enter area.

.other-field {
  show: none;
}

type:has(choice[value="other"]:checked) .other-field {
  show: block;
}

Alerts

When there’s an alert message on a web page, like for instance a significant warning of one thing flawed within the system, we’d have to make it much more apparent.

On this instance, we’ve an alert inside the web page, and with CSS :has, we are able to verify if the dashboard has an alert, and if sure, type accordingly.

.most important:has(.alert) .header {
  border-top: 2px stable purple;
  background-color: #fff4f4;
}

So helpful.

Change grid columns based mostly on the variety of objects

Have you ever ever wanted to show and alter the width of a column in a grid based mostly on the variety of little one objects?

CSS :has can do this, conditionally.

.wrapper {
  --item-size: 200px;
  show: grid;
  grid-template-columns: repeat(
    auto-fill,
    minmax(var(--item-size), 1fr)
  );
  hole: 1rem;
}

.wrapper:has(.merchandise:nth-last-child(n + 5)) {
  --item-size: 120px;
}

Within the instance, it says that if the .wrapper has 5 objects, then the --item-size variable will change to 120px.

To study extra concerning the CSS :has selector, I wrote an article on it with loads of examples.

CSS grid minmax() perform

The way in which minmax() works in CSS grid is conditional. After we use auto-fit key phrase, we’re telling the browser: “if there’s an out there house, make the grid objects fill the house”.

The adjoining sibling combinator

That combinator matches the second ingredient that comes immediately after a component.

Within the following instance, if an <h3> ingredient is adopted by a <p>, the <p> will get customized kinds.

h3 + p {
  margin-top: 8px;
}

The <p> prime margin has been modified conditionally.

The :focus-within pseudo-class

One other attention-grabbing characteristic in CSS is :focus-within. Say that you simply wish to verify whether or not an enter is targeted, and if sure, add a border to its mother or father.

Contemplate the next instance:

We now have a search element. When the enter is targeted, the entire wrapper ought to have a top level view. With :focus-within, we are able to verify if the enter is targeted, and elegance accordingly.

.hero-form:focus-within {
  box-shadow: 0 0 0 5px rgb(28 147 218 / 35%);
}

The :not selector

This pseudo-class excludes parts that don’t match a sure selector. For instance, it may be helpful to verify if an merchandise is the final one, and if sure, take away the border.

.merchandise:not(:last-child) {
  border-bottom: 1px stable lightgrey;
}

Conditional border-radius

Some time in the past, I wrote about how I noticed an attention-grabbing conditional method so as to add border-radius for a card on the Fb web site.

The thought is that when the cardboard is the same as or bigger than the viewport, the radius ought to be 8px, if not, then it’s 0px.

.card {
  border-radius: max(
    0px,
    min(8px, calc((100vw - 4px - 100%) * 9999))
  );
}

You may learn the article right here.

Conditional line separator

One other attention-grabbing use case the place CSS works conditionally is having a line separator that switches its route and dimension based mostly on whether or not the objects are wrapped or not.

Within the following determine, discover the road separator between the 2 sections.

I would like that line to change horizontally when the flex objects are stacked. Through the use of flex-wrap and clamp comparability, we are able to obtain that.

.part {
  --: 400px;
  show: flex;
  flex-wrap: wrap;
  hole: 1rem;
}

.part:earlier than {
  content material: "";
  border: 2px stable lightgrey;
  width: clamp(0px, (var(--breakpoint) - 100%) * 999, 100%);
}

This has been written on my weblog, and the clamp() answer is a suggestion by Temani Afif.

Intrinsic sizing: fit-content

The fit-content key phrase is a mixture of min-content and max-content. I do know, it’s not clear. Let’s check out the next flowchart.

If we’ve a component with width: fit-content, it’s going to work conditionally as per the flowchart above.

h2 {
  width: fit-content;
}

Here’s a video of what’s occurring on resize:

I wrote about intrinsic sizing on my weblog in the event you’re .

Comparability features

CSS comparability features are min(), max(), and clamp(). One explicit instance that feels conditional for me is one thing that I stumbled upon in a latest article I wrote.

The thought is I’ve two completely different containers, one of many article header (title and date), and a container for the principle content material plus the apart.

I wish to align the sting of the header content material with the physique content material.

On cellular, I would like the padding from the left to be 1rem, however on bigger viewports, it will likely be dynamic as per the viewport width.

To try this, I can use the max() perform to decide on one of many two values (1rem or dynamic worth) conditionally.

.prose {
  padding-left: max(1rem, (100vw - var(--wrapper-width)) / 2);
}

You may study extra about this method in my article Contained in the thoughts of a frontend developer: Article format.

Pseudo-classes

There are numerous pseudo-classes in CSS, however the ones that got here to thoughts are :centered and :checked.

enter:checked + label {
  
}

enter:focus {
  define: 2px stable #222;
}

If the enter is checked, add these kinds to the <label>. If the enter is targeted..and so forth.

However.. CSS isn’t a programming language!

I do know, thanks for letting me know. That is argument that I hear quite a bit. I personally don’t have a powerful opinion on that, however CSS is conditional in some ways.

The truth is, a lot of the examples above can’t be carried out in Javascript with out utilizing a conditional assertion.

Conclusion

I loved writing this text as a result of it jogged my memory of why I like utilizing CSS. To me, CSS is sort of a superpower as a result of it permits me to make so many design choices by way of its conditional options. Working with design instruments can generally really feel limiting as a result of I really feel like I’m constrained inside sure partitions. I believe that the power to create conditional guidelines with CSS is what units it aside and makes it highly effective for net design.

That doesn’t imply that I design within the browser. I take into account design instruments as an open canvas to attempt to experiment with design concepts, and constructing polished UI merchandise.

I like to make use of the browser to tweak designs, as a substitute of designing them utterly.

And also you, what do you assume? I’d love to listen to your ideas and concepts.

Thanks for studying.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments