Friday, May 17, 2024
HomeCSSConditional CSS - Ahmad Shadeed

Conditional CSS – Ahmad Shadeed


I like to consider CSS as a conditional design language. Over time, CSS was generally known as a option to type internet pages. Now, nevertheless, CSS has advanced loads to the purpose you possibly can see conditional guidelines. The fascinating bit is that these CSS guidelines aren’t direct (i.e: there may be 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 lots of the flexibleness that CSS has.

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

What’s conditional CSS?

In easy phrases, it’s about design that has sure circumstances. When a number of circumstances 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, now we have a stack of things on the left. When including a brand new one, the opposite gadgets under it should transfer down.

Logically, that sounds anticipated and regular. In design instruments, we obtained this a number of years in the past. In Figma, now we have “Auto Format” options that do the above. On the internet, now we have had that from day 1, even with out CSS in any respect.

Conditional CSS

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

The primary factor to tell apart is that some CSS properties work in particular circumstances or situations. For instance, when utilizing the CSS :emtpy selector to examine if a component is empty or not, it’s a conditional pseudo selector.

.alert p:empty {
  show: none;
}

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

If there may be nothing right here, it’ll 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 number of CSS options which work equally to an if/else assertion.

The aim? To have a stronger thought and expectation in regards to the CSS you wrote. I imply, it is possible for you to to identify conditional CSS by simply wanting on the CSS for a part, a piece, or a web page.

CSS versus Figma

Why Figma? Effectively, I contemplate it as the usual for UX design nowadays, I assumed it’s a good suggestion to do my comparability based mostly on it. I need to share a easy instance. There may be checklist of tags which might be displayed horizontally.

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

  • Can wrap into a brand new strains if there is no such thing as a sufficient house.
  • Works with each LTR and RTL instructions.
  • The hole will likely be used for rows when the gadgets 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 gadgets can wrap when there is no such thing as a out there house.
  • When the gadgets 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 gadgets will swap their order (e.g: design would be the first one from the best).

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

Conditional CSS examples

Media question

We will’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 find out about that title.

Once I did my analysis about who asks or mentions “Conditional CSS”, I discovered a couple of 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 specific if assertion, isn’t it?

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

@media (hover: hover) {
  .card:hover {
    /* Add hover types.. */
  }
}

Dimension container question

With container queries, we are able to examine if the mum or dad of a part has a selected dimension and magnificence the kid part 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.

Model container question

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

With a method question, we are able to examine if a part is positioned inside a wrapper that has a selected CSS variable and if sure, we type it accordingly.

Within the following determine, now we have an article physique that’s coming from a CMS. We have now 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 examine if the determine has a particular CSS variable to permit the customized styling.

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

/* Featured determine type. */
@container determine type(--featured: true) {
  img {
    /* Customized styling */
  }

  figcaption {
    /* Customized styling */
  }
}

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

/* Default determine type. */
@container determine not type(--featured: true) {
  figcaption {
    /* Customized styling */
  }
}

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

One other instance is having a part styled otherwise based mostly on its mum or dad. Think about 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 {
    /* Add the darkish types. */
  }
}

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 will additionally check for the help of a selector, like :has.

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

Flexbox wrapping

In accordance with MDN:

The flex-wrap CSS property units whether or not flex gadgets are pressured 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 gadgets to wrap into a brand new line in case there may be not sufficient house out there.

Think about the next instance. We have now a card that comprises 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 seems 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 gadgets, you requested? At the moment, 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 gadgets will wrap as a result of it relies on the content material.

The great factor is that the spacing may 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 considered one of my favourite flexbox options. Here’s a visible of how hole switches the spacing.

By the way in which, I contemplate flex-wrap as defensive CSS. I nearly add it to any flex container to keep away from any surprising 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 effective, however when the width of the cardboard is just too small, the cardboard title will wrap into a brand new line.

Nothing too unhealthy, however can we do higher? For instance, I need to inform the title: “Hey, in case your width is lower than X, then wrap into a brand new line”. We will 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’ll wrap into a brand new line.

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

To study extra in regards to 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 types, 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 suppose so. Sorry, I obtained too excited.

Hiding or displaying kind gadgets conditionally

In types, it’s widespread to have an enter discipline or a gaggle of inputs hidden by default, and will probably be proven as soon as the person prompts an choice from a <choose> menu.

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

.other-field {
  show: none;
}

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

Alerts

When there may be 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, now we have an alert throughout the web page, and with CSS :has, we are able to examine if the dashboard has an alert, and if sure, type accordingly.

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

So helpful.

Change grid columns based mostly on the variety of gadgets

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 gadgets?

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 gadgets, then the --item-size variable will change to 120px.

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

CSS grid minmax() operate

The best way minmax() works in CSS grid is conditional. Once we use auto-fit key phrase, we’re telling the browser: “if there may be an out there house, make the grid gadgets fill the house”.

The adjoining sibling combinator

That combinator matches the second aspect that comes instantly after a component.

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

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

The <p> prime margin has been modified conditionally.

The :focus-within pseudo-class

One other fascinating characteristic in CSS is :focus-within. Say that you simply need to examine whether or not an enter is targeted, and if sure, add a border to its mum or dad.

Think about the next instance:

We have now a search part. When the enter is targeted, the entire wrapper ought to have an overview. With :focus-within, we are able to examine if the enter is targeted, and magnificence 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 examine 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 fascinating conditional strategy so as to add border-radius for a card on the Fb web site.

The concept 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 fascinating 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 gadgets 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 gadgets 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() resolution is a suggestion by Temani Afif.

Intrinsic sizing: fit-content

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

If now we have a component with width: fit-content, it’ll 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 case you’re .

Comparability features

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

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

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

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

To try this, I can use the max() operate 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 structure.

Pseudo-classes

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

enter:checked + label {
  /* Customized styling */
}

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

If the enter is checked, add these types 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 loads. I personally don’t have a robust opinion on that, however CSS is conditional in some ways.

Actually, 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 means 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 feel that the power to create conditional guidelines with CSS is what units it aside and makes it highly effective for internet design.

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

I like to make use of the browser to tweak designs, as an alternative of designing them fully.

And also you, what do you suppose? I might 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