
Elaine
@elaineleungAll comments
- @dboca93Submitted over 1 year ago@elaineleungPosted over 1 year ago
Hey Dilhan, excellent job here, and it makes me want to go back and clean up some of my old code for this challenge!
The semantic HTML looks pretty clean to me :) In terms of suggestions, one I could think of would probably be just to add a
header
tag even though it can be optional, but it would be nice to have since you got amain
tag with anh1
in there, and I might put thath1
underheader
instead. (By the way, what you did with theh1
was also something I did for a lot of these component challenges... I think that's a good idea too!)One other thing I saw (which was also something I did in my own solution) was putting the stats in
p
tags. If I could do that differently now, I would have the stats as anul
list instead, as that might be easier to pick out for users with a screenreader.Once again, great work!!
Marked as helpful1 - @dhan5aSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Dhanya, first off, I think you did a great job putting this together! About the custom variables not working, it looks like there's a trailing curly brace in line 3 of your CSS file, and I think if you try to remove that, you'd be able to use the variables (I tried it in the browser just now using your code).
Some suggestions I have here: I'd remove the
width: 50%
from the body selector, and if you're hoping to put some space on the sides to prevent the component from touching the browser sides, instead of havingmax-width: 300px
on.card
, you can trywidth: min(90%, 300px)
. This declaration tells the browser to keep the width at 90% until it gets to 300px, at which point the width would be maintained at 300px as the max width.Lastly, about using fixed pixel values in font sizes: It's generally good practice to use relative units (such as rem), so that's something I encourage you to try as well (by default, 1 rem is 16px). One of the main reasons is because relative units allow users to have their own preferred browser/system settings and won't be locked into using fixed sizes in the code.
(Oh, and be sure to fix add alt tags in your
img
elements, otherwise these would show up in your report for sure)Hope this helps you out!
Marked as helpful1 - @DytomaSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Dytoma, this looks like a great start, and I think your code works fine. I do suggest giving your classes and variables more meaning names, where instead of
const rating = document.querySelectorAll(".nbr");
... you can try something like this:
const ratingBtns = document.querySelectorAll(".rating"); // note that Btns stand for buttons since there is more than 1 button here!
For the
for
loop, I suggest usingclassList
instead ofclassName
so that you can easily add or remove a class instead of changing theclassName
attribute directly. I also don't thinkselected
needsquerySelectorAll
since there's only one button being selected. You can try this:for(let i = 0; i < rating.length; i++) { rating[i].addEventListener("click", function() { let selected = document.querySelector(".selected"); selected.classList.remove("selected") this.classList.add("selected"); }); }
Lastly, instead of having a default score of 1, I would just leave it empty and let the user choose. Sometimes users might accidentally click on the submit before they select the score, and you wouldn't want them to accidentally send a score of 1! Hope this helps you out a bit 🙂
1 - @trunglam7Submitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Trung, I think this looks quite well put together! If there's one thing I'd change, I would use a class to change the style of the selected button instead of using the
:focus
pseudo class, seeing that focus is meant to used for showing which element the user had last interacted with. If you accidentally click on something else like the background or the text, the selected button would go back to its unselected color because it has lost the focus, and that would make it seem like no button got selected, even though in the background JS is still keeping track which button got selected. I would just create a new class calledselected
, style the selected button with that class, and then use JS to add/remove the class as needed. Hope this helps you out a bit!Marked as helpful2 - @Owura-56Submitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Agyemang, good job putting this together! For the triangle with the
::after
pseudo element, instead of having justborder: solid transparent
, try specifying the sides, like this:.grid-item-3::after { top: 98%; right: 0; // remove left border-left: solid transparent; border-top: solid white; // rest of your code }
Also, change the border-radius in
.grid-item-3
toborder-radius: 8px 8px 0 8px;
, which should give you that sharp corner instead of a rounded one.With the media query, I'd choose a much higher breakpoint since right now when the layout changes, the sides are cut off. Also, there appears to be some overflow going on, and I think it may have to do with the large margins you're using (such as in
.grid-item-3
) to do positioning. I would actually suggest not having.grid-item-3
as a grid element but to have that as a child of.grid-item-2
instead, and I'd useposition: absolute
instead of using things likemargin-left: 21rem
, which is what I think is causing things to be pushed off to the right side of the screen.Hope this helps you out!
0 - @jodyvanhooseSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Jody, first off, great job in getting your solution to look very close to the design! 🙂 I think you did many things well; for instance, I like how readable and well-annotated your code is. There are just a few things I noticed in the area of responsive design that you can check out:
Breakpoint: The breakpoint is quite large, and you'll notice that the photo in the mobile view gets pixelated past its width of 686px, plus having the mobile view at such a wide width is not very optimal for this card component, as the photo would be gigantic while the lines of text and CTA button gets stretched. What I suggest is to use a smaller breakpoint: to find ideal point, simply see how wide the desktop view is meant to be and use that as a starting point. From what I recall, the design's desktop width should be about 600px.
Image distortion: The image at the desktop view is getting distorted, meaning that the original aspect ratio is being changed. To make sure the image doesn't get stretched or squished, add a
object-fit: cover
to the image class.Component width: Aside from changing the breakpoint, one other thing you can try is to ensure the mobile view card width doesn't get too wide. To do that, instead of just having
width: 93%
, trywidth: min(93%, 400px);
which tells the browser to keep the width at 93% if the width is smaller than 400px (you can use any value here you wish). Likewise, for the desktop view, trywidth: min(93%, 600px);
instead ofwidth: 35%
. Once you do that, you may find that thewidth
property for your desktop image doesn't have to be 25%; in fact, it can be 100% or 50% and still be the same width because you haveflex: 1
as a declaration, and you also have awidth: 50%
for your description container.Hope this can help you out!
Marked as helpful0 - @ahmad-codSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hey Ahmad, well done in building together this solution! To answer your question about why things shift when you click on the dropdown, it's because the dropdown has a
position: relative
. That means that when it appears, its height is part of the header height, and so everything shifts according to that height change.To fix this in the desktop view, simply change the position property in
.dropdown
toposition: absolute
instead and addposition: relative
to your.primary-navigation li
selector, so that the browser knows which parent to anchor.dropdown.
to in the positioning. You may also have to change theleft
andtop
properties as you see fit. I'd also suggest adding awidth: max-content;
to make sure the content takes the whole width and not need to be pushed to the next line. For the mobile view, be sure to keep thatposition: relative
in the.dropdown
when clicked, like how you had it.Hope this helps you out!
Marked as helpful1 - @lily-oliverSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Lily, first off, welcome to Frontend Mentor, and congrats on completing your very first challenge! It's a huge step when you go from tutorials to actually writing your own code, and I must say that for your first challenge, you've done an excellent job!
About your question on centering items, it kind of depends on how you want things to look. Some people want their attribution as a footer pushed all the way to the end of the page, and some people might want it close to their component, which might be somewhere in the center. In your solution, you had your attribution within the component. Each of these cases could have slight variations in how the CSS is written, but regardless what the case is, the key thing that most people tend to forget is the height, which is very crucial because the browser needs to know how much space there is so that it knows where to place the component with even spacing around it. Even when people do remember to add the height, the mistake that most of them make is that they they use
height: 100%
orheight: 100vh
instead ofmin-height: 100vh
.In any case, for the most basic kind of centering where you want everything in the center, here's what you can do:
// centering everything in the middle using flexbox: body { min-height: 100vh; display: flex; flex-direction: column; // this is needed if you have more than one child in the body selector align-items: center; justify-content: center; } // centering everything in the middle using grid: body { min-height: 100vh; display: grid; place-content: center; }
I encourage you to play around with both flexbox and grid so that you understand how they work because I also struggled a lot in the beginning with how to use them for centering things, especially when there are other components involved, like a footer and header.
Anyway, aside from comments on centering, one suggestion I have for your solution is to add a 1rem margin around it so that for smaller browser widths, the sides of the component won't be touching the browser. I really think you did a great job on the whole, and the real challenge will come when you need to work with responsive design (as in building a mobile view and desktop view), but no worries, I think you'll be learning lots when you put your skills to the test!
Marked as helpful2 - @ArthurKingDevSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Kingsley, good job putting this together! 😊 I got a few suggestions for you here:
-
Instead of using
background-image
for handling the switching of the desktop and mobile images, try to use thepicture
element instead since this is a product image and is thus central to the card. Thebackground-image
property is suitable for images that really are background images, usually with some text on top of the image. For the picture element, you can try something like this:<picture> <source media="(max-width: 375px)" srcset="image-mobile.png" /> <img src="image-desktop.png" alt="Glass perfume bottle placed against a leafy background" /> </picture>
-
I suggest a higher breakpoint than 375px. The 1440px desktop view and 375px mobile views are references for you to see how the component should look like that these two views, but they aren't meant to be the max width or breakpoint. As the developer, you'll have to have the judgment to see which point to use so that when the layout changes, the component can still have optimal views.
-
Right now the component isn't so responsive due to fixed widths in certain areas, and as a result, there is content that's being covered by the browser, causing overflow to happen. A big part of this could be the fact that you're using background images right now, but you can also try what I mentioned about changing the breakpoint as well.
-
To make the image width even with the text in the desktop layout, try adding
flex: 1 0 50%;
on theproduct-img
.
Hope some of this can help you out, and really great work on the whole, so keep going!
Marked as helpful0 -
- @debriksSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Great work Deborah! This looks really good, and I think the responsiveness is quite well done. I just got two suggestions:
-
At around the 660px breakpoint when the layout changes, the sides of the component are touching the sides of the browser, so I'd probably just add some spacing to keep that from happening (maybe
margin: 1rem
would be good enough!) -
Your report is giving you some issues about missing alt tags, and actually even for decorative images, you still need the alt tag in the
img
, but you can keep it empty, like this:<img scr="image.png" alt="" >
Once again, well done here, and I'm glad you got improve upon your old solution!
Marked as helpful1 -
- @ajay117Submitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Ajay, well done in building this component! I think there are many things you did well, including making the component responsive, having optimal views, making everything functional with the JS, and having descriptive class names. I found your code to be clean and easy to read, so great job here!
I think the only suggestion I have is that instead of using
li
for the buttons, try to use either a button or radio inputs, as this would have with accessibility since these are control elements and can be used with the tab key, whereas theli
element could not be used with a tab key. Even though you can add make them into focusable control elements, there shouldn't be a need to do that when there are more suitable elements, such asbutton
.Hope this helps and once again, great job!
Marked as helpful1 - @FrozennnSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Marko, I think you did well on the whole! The only three suggestions I have are as follows:
-
The ratings and the testimonials are stretching out quite a bit before the browser width reaches the breakpoint. You can either try a smaller breakpoint, or better yet, use a
max-width
for the cards and ratings. I see that you have a max-width on the ratings but it's in a percentage, which means it will still continue to stretch. What I would suggest is to use a relative unit here, like rem. For starters, trymax-width: 25rem
and then adjust accordingly. -
At desktop view, the site main heading has quite a large line height. I tried changing it via the inspector but I was not able to for some reason. In any case, it would be great if that spacing is a bit smaller!
-
Instead of using the
picture
element for the SVGs, try having them asbackground-image
instead because they are merely functioning as decor elements, and they aren't really there to enhance the site content in any meaningful way.
Hope this could help you out!
Marked as helpful1 -
- @Abdulazeem-codeSubmitted over 2 years ago@elaineleungPosted over 2 years ago
HI Shobiye, it looks like your live site isn't working; the link doesn't appear to be the right one, and when I went to your repo, I don't think the GH pages is properly set up yet. If you need some help with that, check out Matt's post here on how to submit solutions: https://medium.com/frontend-mentor/a-complete-guide-to-submitting-solutions-on-frontend-mentor-ac6384162248
You can also try Vercel, as that's one of the easiest ways to deploy your code.
If you need more help, just let me know by replying to this message!
0 - @krutagna10Submitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Krutagna, first off, great job in making this solution responsive, and I also think you did many things well here, including how you used grid and also relative units instead of pixels.
About your question on good CSS practices, here's a short list on what I consider to be good practices in general:
- Always include reset or normalize rules in your stylesheet to ensure your styles are consistent across different browsers and won't be overridden by the browser's default styles
- A mobile-first approach is better than a desktop-first approach!
- Regarding units, always try to use relative units such as rems and ems instead of pixels, especially for font sizes. Using percentages and viewport units for widths and heights should be taken with caution, as sometimes they might only look optimal for a certain browser width
- It's best to use classes instead of id selectors to avoid specificity issues
- It's important to give meaningful names to your classes, which I think you've done fairly well in your solution!
Hope this helps you out a bit, and great work in general!
Marked as helpful1 - @RahulPaul12Submitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Rahul, your links for the live site and repo don't seem to be working, unfortunately! I managed to find your repo, but I can't access your site as I can't find the Netlify link at all. Hopefully you can fix those first, and then we can see how to give you some feedback!
0 - @David-Henery4Submitted over 2 years ago@elaineleungPosted over 2 years ago
Hi David, well done in building this project in React, which seems to work quite well to me! The only comment I have is that, when the numbers switch to the next time unit (e.g., counting down from the "01" second mark), I think it should be showing zero. For instance, after "01" in the seconds column, I would expect to see "00", but instead I see "60". In short, I suggest that the range should be from 0 to 59, not 1 to 60.
As for other solutions, I really like what Curtis did his solution, and even though it's a plain JS solution and not in React, I think it's still a good reference, so check it out here: https://www.frontendmentor.io/solutions/responsive-countdown-timer-made-using-vanilla-js-sass-3wnMC395Zn
Marked as helpful0 - @HDanielOSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Daniel, good attempt in building this project, and I just wanted to answer your question about
eval()
:I also used
eval()
at first, but after reading up more about it on MDN and reading Stack Overflow posts that explain why it shouldn't be used, I ended up using a switch statement for the four operators. Here's the link to the MDN article oneval()
, and I highly recommend that you read it and consider whether to useeval()
: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/evalAnyway, I tried out your calculator, and I really only got three main comments:
-
I think you need to write a bit more logic in your function for the computation, and I also think you need to have a look at how real-life calculators work (whether they are single-step or expression evaluators). I know there aren't too many specific instructions for this challenge, but I think it should be assumed that this calculator is meant to function in a way that real-life calculators function. What this means is that, let's say I enter "3", "+", and then "5"; I get the answer "8", which is the desirable and correct answer. Then say I wanted to input another number for the next calculation, and that number is "2". What I see on the screen is not "2" but "82" because the display is not cleared and the calculator simply appends the new digit to the previous answer.
-
Good job in getting the themes to work! The only thing is that, how the JS is written is rather clunky and hard to read, as it's a bit too repetitive right now with all the adding and removing of classes. I also don't think this is the most ideal way to write the theme function. I would suggest that you look into how else the themes can be wired up and do try some refactoring and use of
forEach
or afor
loop. -
You have quite a number of issues in your HTML report! Some of involve very fundamental principles being broken, such as
id
being used more than once. I think you'll need to be careful here and try to remember the basics as you're writing your HTML.
In reviewing your work here, I suggest that you try a few more Junior level projects first that involve writing JS before you tackle more intermediate projects, which I think are a bit beyond your level right now. Otherwise you may find those projects quite challenging! Good luck, and keep going 😊
Marked as helpful2 -
- @JoelLHSubmitted over 2 years ago@elaineleungPosted over 2 years ago
Hi Joel, about your question on the API, if you happen to be using Firefox like I am, then there's a caching setting in the browser that causes the next advice to not load right away. To fix that, you just need to add an object in the fetch method, like this:
fetch('https://api.adviceslip.com/advice', { cache: 'no-cache' })
One other suggestion here: You can try to change the
width
tomax-width
in yourquote-card
with a bit of margin around (e.g.,margin: 1rem
), and once you do that, you can try making your breakpoint smaller (e.g., 500px) since the card should be more responsive now.Marked as helpful0