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 towrap
, 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
torow
. 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.