object-fit – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Tue, 12 Jul 2022 17:08:50 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 object-fit – CSS-Tricks https://css-tricks.com 32 32 45537868 In Praise of Shadows https://css-tricks.com/in-praise-of-shadows/ https://css-tricks.com/in-praise-of-shadows/#respond Tue, 12 Jul 2022 17:08:49 +0000 https://css-tricks.com/?p=366896 Our dear friend Robin has a new essay called In Praise of Shadows. Now, before you hop over there looking for nuggets on CSS box shadows, text shadows, and shadow filters… this is not that. It’s an essay …


In Praise of Shadows originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Our dear friend Robin has a new essay called In Praise of Shadows. Now, before you hop over there looking for nuggets on CSS box shadows, text shadows, and shadow filters… this is not that. It’s an essay on photography and what Robin has learned about handing shadows with a camera.

So, why share this? Because it’s cool as heck that he made an article directed page dedicated to one essay. And you’ll learn a lot about CSS if you crack open DevTools on it:

  • Centering techniques. Notice how CSS Grid is used on the <body> simply to center the pamphlet. Then Robin reaches for it again on each .frame of the essay to do the same thing with the content.
  • “Faux” background images. Robin could have made a lot of work for himself by creating a CSS class for each .frame to get the background images. Instead, he uses object-fit: cover on inlined HTML <img>s to maintain the aspect ratio while filling the .frame container. (He’s actually written about this before.) That sure saves a lot of CSS’ing, but it also allows him to use alt text if needed. I sorta wonder if a <figure>/<figcaption> structure could’ve worked here instead but I doubt it would provide much additional benefit for what’s going on.
  • Stacking contexts. Another perk of those faux background images? They use absolute positioning which creates a stacking context, allowing Robin to set a z-index: 0 on the images. That way, the text stacks directly on top with z-index: 1. Again, CSS Grid is handling all the centering so things are nicely aligned.
  • Scroll snapping. I always love it when I see CSS scroll snapping in the wild. Robin made a nice choice to use it here, as it really lends to the whole page-turning experience while scrolling through frames. Horizontal scrolling can be maddening, but also extremely elegant when executed well as it is here in how it enhances the narrow-column design. If you want a nice explanation of how it all works, Robin has also written about horizontal scroll snapping.

If nothing else, Robin is an excellent writer and it’s worth reading anything he publishes, CSS and beyond.

To Shared LinkPermalink on CSS-Tricks


In Praise of Shadows originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/in-praise-of-shadows/feed/ 0 366896
Beyond Media Queries: Using Newer HTML & CSS Features for Responsive Designs https://css-tricks.com/beyond-media-queries-using-newer-html-css-features-for-responsive-designs/ https://css-tricks.com/beyond-media-queries-using-newer-html-css-features-for-responsive-designs/#comments Fri, 04 Sep 2020 14:46:17 +0000 https://css-tricks.com/?p=319906 Beyond using media queries and modern CSS layouts, like flexbox and grid, to create responsive websites, there are certain overlooked things we can do well to make responsive sites. In this article, we’ll dig into a number tools (revolving around …


Beyond Media Queries: Using Newer HTML & CSS Features for Responsive Designs originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Beyond using media queries and modern CSS layouts, like flexbox and grid, to create responsive websites, there are certain overlooked things we can do well to make responsive sites. In this article, we’ll dig into a number tools (revolving around HTML and CSS) we have at the ready, from responsive images to relatively new CSS functions that work naturally whether we use media queries or not.

In fact, media queries become more of a complement when used with these features rather than the full approach. Let’s see how that works.

Truly responsive images

Remember when we could just chuck width: 100% on images and call it a day? That still works, of course, and does make images squishy, but there are a number of downsides that come with it, the most notable of which include:

  • The image might squish to the extent that it loses its focal point.
  • Smaller devices still wind up downloading the full size image.

When using images on the web, we have to make sure they’re optimized in terms of their resolution and size. The reason is to ensure that we have the right image resolution to fit the right device, so we don’t end up downloading really large and heavy images for smaller screens which could end up reducing the performance of a site. 

In simple terms, we’re making sure that larger, high-resolution images are sent to larger screens, while smaller, low-resolution variations are sent to smaller screens, improving both performance and user experience.

HTML offers the <picture> element that allows us specify the exact image resource that will be rendered based on the media query we add. As described earlier, instead of having one image (usually a large, high-resolution version) sent to all screen sizes and scaling it to the viewport width, we specify a set of images to serve in specific situations.

<picture>
  <source media="(max-width:1000px)" srcset="picture-lg.png">
  <source media="(max-width:600px)" srcset="picture-mid.png">
  <source media="(max-width:400px)" srcset="picture-sm.png">
  <img src="picture.png" alt="picture"">
</picture>

In this example, picture.png is the full-size image. From there, we define the next-largest version of the image, picture-lg.png, and the size reduces in descending order until the smallest version, picture-sm.png. Note that we’re still using media queries in this approach, but it’s the <picture> element itself that is driving the responsive behavior rather than defining breakpoints in the CSS.

The media queries are added appropriately to scale with the sizes of the picture:

  • Viewports that are 1000px and above get picture.png.
  • Viewports that are between 601px and 999px get picture-lg.png.
  • Viewports that are between 401px and 600px get picture-sm.png.
  • Any thing smaller than 400px gets picture-sm.png.

Interestingly, we can also label each image by image density —  1x, 2x, 3x and so forth — after the URL. This works if we have made the different images in proportion to each other (which we did). This allows the browser to determine which version to download based on the screen’s pixel density in addition to the viewport size. But note how many images we wind up defining:

<picture>
  <source media="(max-width:1000px)" srcset="picture-lg_1x.png 1x, picture-lg_2x.png 2x, picture-lg_3x.png 3x">
  <source media="(max-width:600px)" srcset="picture-mid_1x.png 1x, picture-mid_2x.png 2x, picture-mid_3x.png 3x">
  <source media="(max-width:400px)" srcset="picture-small_1x.png 1x, picture-small_2x.png 2x, picture-small_1x.png 3x">
  <img src="picture.png" alt="picture"">
</picture>

Let’s look specifically at the two tags nested inside the <picture> element: <source> and <img>.

The browser will look for the first <source> element where the media query matches the current viewport width, and then it will display the proper image (specified in the srcset attribute). The <img> element is required as the last child of the <picture> element, as a fallback option if none of the initial source tags matches.

We can also use image density to handle responsive images with just the <img> element using the srcset attribute:

<img
 srcset="
  flower4x.png 4x,
  flower3x.png 3x,
  flower2x.png 2x,
  flower1x.png 1x
 "
 src="flower-fallback.jpg"
>

Another thing we can do is write media queries in the CSS based on the screen resolution (usually measured in dots per inch, or dpi) of the device itself and not just the device viewport. What this means is that instead of:

@media only screen and (max-width: 600px) {
  /* Style stuff */
}

We now have:

@media only screen and (min-resolution: 192dpi) {
  /* Style stuff */
}

This approach lets us dictate what image to render based the screen resolution of the device itself, which could be helpful when dealing with high resolution images. Basically, that means we can display high quality pictures for screens that support higher resolutions and smaller versions at lower resolutions. It’s worth noting that, although mobile devices have small screens, they’re usually high resolution. That means it’s probably not the best idea rely on resolution alone when determining which image to render. It could result in serving large, high-resolution images to really small screens, which may not be the version we really want to display at such a small screen size.

body {
  background-image : picture-md.png; /* the default image */
}


@media only screen and (min-resolution: 192dpi) {
  body {
    background-image : picture-lg.png; /* higher resolution */
  }
}

What <picture> gives us is basically the ability to art direct images. And, in keeping with this idea, we can leverage CSS features, like the object-fit property which, when used with object-position, allows us to crop images for better focal points while maintaining the image’s aspect ratio.

So, to change the focal point of an image:

@media only screen and (min-resolution: 192dpi) {
  body {
    background-image : picture-lg.png;
    object-fit: cover;
    object-position: 100% 150%; /* moves focus toward the middle-right */
  }
}

Setting minimum and maximum values in CSS

The min() function specifies the absolute smallest size that an element can shrink to. This function proves really useful in terms of helping text sizes to properly scale across different screen sizes, like never letting fluid type to drop below a legible font size:

html {
  font-size: min(1rem, 22px); /* Stays between 16px and 22px */
}

min() accepts two values, and they can be relative, percentage, or fixed units. In this example, we’re telling the browser to never let an element with class .box go below 45% width or 600px, whichever is smallest based on the viewport width:

.box {
  width : min(45%, 600px)
}

If 45% computes to a value smaller than 600px, the browser uses 45% as the width. Conversely, if  45% computes to a value greater than 600px, then 600px will be used for the element’s width.

The same sort of thing goes for the max() function. It also accepts two values, but rather than specifying the smallest size for an element, we’re defining the largest it can get.

.box {
  width : max(60%, 600px)
}

If 60% computes to a value greater than 600px, the browser uses 60% as the width. On the flip side, if 60% computes to a value smaller than 600px, then 600px will be used as the element’s width.

Clamping values

Many of us have been clamoring for clamp() for some time now, and we actually have broad support across all modern browsers (sorry, Internet Explorer). clamp() is the combination of the min() and max() functions, accepting three parameters:

  1. the minimum value,
  2. the preferred value, and
  3. the maximum value

For example:

.box {
  font-size : clamp(1rem, 40px, 4rem)
}

The browser will set the font at 1rem until the computed value of 1rem is larger than 40px. And when the computed value is above 40px? Yep, the browser will stop increasing the size after it hits 4rem. You can see how clamp() can be used to make elements fluid without reaching for media queries.

Working with responsive units

Have you ever built a page with a large heading or sub-heading and admired how great it looked on a desktop screen, only to check it on a mobile device and find out that’s it’s too large? I have definitely been in this situation and in this section I’ll be explaining how to handle such problems.

In CSS, you can determine sizes or lengths of elements using various units of measurements, and the most used units of measurements includes: px, em, rem, %, vw, and vh. Although, there are several more units that aren’t used as frequently. What’s of interest to us is that px can be considered an absolute unit, while the rest are considered relative units.

Absolute units

A pixel (px) is considered an absolute unit mainly because it’s fixed and does not change based on the measurement of any other element. It can be considered as the base, or root, unit that some other relative units use. Trying to use pixels for responsive behavior can bump into issues because it’s fixed, but they’re great if you have elements that should not be resized at all.

Relative units

Relative units, like %, em, and rem, are better suited to responsive design mainly because of their ability to scale across different screen sizes.

vw: Relative to the viewport’s width
vh: Relative to the viewport’s height
rem: Relative to the root (<html>) element (default font-size is usually 16px )
em: Relative to the parent element
%: Relative to the parent element

Again, the default font size for most browsers is 16px and and that’s what rem units use to generate their computed values. So, if a user adjusts the font size on the browser, everything on the page scales properly depending on the root size. For example, when dealing a root set at 16px, the number you specify will multiply that number times the default size. For example:

.8rem = 12.8px (.8 * 16)
1rem = 16px (1 * 16)
2rem = 32px (2 * 16)

What if either you or the user changes the default size? As we said already, these are relative units and the final size values will be based off of the new base size. This proves useful within media queries, where you just change the font size and the entire page scales up or down accordingly.

For example, if you changed the font-size to 10px within the CSS, then the calculated sizes would end up being:

html {
  font-size : 10px;
}
1rem = 10px (1 * 10)
2rem = 20px (2 * 10)
.5rem = 5px (.5 * 10)

Note: This also applies to percentage %. For instance:

100% = 16px;
200% = 32px; 
50% = 8px;

And what’s the difference between rem and em units? It’s what the unit uses as its base element. rem calculates values using the font size of the root (<html>) element, whereas an element declaring em values references the font size of the parent element that contains it. If the size of specified parent element is different from the root element (e.g. the parent elements is 18px but the root element is 16px) then em and rem will resolve to different computed values. This gives us more fine-grained control of how our elements respond in different responsive contexts.

vh is an acronym for viewport height, or the viewable screen’s height. 100vh represent 100% of the viewport’s height (depending on the device). In the same vein, vw stands for viewport width, meaning the viewable screen’s width of the device, and 100vw literally represents 100% of the viewport’s width.

Moving beyond media queries

See that? We just looked at a number of really powerful and relatively new HTML and CSS features that give us additional (and possible more effective) ways to build for responsiveness. It’s not that these new-fangled techniques replace what we’ve been doing all along. They are merely more tools in our developer tool belt that give us greater control to determine how elements behave in different contexts. Whether it’s working with font sizes, resolutions, widths, focal points, or any number of things, we have more fine-grain control of the user experience than ever before.

So, next time you find yourself working on a project where you wish you had more control over the exact look and feel of the design on specific devices, check out what native HTML and CSS can do to help — it’s incredible how far things have come along.


Beyond Media Queries: Using Newer HTML & CSS Features for Responsive Designs originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/beyond-media-queries-using-newer-html-css-features-for-responsive-designs/feed/ 27 319906
How to Make a Media Query-less responsive Card Component https://css-tricks.com/how-to-make-a-media-query-less-card-component/ https://css-tricks.com/how-to-make-a-media-query-less-card-component/#comments Tue, 01 Sep 2020 14:29:00 +0000 https://css-tricks.com/?p=319736 Fun fact: it’s possible to create responsive components without any media queries at all. Certainly, if we had container queries, those would be very useful for responsive design at the component level. But we don’t. Still, with or without …


How to Make a Media Query-less responsive Card Component originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Fun fact: it’s possible to create responsive components without any media queries at all. Certainly, if we had container queries, those would be very useful for responsive design at the component level. But we don’t. Still, with or without container queries, we can do things to make our components surprisingly responsive. We’ll use concepts from Intrinsic Web Design, brought to us by Jen Simmons.

Let’s dive together into the use case described below, the solutions regarding the actual state of CSS, and some other tricks I’ll give you.

A responsive “Cooking Recipe” card

I recently tweeted a video and Pen of a responsive card demo I built using a recipe for pizza as an example. (It’s not important to the technology here, but I dropped the recipe at the end because it’s delicious and gluten free.)

The demo here was a first attempt based on a concept from one of Stéphanie Walter’s talks. Here is a video to show you how the card will behave:

And if you want to play with it right now, here’s the Pen.

Let’s define the responsive layout

A key to planning is knowing the actual content you are working, and the importance of those details. Not that we should be hiding content at any point, but for layout and design reasons, it’s good to know what needs to be communicated first and so forth. We’ll be displaying the same content no matter the size or shape of the layout.

Let’s imagine the content with a mobile-first mindset to help us focus on what’s most important. Then when the screen is larger, like on a desktop, we can use the additional space for things like glorious whitespace and larger typography. Usually, a little prioritization like this is enough to be sure of what content is needed for the cards at any and all viewport sizes.

Let’s take the example of a cooking recipe teaser:

In her talk, Stéphanie had already did the job and prioritized the content for our cards. Here’s what she outlined, in order of importance:

  1. Image: because it’s a recipe, you eat with your eyes!
  2. Title: to be sure what you’re going to cook.
  3. Keywords: to catch key info at the first glance.
  4. Rating info: for social proof.
  5. Short description: for the people who read.
  6. Call to action: what you expect the user to do on this card.

This may seem like a lot, but we can get all of that into a single smart card layout!

Non-scalable typography

One of the constraints with the technique I’m going to show you is that you won’t be able to get scalable typography based on container width. Scalable typography (e.g. “fluid type”) is commonly done with the with viewport width (vw) unit, which is based on the viewport, not the parent element.

So, while we might be tempted to reach for fluid type as a non-media query solution for the content in our cards, we won’t be able to use fluid type based on some percentage of the container width nor element width itself, unfortunately. That won’t stop us from our goal, however!

A quick note on “pixel perfection”

Let’s talk to both sides here…

Designers: Pixel perfect is super ideal, and we can certainly be precise at a component level. But there has to be some trade-off at the layout level. Meaning you will have to provide some variations, but allow the in-betweens to be flexible. Things shift in responsive layouts and precision at every possible screen width is a tough ask. We can still make things look great at every scale though!

Developers: You’ll have to be able to fill the gaps between the layouts that have prescribed designs to allow content to be readable and consistent between those states. As a good practice, I also recommend trying to keep as much of a natural flow as possible.

You can also read the Ahmad’s excellent article on the state of pixel perfection.

A recipe for zero media queries

Remember, what we’re striving for is not just a responsive card, but one that doesn’t rely on any media queries. It’s not that media queries should be avoided; it’s more about CSS being powerful and flexible enough for us to have other options available.

To build our responsive card, I was wondering if flexbox would be enough or if I would need to do it with CSS grid instead. Turns out flexbox in indeed enough for us this time, using the behavior and magic of the flex-wrap and flex-basis properties in CSS.

The gist of flex-wrap is that it allows elements to break onto a new line when the space for content gets too tight. You can see the difference between flex with a no-wrap value and with wrapping in this demo:

The flex-basis value of 200px is more of an instruction than a suggestion for the browser, but if the container doesn’t offer enough space for it, the elements move down onto a new line. The margin between columns even force the initial wrapping.

I used this wrapping logic to create the base of my card. Adam Argyle also used it on the following demo features four form layouts with a mere 10 lines of CSS:

In his example, Adam uses flex-basis and flex-grow (used together in flex shorthand property) )to allow the email input to take three times the space occupied by the name input or the button. When the browser estimates there is not enough rooms to display everything on the same row, the layout breaks itself into multiple lines by itself, without us having to manage the changes in media queries.

I also used clamp() function to add even more flexibility. This function is kind of magical. It allows us to resolve a min() and a max() calculation in a single function. The syntax goes like this:

clamp(MIN, VALUE, MAX)

It’s like resolving a combination of the max() and min() functions:

max(MIN, min(VAL, MAX))

You can use it for all kind of properties that cover:  <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer>.

The “No-Media Query Responsive Card” demo

With all of these new-fangled CSS powers, I created a flexible responsive card without any media queries. It might be best to view this demo in a new tab, or with a 0.5x option in the embed below.

Something you want to note right away is that the HTML code for the 2 cards are exactly the same, the only difference is that the first card is within a 65% wide container, and the second one within a 35% wide container. You can also play with the dimension of your window to test its responsiveness.

The important part of the code in that demo is on these selectors:

  • .recipe is the parent flex container.
  • .pizza-box is a flex item that is the container for the card image.
  • .recipe-content is a second flex item and is the container for the card content. 

Now that we know how flex-wrap works, and how flex-basis and flex-grow  influence the element sizing, we just need to quickly explain the clamp() function because I used it for responsive font sizing in place of where we may have normally reached for fluid type.

I wanted to use calc() and custom properties to calculate font sizes based on the width of the parent container, but I couldn’t find a way, as a 100% value has a different interpretation depending on the context. I kept it for the middle value of my clamp() function, but the end result was over-engineered and didn’t wind up working as I’d hoped or expected.

/* No need, really */
font-size: clamp(1.4em, calc(.5em * 2.1vw), 2.1em);

Here’s where I landed instead:

font-size: clamp(1.4em, 2.1vw, 2.1em);

That’s what I did to make the card title’s size adjust against the screen size but, like we discussed much earlier when talking about fluid type, we won’t be able to size the text by the parent container’s width.

Instead, we’re basically saying this with that one line of CSS:

I want the font-size to equal to 2.1vw (2.1% of the viewport width), but please don’t let it go below 1.4em or above 2.1em.

This maintains the title’s prioritized importance by allowing it to stay larger than the rest of the content, while keeping it readable. And, hey, it still makes grows and shrinks on the screen size!

And let’s not forget about responsive images, The content requirements say the image is the most important piece in the bunch, so we definitely need to account for it and make sure it looks great at all screen sizes. Now, you may want to do something like this and call it a day:

max-width: 100%;
height: auto;

But that’s doesnt always result in the best rendering of an image. Instead, we have the object-fit property, which not only responds to the height and width of the image’s content-box, but allows us to crop the image and control how it stretches inside the box when used with the object-position property.

img {
  max-width: 100%;
  min-height: 100%;
  width: auto;
  height: auto;
  object-fit: cover;
  object-position: 50% 50%;
}

As you can see, that is a lot of properties to write down. It’s mandatory because of the explicit width and height properties in the HTML <img> code. If you remove the HTML part (which I don’t recommend for performance reason) you can keep the object-* properties in CSS and remove the others.

An alternative recipe for no media queries

Another technique is to use flex-grow as a unit-based growing value, with an absurdly enormous value for flex-basis. The idea is stolen straight from the Heydon Pickering’s great “Holy Albatross” demo.

