Profile preview card component using HTML, CSS, JS, FLEXBOX
Design comparison
Solution retrospective
positioning the background patterns felt really tricky. I copied grace's code to make it work. but I didn't really understand.
- why doesn't it work, if we apply the same styles to the body? If the same styles are applied to the component-wrapper, it's working. what's the difference? component-wrapper and body are both outside the main. it's confusing. please clarify.
- why can't we just place the background patterns normally without using pseudo-selectors?(I've tried to place them normally but I was not successful)
- :Before selector has only top pattern and :after has bottom pattern. Why use both selectors?
Community feedback
- @Mar1362Posted about 2 years ago
Awesome render !!!
0@venkat2305Posted about 2 years ago@Mar1362 hey, I've a few questions. positioning the background patterns felt really tricky. I copied grace's code to make it work. but I didn't really understand.
why doesn't it work, if we apply the same styles to the body? If the same styles are applied to the component-wrapper, it's working. what's the difference? component-wrapper and body are both outside the main. it's confusing. please clarify. why can't we just place the background patterns normally without using pseudo-selectors?(I've tried to place them normally but I was not successful) :Before selector has only top pattern and :after has bottom pattern. Why use both selectors?
0@Mar1362Posted about 2 years ago@venkat2305 Hi,
- The problem is you have too much container for the same thing and you don't need that. In fact, your
.component-wrapper
, yourmain
as well as your.container
are all styled as container of your card because they all fit the screen and center their children which does the same too. Moreover, if you addz-index
you should take care about which container is behind and which one is in front of the other. As a consequence, if you set abackground
, for exemple, to an element, let's say A with awidth:100%; height: 100%;
, which happen to be in front of another element, B due to the z-index, this last one will be hidden by the A element even if you set a background for it . i tried to clean your html code a little bit and now it looks like this (showing just the body):
<body> <main > <img src="images/bg-pattern-card.svg" alt="" /> <div class="content"> <img src="images/image-victor.jpg" alt="Image of Victor" /> <h1>Victor Crest <span>26</span></h1> <p>London</p> </div> <hr /> <ul class="info-container"> <li><strong>80K</strong>Followers</li> <li><strong>803K</strong>Likes</li> <li><strong>1.4K</strong>Photos</li> </ul> </main> </body>
compare it to your first code and see what i deleted because i didn't add anything and do not care about the classes that i remove that's not the most important just take a look at the new structure.
and here is the css code that i modified and reorganized for better reading. again, nothing was added i just deleted some code and renamed some classes that i deleted from the html to their tag name. And you'll see that it is possible to apply the same style of your
.component-wrapper
to thebody
tag. :@import url("https://fonts.googleapis.com/css2?family=Kumbh+Sans:wght@400;700&display=swap"); *, *:before, *:after { margin: 0; padding: 0; box-sizing: border-box; } :root { --Dark-cyan: hsl(185, 75%, 39%); --Very-dark-desaturated-blue: hsl(229, 23%, 23%); --Dark-grayish-blue: hsl(227, 10%, 46%); --Dark-gray: hsl(0, 0%, 59%); } body { font-family: "Kumbh Sans", sans-serif; background-color: var(--Dark-cyan); min-height: 100vh; display: flex; flex-direction: row; justify-content: center; align-items: center; position: relative; font-family: "Kumbh Sans", sans-serif; overflow: hidden; background: #19a2ae; } body:before, body:after { position: absolute; content: ""; width: 100vw; height: 100vh; background-size: auto; transform: translate(-50%, -50%); } body:before { top: 0; left: 0; background: url("images/bg-pattern-top.svg") no-repeat bottom right; } body:after { top: 100%; left: 100%; background: url("images/bg-pattern-bottom.svg") no-repeat top left; } main { display: flex; flex-direction: column; border-radius: 10px; overflow: hidden; background-color: white; max-width: 400px; margin: 15px; box-shadow: 1px 1px 60px 0px hsl(227, 10%, 46%); z-index: 1; } .content img { display: block; max-width: 100%; border-radius: 50%; border: 5px solid white; margin: -50px auto 10px auto; } h1 { font-size: 1.5rem; } h1, strong { font-weight: 700; color: var(--Very-dark-desaturated-blue); text-align: center; } .content span { font-weight: 400; color: var(--Dark-grayish-blue); } p, li { font-weight: 400; text-align: center; color: var(--Dark-grayish-blue); } .content p { margin-top: 7px; } .info-container { display: flex; justify-content: space-evenly; padding: 25px 0; list-style: none; } strong { display: block; } hr { border: none; height: 0.51px; background-color: var(--Dark-gray); margin-top: 30px; }
-
:before
selector is positionned asabsolute
withtop
property so it is logic for it to hold the top pattern if we want to correctly place the pattern and that is the same thing for:after
pseudo-selector. and don't forget that they havetransform: translate(-50%, -50%)
even if they havewidth:100vw
andheight:100vh
. I suggest you to learn about these pseudo-selector and a video is most easy so click here to watch one -
Also, if you want to correctly add the background pattern without using pseudo-selector, let me tell you that it is possible. But, let me tell you also it will be really tiring doing it so. In fact for each interval of screen size you have to re-adjust it in order to place it correctly and i think that you'll have at least 8 media queries 🤣. for exemple here is your commented code in the
body
modified for a screen of 1360 * 675 :
background-image: url("images/bg-pattern-top.svg"), url("images/bg-pattern-bottom.svg"); background-position: -90% 190%, 48vw 55vh; background-repeat: no-repeat;
Hope this helped you and this new code being more comprehensive !
we are always here for help so feel free to ask again if there is another one
1@venkat2305Posted about 2 years ago@Mar1362
- in the second method, we are positioning the patterns in viewport units and it changes with the size of the device. so, it should automatically adopt with respect to the device right?
- can you please explain why we have used
width: 100vw; height: 100vh;
it means that patterns are being applied on the
viewport
completely. but, we need them only at selective places. Please explain.1@Mar1362Posted about 2 years ago@venkat2305 hi again, in my previous comment here is what i said "don't forget that they have
transform: translate(-50%, -50%)
even if they havewidth:100vw
andheight:100vh
". In fact, i invite you to place the pattern in a blank page to see how it really looks like then you'll remark that we do not need, for the top pattern, the upper half and the left half so 50% of the top and 50% of the left should be off the screen and it is the reverse for the bottom pattern ( 50% right and 50% bottom should be off the screen). so we only need the bottom-right part of the top pattern and the upper-left part of the bottom pattern and in order to place them at the right size we have to fill all the patterns at the viewport size so we'll have the right ratio whatever the screen size is and then making off screen the not needed part of the pattern by using thetransform: translate(-50%, -50%)
property. and another way to make them off screen is to play with thetop: ; | left: ; | right: ; | bottom: ;
properties since the:before | :after
are inposition: absolute;
GOOD NEWS : it is possible to place the pattern without using the pseudo-selectors by just using the background of the body without any media queries and i found this solution by answering your question.
-
first of all add the patterns as backgrounds of the body like that
background: url(images/bg-pattern-top.svg) no-repeat top left, url(images/bg-pattern-bottom.svg) no-repeat bottom right, #19a2ae;
-
then set their size to fill all the viewport width for the same reason i explained earlier like this:
background-size: 100vw 100vw
i usevw
for the height of the pattern in order to get a square ratio so it won't looks streched -
and finally place them by putting the not needed parts of the patterns off the screen as follow:
background-position: left -50vw top -50vw, bottom -50vw right -50vw;
here is the full code:
background: url(images/bg-pattern-top.svg) no-repeat top left, url(images/bg-pattern-bottom.svg) no-repeat bottom right, #19a2ae; background-size: 100vw; /* it means the same thing as before*/ background-position: left -50vw top -50vw, bottom -50vw right -50vw;
this new method is responsive and easier than the last one with pseudo-selectors and i hope you understand my explaination. do not worry we are always happy to get question so if there is another question feel free to ask it.
1@venkat2305Posted about 2 years ago@Mar1362 Thank you so much for your explanation. I have the clarity now. You are awesome
0@Mar1362Posted about 2 years ago@venkat2305 you're welcome all the pleasure was for me and it's you the most awesome. And what do you think about the new method ? Is it what you was looking for (placing pattern without pseudo-selectors) ?
0 - The problem is you have too much container for the same thing and you don't need that. In fact, your
Please log in to post a comment
Log in with GitHubJoin our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord