Skip to content
  • Unlock Pro
  • Log in with GitHub
Profile
OverviewSolutions
35
Comments
704

👾 Ekaterine Mitagvaria 👾

@catherineisonlineTbilisi, Georgia7,860 points

Front-end dev passionate about crafting cool websites, open to new challenges, and happy to share something new with my fellow devs. Let’s learn and grow together! 🫰🏻

I’m currently learning...

Mastering the fundamentals of JavaScript

Latest solutions

  • Multi-step form

    #accessibility#react#vite#pure-css

    👾 Ekaterine Mitagvaria 👾•7,860
    Submitted 3 months ago

    The best color choice for title paragraphs (e.g. "Please provide your name, email address, and phone number.") from the provided colors was Gray 500, however, this color choice doesn't pass the accessibility check, as it doesn't have enough contrast - "Background and foreground colors do not have a sufficient contrast ratio.". That's why I had to make it slightly darker on purpose. What are your thoughts about this?


    1 comment
  • Social links profile

    #tailwind-css#accessibility

    👾 Ekaterine Mitagvaria 👾•7,860
    Submitted 6 months ago

    1 comment
  • Blog preview card

    #accessibility#bem

    👾 Ekaterine Mitagvaria 👾•7,860
    Submitted 6 months ago

    1 comment
  • Intro section with dropdown navigation


    👾 Ekaterine Mitagvaria 👾•7,860
    Submitted over 2 years ago

    9 comments
  • News homepage


    👾 Ekaterine Mitagvaria 👾•7,860
    Submitted over 2 years ago

    9 comments
  • Huddle landing page with alternating feature blocks


    👾 Ekaterine Mitagvaria 👾•7,860
    Submitted almost 3 years ago

    6 comments
View more solutions