The interesting part of the code is this:

/* Container */
.recipe {
  --modifier: calc(70ch - 100%);


  display: flex;
  flex-wrap: wrap;
}


/* Image dimension */
.pizza-box {
  flex-grow: 3;
  flex-shrink: 1;
  flex-basis: calc(var(--modifier) * 999);
}


/* Text content dimension */
.recipe-content {
  flex-grow: 4;
  flex-shrink: 1;
  flex-basis: calc(var(--modifier) * 999);
}

Proportional dimensions are created by flex-grow while the flex-basis dimension can be either invalid or extremely high. The value gets extremely high when calc(70ch - 100%), the value of  --modifier, reaches a positive value. When the values are extremely high each of them fills the space creating a column layout; when the values are invalid, they lay out inline.

The value of 70ch acts like the breakpoint in the recipe component (almost like a container query). Change it depending on your needs.

Let’s break down the ingredients once again

Here are the CSS ingredients we used for a media-query-less card component:

  • The clamp() function helps resolve a “preferred” vs. “minimum” vs. “maximum” value.
  • The flex-basis property with a negative value decides when the layout breaks into multiple lines.
  • The flex-grow property is used as a unit value for proportional growth.
  • The vw unit helps with responsive typography.
  • The  object-fit property provides finer responsiveness for the card image, as it allows us to alter the dimensions of the image without distorting it.

Going further with quantity queries

I’ve got another trick for you: we can adjust the layout depending on the number of items in the container. That’s not really a responsiveness brought by the dimension of a container, but more by the context where the content lays.

There is no actual media query for number of items. It’s a little CSS trick to reverse-count the number of items and apply style modifications accordingly.

The demo uses the following selector:

.container > :nth-last-child(n+3),
.container > :nth-last-child(n+3) ~ * {
  flex-direction: column;
}

Looks tricky, right? This selector allows us to apply styles from the last-child and all it’s siblings. Neat! 

Una Kravets explains this concept really well. We can translate this specific usage like this:

  • .container > :nth-last-child(n+3): The third .container element or greater from the last .container in the group.
  • .container > :nth-last-child(n+3) ~ *: The same exact thing, but selects any .container element after the last one. This helps account for any other cards we add.

Kitty Giraudel’s “Selectors Explained” tool really helps translate complex selectors into plain English, if you’d like another translation of how these selectors work.

Another way to get “quantity” containers in CSS is to use binary conditions. But the syntax is not easy and seems a bit hacky. You can reach me on Twitter if you need to talk about that — or any other tricks and tips about CSS or design. pastedGraphic.png

Is this future proof?

All the techniques I presented you here can be used today in a production environment. They’re well supported and offer opportunities for graceful degradation.

Worst case scenario? Some unsupported browser, say Internet Explorer 9, won’t change the layout based on the conditions we specify, but the content will still be readable. So, it’s supported, but might not be “optimized” for the ideal experience.

Maybe one day we will finally get see the holy grail of container queries in the wild. Hopefully the Intrinsic Web Design patterns we’ve used here resonate with you and help you build flexible and “intrinsicly-responsive” components in the meantime.

Let’s get to the “rea” reason for this post… the pizza! 🍕


Gluten free pan pizza recipe

You can pick the toppings. The important part is the dough, and here is that:

Ingredients

  • 3¼ cups (455g) gluten free flour
  • 1 tablespoon, plus 1 teaspoon (29g) brown sugar
  • 2 teaspoons of kosher salt
  • 1/2 cube of yeast
  • 2½ cups (400 ml) whole almond milk
  • 4 tablespoons of melted margarine
  • 1 tablespoon of maizena

Instructions

  1. Mix all the dry ingredients together.
  2. Add the liquids.
  3. Let it double size for 2 hours. I’d recommend putting a wet dish towel over your bowl where the dough is, and place the dish close to a hot area (but not too hot because we don’t want it to cook right this second).
  4. Put it in the pan with oil. Let it double size for approximately 1 hour.
  5. Cook in the oven at 250 degrees for 20 minutes.

Thanks Stéphanie for the recipe 😁


How to Make a Media Query-less responsive Card Component originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/how-to-make-a-media-query-less-card-component/feed/ 17 319736