::before and ::after to create a hamburger icon
Hey all!
This is the code: https://gist.github.com/zenonmesic/ac335a5c48eb1b180e361e2f265ba93e
I am following a guide on how to create a hamburger icon. It uses an empty div and then ::before and ::after to add two extra lines that are then moved above and below the div and that is it. I am playing with it to actually understand how it works and I have read the documentation but it is still not clear to me.
Note before I start: I changed some colors, added the 1s and changed space-between to space-evenly just to better see and understand things.
The div is in button element, which is an in-line element. Here the button is given square dimensions of 48px. The div is a block-level element inside button but it has no content so it has been given fixed dimensions of 40px x 5px. The button is also set to display: flex to help center that div within the button. It is then given position: relative because we will be using position: absolute within the button.
Next, contentless ::before and ::after are given the same dimensions as our contentless div. Since the div has no real content, ::before and ::after have the same starting point, which is "in the middle" of our centered div. They have fixed width so they stretch outside of the div.
Okay, so far, so good.
Now, if I add "1" as content to my div and also "11" to ::before and ::after, since div now has some content, ::before moves a bit to the left, and ::after a bit to the right. Also understandable.
Now my questions:
1. What is the parent element of ::before and ::after? The div they are being attached to or the button element?
2. When we put position: absolute in .menu-icon, .menu-icon::before, .menu-icon::after, they are taken outside of the normal flow and now they are placed relative to their parent, in this case the button for menu-icon. Why is menu-icon div centered? Does flex centering still apply to it, even though it is now in absolute "mode"?
17 Replies
3. Why is content in .menu-icon, .menu-icon::before, .menu-icon::after centered? Why aren't 1s starting at the left of the div, of ::before and of ::after?
I must add that, when I read MDN, it is often not clear to me. It seems like you have to have a certain level of expertise to understand the documentation. So please try explaining in a more beginner-oriented manner. Thanks a lot everyone!
If you want to see where all of this comes from, this is the YT video I am following: https://youtu.be/PN5OC1mZlfY?list=PL0Zuz27SZ-6Mx9fd9elt80G1bPcySmWit&t=2150
What is the parent element of ::before and ::after? The div they are being attached to or the button element?They are attached to the div with the class ".menu-icon". In your code, this div is a child of the button with the class ".menu-button".
When we put position: absolute in .menu-icon, .menu-icon::before, .menu-icon::after, they are taken outside of the normal flow and now they are placed relative to their parent, in this case the button for menu-icon. Why is menu-icon div centered? Does flex centering still apply to it, even though it is now in absolute "mode"?Yes, the flex centering is still being applied. This is because, whilst you have given them a
position: absolute
you haven't actually "changed" their position within their parent container (the button).By default they are still placed in their natural position (without actually taking up any space). However, as they now have position absolute you can position them wherever you want using, for example, top, left, right and bottom.
Why is content in .menu-icon, .menu-icon::before, .menu-icon::after centered? Why aren't 1s starting at the left of the div, of ::before and of ::after?This is basically the same as question 2 - they are centered due to the flex properties that you have set up un the parent "button" element. I'm not sure that my answer is actually any clearer than mdn.... Basically setting
position: absolute
doesn't, by default, change the actual position of the element, it just allows it to be positioned wherever you need to,So, they are children of the button with the class ".menu-button"?
Shouldn't flex only apply to direct children? We have here:
.menu-button (button) > .menu-icon (div) > content of that div. Why is flex from .menu-button centering 2 levels deep?
I thought only div would be centered and then, if I wanted to center the content of the div itself, I would have to make it display: flex too and then center everything.
Thanks!
Did I misunderstand it completely?
They pseudo elements are inserted inline (by default) "before" and "after" the menu-icon so I suppose that, in one sense, they too are children of the .menu-button.
They do, however, inherit properties from the .menu-icon which makes them children of that element.... I can see how it can get confusing
So, they are children of both in a sense of inheriting properties?
And what about flex going two levels deep? Did I misunderstand that? I know I can center a text in div with text-align or centering anything in a div by doing display: flex or grid and centering it, but this is centered without me doing anything (at least as I see it, but I have only been learning this all for less than a month).
The .menu-icon is centered due to the flex and centering in the .menu-button.
The pseudo elements are placed, inline either side of that .menu-icon so they are also centered as their position is relative to that.
I'm not sure where you would actually expect them to be placed?
By default pseudo elements before and after are simply placed inline either side of the element to which they are attached.
Whilst it is quite common for them to then be absolutely positioned, that is not their default behaviour.
By default pseudo elements before and after are simply placed inline either side of the element to which they are attached.
Whilst it is quite common for them to then be absolutely positioned, that is not their default behaviour.
Their positioning is clear to me. What is not clear is why their content ends up being centered within them. The "1s" I have inserted. I would have expect them to be aligned at the beginning of ::after and ::before, like "1----" instead of "--1--". I am not sure why these "1s" are centered there. There is nothing from my point of view that would be centering the contents of .menu-icon, .menu-icon::before and .menu-icon::after. Am I missing something?
(p.s. don't mind my direct language, I do not natively speak English, and people did complain in the past that my direct way of writing can be perceived as negative by native speakers)
Ah, ok, you are specifically referring to the actual content of the pseudo elements. I miss understood 🙏
I am not at my computer right now but will take a closer look in a bit….
this is one hamburger icon i made quite a while ago
https://codepen.io/-bloop-/pen/rNqaJwN
with before and after
Hey boob, I am not looking to create a hamburger icon, that's already been done. I actually have question regarding how certain things work in the solution that I have linked above to fully understand what is happening.
aaah i see
i thought you were trying to make one after reading the title
no worries xD
OK, I have worked it out - once I had taken a closer look at your code and better understood what it was that you were specifically asking (my bad) I realised that it has nothing to do with flex, rather the fact that the parent text content which explains why all it is centered.
.menu-button
is... a button (big hint in it's name 🤦♂️ ) - I should have taken a closer look at the html rather than concentrating on the CSS. By default a button centers it's TIL about button centering, thanks. And that this type of inherent centering would be inherited by ::before and ::after. That is interesting, I wouldn't think that it would.
::before and ::after inherit settings from both the element they are created from and that element's parent. Very important to know.
Thanks a lot Chris! Does this server have some sort of +1 or "thanks" I can give you?
And that this type of inherent centering would be inherited by ::before and ::after. That is interesting, I wouldn't think that it would.To be honest I am now not sure that it is... rather their position is set by the position of the element to which the pseudo elements are attached, so, if that is centered then, as they are inline by default, the pseudo elements would also appear to be centered as they are placed either side of that. Again, I got distracted by not checking the actual .menu-button element type and just concentrating on the CSS
Ah, I see, thanks.
Does this server have some sort of +1 or "thanks" I can give you?
I couldn’t tell you but there is no need. To be honest I think that some of my answers might have been more confusing than helpful 🤣