Latest comments

  • Gil Yorba•60
    @gilzcdng
    Submitted 3 months ago
    What are you most proud of, and what would you do differently next time?

    Most proud of finishing! I would definitely want to change the padding top on my container class to not have to center it in the middle of the page there has to be a better way.

    What challenges did you encounter, and how did you overcome them?

    Figuring out I needed to wrap the image AND text in a container to get the white border behind both of them and then trying to center that in the middle of the page as well.

    What specific areas of your project would you like help with?

    What would be the best way to center the container? I feel like adding a padding top of x px's is not the best way to do it I felt like I tried all of the flex box properties and nothing worked.

    My Frontend Mentor QR Code Solution

    2
    👾 Ekaterine Mitagvaria 👾•7,860
    @catherineisonline
    Posted 3 months ago

    Hello, Gil Yorba, the solution looks neat. You did a great job.

    The white border you are talking about is often referred to as padding, which adds the inner space between the parent and the children inside it. So whenever you see something similar, it most likely means we need to add padding. You can add the same padding to all sides or even target specific ones like top, left, right, or bottom only.

    This adds padding on all sides:
    padding: 1px;
    
    This way, you can target more specifically:
    padding: 1px 2px 3px 1px;
    This means padding: top right bottom left;
    

    The example above, is something you are already using as well and you can actually shorten your solution.

    You have:
    padding: 0px 20px 0px 20px;
    

    You can do:

    padding: 0px 20px;
    

    This means 0px top and bottom, 20px right and left :)

    Regarding the centering, you already got the correct answer, but I will mention it one more time as it's the best solution. Flex can work for any situation where you have a parent and a child.

    Do this on the parent:
    display: flex;
    justify-content: center;  👈 Horizontal alignment
    align-items: center; 👈 Vertical alignment
    

    As an alternative, you can also use a grid and achieve a similar result as long as there are no other things that affect the positions.

    Do this on the parent:
    display: grid;
    place-items: center; 👈 Both horizontal and vertical alignment
    

    As an additional reading or reference for future projects, I definitely recommend that you read this cool article about Flexbox with some really nice visual examples.

    Marked as helpful
  • P
    Kristian Haug•150
    @klhaug
    Submitted 5 months ago
    What are you most proud of, and what would you do differently next time?

    Thinking through the entire structure before I even wrote a single line of code. And also keeping the code pretty clean, not using unnecessary class-names and id's.

    What challenges did you encounter, and how did you overcome them?

    Not having the proper images delivered. I solved it with using the proper one, and then cropping and scaling it with a container and transform.

    What specific areas of your project would you like help with?

    How could I make this card even more accessible?

    Product Preview Card // HTML & CSS

    3
    👾 Ekaterine Mitagvaria 👾•7,860
    @catherineisonline
    Posted 5 months ago

    Hello, Kristian, the solution looks great.

    Here is what I have to share 👇

    1. First, I wonder why you need an extra div around the img tag because it's pretty self-manageable until you plan to add some overlay, for instance.
    2. For the old price, which has a line-through, you can actually use del tag, it would fit here perfectly: <del>$169.99</del>. So you won't need to add extra CSS plus it conveys the semantic meaning of the old price value. You did similar perfectly with <strong>$149.99</strong>.
    3. The cart image in the button doesn't need any alt because technically it's just a decoration. Decoration means that it's just there for the visuals but it doesn't bring any actual importance. If, let's say you had no text there and only an icon and the icon triggered the click, then it would be important. In this case, you can keep it as alt="" but because of this better to add aria-hidden="true" to make sure that screen readers also skip this.
    4. Finally, usually it's better to separate CSS reset into another file but in this scenario, it might not bring a huge difference. Simply, it's always better to separate the concerns.

    Hope any of this helps, nice job 😎

    Marked as helpful
  • P
    NunoJDMachado•150
    @NunoJDMachado
    Submitted 5 months ago
    What are you most proud of, and what would you do differently next time?

    I'm proud of learning how to deploy via vercel using a build script in package.json.

    Next time I would create custom css classes to better match the design colours.

    What challenges did you encounter, and how did you overcome them?

    The deployment with a build script was failing multiple times, but I watched some youtube videos explaining how to do it.

    What specific areas of your project would you like help with?

    I'd like to know whether the use of <address> is appropriate for this case and also if I should have an <ul> and wrap the <a>'s with <li> tags the way I did. It was tricky because then the clickable part of the button was only the <a> portion so I had to set the display to block. Not sure if this is a good practice or if I should just keep it simple with a <div> and <a>'s inside.

    Social links card using tailwindcss

    #tailwind-css
    1
    👾 Ekaterine Mitagvaria 👾•7,860
    @catherineisonline
    Posted 5 months ago

    Hello, there, the solution looks great.

    The address tag isn't very appropriate here it's meant for the type of info that can help us contact the person or organization. This means in this case it could be even socials, not the country. You can read more about it on MDN.

    The ul and li are used as needed, and also are very good for structuring similar lists. And when you have ul, li always needs to be an outer-most tag.

    Finally, it's also fine to make the a tag block so it occupies the entire container, great job!

    What I would change:

    • add to every a tag attribute target="_blank" so it opens up in a new tab.
    • make the quote p tag instead of heading because it's not really a heading
    • make Github profile public so it's easier for people to add feedback to your solutions if you need them. With more complex projects it will be much harder 😬

    Hope this helps, good luck 🔥

    Marked as helpful
  • amgad sameh•150
    @megzzawy
    Submitted 5 months ago
    What are you most proud of, and what would you do differently next time?

    that i manged to do it using react

    What challenges did you encounter, and how did you overcome them?

    a lot of challenges starting from how to fetch the data from an online api ending with how to deploy react app using github pages (i deployed a lot off projects before but i don't know why the react app is very commplicated to deploy) and suddenly the dice icon not working when i deploy it i don't know why and it works perfectly on my local device

    What specific areas of your project would you like help with?

    fetching data using react and deploy the react app

    css grid and some react function

    #tailwind-css#react
    2
    👾 Ekaterine Mitagvaria 👾•7,860
    @catherineisonline
    Posted 5 months ago

    Hello, there, nice solution!

    👉 #1 There are a couple of things I would do a bit differently which might be interesting for you as well.

    Intead of directly calling fetch, I would place it inside a function and use it that way. This will enable you to run this fetch not only during the initial render but also on the button click. Because you need to enable the user to generate the new quote and it wouldn't a good choice to achieve that by making the user reload the page.

    Besides, it's much better to separate things, this makes the code easier to read. Instead of chaining usually it's more recommended to use async/await which is much easier to read. Maybe here it's not so much code but in more complex situations it can help a lot.

    Finally, you are reusing setLoading(false); in the same fetch twice, which is redundant. You can simply move this to the finally block. This block comes at the very end of the chain that will execute no matter the result. So this works great in this scenario.

    As a result, instead of this:

     useEffect(()=> {
            generateRandomNumber();
    
            fetch('https://catfact.ninja/fact')
           .then(response => response.json())
           .then(data => {setQuote(data);
            setLoading(false);
           })
           .catch(error => {console.error('Error:', error);
            setLoading(false);
           });
        }, [])
    

    We would have:

    const fetchQuote = async () => {
            try {
                generateRandomNumber();
                const response = await fetch('https://catfact.ninja/fact');
                if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
                const data = await response.json();
                setQuote(data);
            } catch (error) {
                console.error('Error fetching quote:', error);
            } finally {
                setLoading(false);
            }
        };
        useEffect(() => {
          fetchQuote();
      }, []);
    

    This will also give you a warning in the useEffect dependency array, the [] at the very end. Here we usually pass states that might change eventually and this helps React to understand when to re-render and show the updated state. If we call fetchQuote it will add a warning that you need to add it in order to monitor its change.

    But the thing is that if we pass this function, it will keep re-rendering all the time. Because functions are objects and when component re-renders, it will create a new reference and treated it as a change. A change will make the useEffect re-render the component which result in infinite re-renders.

    To avoid the re-renders and prove React it's always the same function, you can use another hook called useCallback. What it does that it will cache this function, store it in the memory during the first render.Then component might re-render again because we change the state of the quote but it will reuse the same function.

    As as result we have something like this:

    
      const fetchQuote = useCallback(async () => {
        try {
          generateRandomNumber();
          const response = await fetch("https://catfact.ninja/fact");
          if (!response.ok)
            throw new Error(`HTTP error! Status: ${response.status}`);
          const data = await response.json();
          setQuote(data);
        } catch (error) {
          console.error("Error fetching quote:", error);
        } finally {
          setLoading(false);
        }
      }, []);
    
      useEffect(() => {
        fetchQuote();
      }, [fetchQuote]);
    

    As you see, useCallback also has it's dependency array and it works the same way as in useEffect. It will determine whether it should re-create the function but in our case we don't need this. Our function call doesn't depend on any state.

    A good example if we needed something is, let's say an API request that changes depending on the state. Let's say if in the fetch we had additional info on what type of quote we need, like category and we had state category const [category, setCategory] = useState("funny");. And our fetch call is const response = await fetch(https://api.example.com/quotes?category=${category});. Here, if category changes we need to monitor its change and that's why we would need to pass the category to the useCallback dep array.

    We could also add fetch function right inside useEffect and call it there but function will become local to this useEffect and we can't reuse it outside. But we need to call the same function in the dice which generates another random quote.

    This needs to be done here:

    <button className='bg-[#52ffa8] w-14 rounded-full h-14 absolute -bottom-7 grid place-items-center'>
    <img src="../public/icon-dice.svg" alt="" />
    </button>
    

    And to make the function be called we simply add onClick={fetchQuote}

    👉 #2 Semantic-wise, it's also not recommended to omit the text completery in the button/a tags and use only an image. You can add a span and hide the text from the UI using CSS, so when the person who uses screen reader will be notified about the purpose of this button.

    👉 #3 In React you can't use images the way we do in Vanilla JS.

    <img src="../public/pattern-divider-desktop.svg" className='mt-5 mb-5'/>
    

    You will need default import and place the image that way. You would import at the very top first:

    import Divider from "../public/pattern-divider-desktop.svg"

    And then insert it:

    <img src={Divider} className='mt-5 mb-5'/>
    

    Do the same for <img src="../public/icon-dice.svg" alt="" />

    I hope this helps you out in your future projects, good luck 🤞

    Marked as helpful
  • P
    elCris99•240
    @elCris99
    Submitted 5 months ago
    What are you most proud of, and what would you do differently next time?

    Dealing with all the size/font-size changes through the various media queries pushed me to look for different ideas/implementations for my design system. I need to to step up my layout skills, I waste too much time on choosing what to use between flex and grid...

    What challenges did you encounter, and how did you overcome them?

    Sizes, font-sizes and layout changes between the different media queries were the major challange for me.

    What specific areas of your project would you like help with?

    Any suggestion is welcome. Accessibilty tips would help a lot.

    Tech book landing page - HTML & SASS

    #vite#sass/scss
    1
    👾 Ekaterine Mitagvaria 👾•7,860
    @catherineisonline
    Posted 5 months ago

    Hello, nice solution, I have not done this one yet, looks pretty cool!

    I have a couple of suggestions for accessibility that I would make a bit different, it doesn't necessarily need to be like this.

    👉 #1 If you decided to place the footer outside, I would also place the header away from the hero as the header doesn't really belong there, I think, and can cause confusion structure-wise. We also need to use header tag.

    <header class="hero__header">
    <div class="logo-container">
    <img src="/assets/images/logo.svg" alt="Tech Book Club logo">
    </div>
    </header>
    
    

    I don't see the need for an extra div around the image because the image is already standalone and can easily be styled without any external controller container.

    Besides, if the image is the company logo, I wouldn't rely on only alt text. It's better to add actual text e.g. <h1 class="visually-hidden">Tech Book Club</h1> and hide it with CSS. It will be hidden from UI but the screen reader will understand it.

    👉 #2 Section tags always need text that describes them but sometimes we might not have a heading right under the section like in your scenario due to styling reasons <section class="hero"> Because the screen reader would need to announce the section content the way it makes sense. You can use aria-labelledby and add an id of the heading somewhere below.

    We can use

    <h1 class="heading-1 margin-block-end-6">Join the ultimate tech book club</h1>
    
    

    So it would be :

    <section class="hero" aria-labelledby="hero-title">
    ....
    <h1 id="hero-title" class="heading-1 margin-block-end-6">Join the ultimate tech book club</h1>
    
    

    Considering that we already added h1 to the structure, we usually use only one h1 heading, so the next one shall be h2 (which can be repeated compared to h1).

    <h2 id="hero-title" class="heading-1 margin-block-end-6">Join the ultimate tech book club</h2>
    
    

    This applies to other sections you have. If the heading isn’t a direct child of the section, we need to attach the heading if it’s deeply nested.

    So we need to improve

    <section class="section community">
    
    
    <section class="section journey">
    
    <section
    id="membership-tiers"
    class="section membership">
    
    

    👉 #3 Images don’t need any alt text if they are decorative. Non-decorative would be an arrow in the button where there is no text and the arrow itself triggers the action or an image that describes the scenario present in the text around it which is important. If it’s just decorative you can keep the alt tag empty but also add aria-hidden="true” so the screen reader skips it.

    Examples of the decorative in this case will be:

      <img
    src="/assets/images/icon-arrow-down.svg"
    alt=""
    aria-hidden="true"
                    />
    
    
     <img
    src="/assets/images/image-avatars.webp"
    alt=""
    aria-hidden="true" />
    

    And once again, you don’t need the extra divs around the images until you need some extra styling. If you need a colored overlay then yes, you can do something with div and make it wrap the image.

    👉 #4 It’s always much better to use semantic tags instead of div, especially when it’s something important. For testimonials, you can also use blockquote and add a footer for the author:

    <blockquote>
     <p>"This book club transformed my technical reading from a solitary activity into an enriching community experience. The discussions are gold!"</p>
     <footer>
     <p><strong>Sarah Chen</strong>, Software Architect</p>
     </footer>
    </blockquote>
    
    

    All this has no semantic meaning but in reality, we do want this text to be important because it’s a testimonial!

    👉 #5 Add labels or hidden text to buttons/a tags when there is no text and the image instead.

    <a href="#">
    <img
    src="/assets/images/logo-bluesky.svg"
    alt="Bluesky social media logo"
    /></a>
    
    

    This would be read something like “Bluesky social media logo, link” which isn’t very clear so you could add a label to describe the link and maybe even make the image decorative in this case.

    <a href="#" aria-label="Bluesky Social Media">
      <img src="/assets/images/logo-bluesky.svg" alt="" aria-hidden=“true”>
    </a>
    

    so this should become something like “Bluesky Social Media, link”.

    Finally, some things can be a preference and done differently, there isn't always one rule for everything. Also depends on the target audience. Even modern tags are not supported on older browsers if by chance you have a visitor with an ancient browser you can add roles but for such projects this is extra.

    There is much more that can be changed but I hope these small changes help you out 😁 🔥

    Marked as helpful
  • Fares Ali Raafat•30
    @faressali74
    Submitted 5 months ago
    What are you most proud of, and what would you do differently next time?

    it didn't take much time and i didn't ask help from any person

    What challenges did you encounter, and how did you overcome them?

    the centering of container

    What specific areas of your project would you like help with?

    security

    a social-links-profile using html and css

    1
    👾 Ekaterine Mitagvaria 👾•7,860
    @catherineisonline
    Posted 5 months ago

    Hello, the solution looks great! For more security, you can add to each <a> tag, rel="noopener noreferrer". This is especially a must when we use target="_blank" which opens a new tab.

    A new tab without those two can get access to information on the website we came from (our website in this scenario).

    Without the noopener, the new tab can get access to your document and modify it. In other words, the malicious tab could create a fake version of your website, for instance, a fake login.

    Without noreferrer, the new tab knows where the person came from. This can be bad if you have for example a link that is for internal use, or some hidden pages or even tracking the target audience for marketing by showing where they came from and what they were reading about.

    Marked as helpful
View more comments

Stay up to datewith new challenges, featured solutions, selected articles, and our latest news

Frontend Mentor

  • Unlock Pro
  • Contact us
  • FAQs
  • Become a partner

Explore

  • Learning paths
  • Challenges
  • Solutions
  • Articles

Community

  • Discord
  • Guidelines

For companies

  • Hire developers
  • Train developers
© Frontend Mentor 2019 - 2025
  • Terms
  • Cookie Policy
  • Privacy Policy
  • License

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Mentor of the Week - 1st Place

This badge is awarded to the top placed community member on the weekly Wall of Fame.

Mentor of the Month - 3rd Place

This badge is awarded to the 3rd placed community member on the monthly Wall of Fame.

Fun fact

An abacus is an ancient calculating tool. These days we would typically use a calculator or computer but the abacus is where it all started!

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub