Join Ray Villalobos for an in-depth discussion in this video Use calc() function for simple calculations in CSS, part of Building a Responsive Single-Page Design with PostCSS.
- PreCSS has another really useful plugin that makes it easy to reform simple calculations. Now, that can make life easier for you when you have to write some of the rules. So lets work on the next section which is the products section, and take a look at how this works. So, I'm going to create a new section right here and I'll give it a name called products, and then of course I need to call it right here in the style.css document.
And then I'm going to start working on this one. Let's go ahead and close some of these other ones. Ok, so right here I'm going to start off by targeting that section. So, products and I'm going to go ahead and put something in the .imageheader section so in a lot of these sections I have this special div called imageheader so, right here, I have, this imageheader that I can place a photo into.
Just to give this site a few extra pictures. I think adding some pictures is just sort of really nice. So we will go ahead and call our mixin called backImage. And then we will ask for a specific photo. It's really nice to have this mixin built. It really makes adding this background image a lot easier. So its going to be in the backgrounds folder, swimming.jpg and let's go ahead and add some other parameters. So, I'm going to give it an auto height and then I don't want this to have that darkening effect, so I'm going to do a transparent, to a transparent color here.
So, that brings this image of this swimming person, and, looks pretty cool I think. And then we begin with our products. So, lets go back here and now we can work on our product list. So let's go ahead and do products, let's go ahead and do some comments. Sometimes it's really sort of nice to add comments, just because its sort of tough sometimes with so many of these curly braces to tell what's what. So, if we look at the HTML, we have a div with a class of container, that just has the headline, and a paragraph right here.
So that is what I want to indent. You can see that it's indented here. And following all the normal container width. However, these products are just a bunch of big photos. I don't really want that to be in a container. I want them to go the full width of the browser. So, I'm going to come back here, and do .product-list and then take out the padding as well as the margin, just in case we have any. The product list happens to be an unordered list.
And normally those have margins and paddings, a lot of times they'll be using a normalizing sort of css template, but I'm not doing that here. So I need to make sure that I clear those out and then take out the list-style, make that none. So that it doesn't have the bullet points right here next to each image. And you can see that now the margin and paddings are gone. So lets go ahead and make this smaller and kind of scroll it up so we can see what's happening here a little better. Alright, so next up I want to make these fall in a grid, and to do that I'm going to use the display: flex property.
So, what that will do is, it will essentially put them side by side so you can see whats happening here. Now they're all side by side, and that is ok, but seems like, you don't really want them all to be side by side, because they need to wrap, otherwise they're just going to take up a crazy amount of room. So in addition to saying display: flex, we're also going to use flex-flow and ask for a row wrap.
So that all these images go into different rows. Now, it looks like they're stacked up on top of one another for now, and that's just because we need to resize them, because they're going to be sort of 100% of the width by default. So let's go ahead and work on that next. So for each one of these, I have a product item and one of the things that I want to do is hide the labels until I roll my mouse over the labels as well. So to do that I'm going to use a positioning trick where I position the container of both the label and the photo as a relative element, and let's go ahead and, make the color of the background and hide any overflow.
You're going to see how. Later on I'm going to add some animations here. So by hiding the overflow we'll actually be able to hide the animation so that its inside this image section. Alright, so now I'm going to set the width of these items. Now, I could do width like this, and this is normally what you would end up doing. You would say I want the width of this element to be 50% of the width of the container, and what's happening now is, you can see their appearance, side by side, because each one of these photos is going to take up half of the width of the container.
So, there should be two of them up side by side, and what I'm going to show you is, there is a really cool function that you can use with PreCSS. It's one of the plugins. And you remember, PreCSS is a pack of plugins. So one of them allows you to use this calc() method. And this is actually a quote unquote CSS4 method. It's something that's coming up in CSS. The ability to do calculations. There is no such thing as CSS4, but this is an upcoming feature in CSS, and its sort of useful.
I'm going to create a variable called item-width and then specify how many columns I want to divide that width by, so at the very top of the document I'm going to declare item-width to just be 100% of the width of the container. And then I'm going to say the width of this item is going to be whatever that item width is, divided by two. And since it's set up to be 100%, divided by two would be 50%, which is what you see here. But what that does is allow you to define these as columns so that you don't have to do that calculation.
100 divided by 2 is not a big deal. Divided by 3 ends up being like, .333 or 33.333333% and just think its kind of nice to just do this as opposed to have to pull out a calculator when you do like divide it by six, it ends up being like, 16.6667 so its just easier to use them like this. So, now it's going to be much simpler to do our media query. So I'm going to do-- Whenever we are at a small size so, media, and then do small.
Then I'm going to just do this rule here again. And I could probably put this in a variable, so, whenever we're at a small size I want to divide this by 3, and then I'm going to do that a couple more times. One for the medium, and one for the large size. And then I can just simply come in here and go. Well, whenever it's at a medium size I want 4 of these next to each other, and then whenever we're at the large size, I want to say I want 6 and it's much easier to play with these values when you write them out like this, than having to, you know, pull out a calculator and do that.
So, that is pretty cool. Let's go ahead and do the product names so that they're hidden before I save this, so that we can just not show the product name by default. So you can see the grid, looking really nice. So we'll do .product-name, and then in here we'll set the background of the product-name to the red color, and set the color of that label to yellow, the font-weight, we'll set it to our font-weight-heavy variable.
font-size, 80% of the default size, and then text-align-- this is just straight CSS. text-align: center. And here's where we finish off the other trick. When we set the position of this element to absoloute then because the container has a position of relative then this one will be drawn relative to the position of the other one. So the label will be placed relative to the position of the image, not really the image, but the container of the image.
And so, this is what's going to allow us to put these on top of one another. I think it'll make more sense when you see it. So just, bear with me a second while I finish this off. I want the labels to be at the bottom, so align them to the bottom by 0%, make the width of the labels 100%, and then align-- I think I already said align-center. Here's where we hide them. We'll say display: none; Alright, so let's go ahead and save it so we can at least see the grid. And we can see that now the labels are gone.
It's got all this styling to them, but we can't see them which is fine. Because I just want to show you the grid that we created when we did all of these right here. So, by default they're going to appear two up. That's where this two comes in. And whenever this is a little bigger, it'll go to three up, right? And whenever its a little bigger it'll go to four up. And whenever we're at the very large, I've got a super size monitor size, it'll go to six up. I just like that you can do this calc() function and visually see what your columns are going to be as opposed to having to try to do something with a calculator.
Alright, so let's do, what happens when somebody hovers over the product item. What I can do here. So this is, let's see, .product-name, and I just want a little comment here. I like to comment stuff. We can use an ampersand in PreCSS, like we can in Sass, to call the parent element, so what we're saying here is, whenever somebody rolls over the item, so right now, we are in this product-item section here, and let's go ahead and add that to this.
So I'm going to do a comment here again. Comments are so awesome. I love comments. They make your life so much easier, because now I don't really know-- product-item, indent, this is product-list. Right, so its just, whenever you have so many of these kind of code, it's just easier to put comments on them, and then you know where you are. Ok, that looks much more beautiful for me. So, whenever you hover each one of these items, or whenever these items are focused, you should always do the focus with the hover, an item can come into focus if somebody tabs through items, and also for readers.
So whenever you do hover, make sure you add focus. And then in here we'll just say .product-name and then we'll display this as a block element. Alright, so, let's go ahead and save this, probably add some more comments, if you really wanted to here. And then now, when we roll over these, the comments show, and it looks really nice even at the bigger size, and we've got a nice roll over effect. And we've got this really awesome grid, brought to you by flexbox and a combination of positioning relative with positioning absolute.
So the trick that is allowing us to align these labels to the bottom of the container that has the image and the label, is that we are saying, I want everything to align to the position of this product item, so I want everything to go with this position relative. And then each one of the items, the product names are going to be positioned with an absolute positioning. And that just makes the names move together with the items, and visually, that shows up as, I don't care where these items are, the names are going to be at the bottom of each one of these items.
And that works pretty well. So calculations are a very nice way to avoid having to pull out the calculator whenever you're working with CSS, you can use them more extensively to create complex mixins, or add formulas to your CSS and help you code a little more efficiently.
- Structuring the HTML markup for a single-page design
- Using PreCSS Sass-like imports in PostCSS
- Creating Sass-like variables with PreCSS
- Building styles
- Creating a layout for the header and navigation with Flexbox
- Creating and styling sections
- Animating page elements with PostCSS