Skip to content
  • Unlock Pro
  • Log in with GitHub
Solution
Submitted over 3 years ago

Minimalist Portfolio w/ Vue Router

Fraser Watt•1,790
@fraserwat
A solution to the Minimalist portfolio website challenge
View live sitePreview (opens in new tab)View codeCode (opens in new tab)

Solution retrospective


This was a tough one!! 😄

Tricky parts were getting the borders working at different page widths, and getting the Vue CLI to properly access the correct images in the public directory for the portfolio/inner pages. As the project pages are the same page with data and images populated with a query, I was trying to autogenerate the img urls with a method. This worked locally but caused havoc when deployed into production 😫

In the end I put the image paths in the JSON file alongside the rest of the info on the page and it worked fine.

This project was good to get the hang of more complex routing. As ever, any way I could have improved on this v much appreciated 👍😎

says there's an accessibility issue on one of the buttons, but ive got it aria-labelled with a title how the documentation says it should be so should be fine 🤷‍♂️

Code
Couldn’t fetch repository

Please log in to post a comment

Log in with GitHub

Community feedback

  • Raymart Pamplona•16,040
    @pikapikamart
    Posted over 3 years ago

    Hey, awesome work on this one. Just viewed the different links and everything looks great. Desktop layout looks great, there is just a horizontal scrollbar at the bottom, (suspecting a width: 100vw usage in here), the site is responsive as well and the mobile state looks really great.

    Don't know if I could check other links as well but here are some: HOME

    • On your footer remove the width: 100vw since this will create the horizontal scrollbar. 100vw doesn't respect the size of the vertical scrollbar on the right side. You can think of it by:
    100vw === 100% of the screen
    vertical scrollbar on the right side === 16px ish?
    

    So 100vw plus the scrollbar size exceeds the total width of the screen, creating extra space for horizontal scroll.

    • I don't know if aria-current is needed on the website-logo link since there is the home link already. User will get 2 announcement if they are on the homepage when traversing both link.
    • Website-logo-link a tag should have either aria-label attribute or sr-only text inside, that describes where the link would take the user. Since this takes user to homepage, use homepage as the text-value.
    • For the website-logo img, I don't know a suitable text for this one though when it comes to portfolio with logo :> but still, logo word as well is not suitable for describing image since this will just announce " logo graphic" and it will be ambiguous for the user. Maybe more valid text.
    • Usage of id in styling is not advisable, though I only found it on your hamburger toggle.
    • For the header navbar, use aria-label="primary" on this and on the footer use aria-label="footer" , use it on the nav tag.
    • The 3 navlinks could have been wrapped inside a ul since they are "list" of links.
    • For the hero-section about me you should've not used button with a tag since this will just create extra navigation when using keyboard. Use only a tag in here with the arrow-icon on the left side as a ::before or ::after of the a tag.
    • Also, you don't use aria-label attribute on img tag, you use them for interactive elements like button, a tag and other that does need a text inside them to give meaning on the element.
    • Changing section tags into just using div on this since section by itself is not informative when navigated as landmark unless they are labelled by aria-labelledby pointing to like a heading tag inside the section.
    • go to portfolio should be using an a tag since it is a link. When a component directs user to a new page, always use a tag because button are for controls.
    • contact me should be using a link as well since it directs user.
    • When using client-side-navigation, always make sure that the next focus after the user navigates to the new page will be on the top of that current page. For example, you using keyboard and go the portfolio on the footer tag then select it as well using keyboard. It navigates the user properly, but, try using the tab key again, the focus goes to the next link after the portfolio which is the contact me.

    So a good approach would be use something like, when the user navigates on the next page, make the body tag have like tabindex="-1" for a moment then transfer the focus on the body tag so that the focus after toggling the footer-links won't stay at the bottom. Maybe creating a function that will run on first load for every link, the function will make sure that the focus is on the body tag of the current-link. Then maybe after like a second, remove the tabindex, a setTimeout would be great.

    FOOTER

    • Use <nav aria-label="footer">.../<nav> so that it will be unique.

    PORTFOLIO

    • It would be better to use h2 on the Manage project title and use a sr-only h1 inside the main tag. You could use something like:
    <main>
      <h1 class="sr-only"> Alex Spencer Projects </h1>
      .....
    </main>
    

    This way it will suit more.

    • View Project should be link as well since they directs user in another page.
    • Adding a more visual on the :focus-visible state of each view project. Right now, if you navigate on them using keyboard, it is hard to see where you are at.
    • Also for me, I would something like screen-reader span between the "view" and "project" text because for example, using screen-reader and navigating different links, I would just get view project multiple times since all links have the same name. I would use something like:
    <a href="/projects?project=manage">
     View
      <span class="sr-only"> Manage </span>
    Project
    </a>
    

    This way, I would know what project am I going into without checking the heading tags at first if just skimming.

    CONTACT ME

    • On each input, it would be better to use the for attribute of the label to point with their respective input so that the label text could be clicked as well in order to type in the input-field instead of using aria-labelledby.
    • Also, you don't use aria-live for each of the input tags. Use only a single aria-live maybe a p tag inside the form which will handle all different event that will occur. For example, the name and email field are incorrect, you will just change the single-aria-live-text to like:
    <p aria-live="polite"> Name field incorrect! Email field incorrect!
    
    • When submitting a wrong form, you use the aria-invalid on the label tag which should be on the input tag. Also, a proper way of linking the error-messages would look like:
    if ( input is wrong )
      input.setAttribute("aria-invalid", "true");
      input.setAttribute("aria-describedBy", id of the error-message);
    else 
      input.removeAttribute("aria-invalid");
      input.removeAttribute("aria-describedBy");
    

    The error-message element should have an id attribute which is referenced by the aria-describedBy attribute on the input element. By doing that, your user will know that the input is wrong because of aria-invalid and they will know what kind of error they made because of the aria-describedBy.

    • Submitting a correct form, it would be great to have something like a success message and you can change the aria-live element to announce something like form successfully submitted so that the user will be informed right away.

    MOBILE

    • Use aria-expanded attribute on the button to inform a user that it has expanded/shown something.
    • Use position: fixed on the nav when activating the toggle so that it won't create short horizontal scroll. Try toggling the hamburger at the moment and you can see that it creates a scroll at the bottom.

    For now, those only. Again, really nice work on this one.

    Marked as helpful

Join 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

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

Oops! 😬

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

Log in with GitHub

How does the accessibility report work?

When a solution is submitted, we use axe-core to run an automated audit of your code.

This picks out common accessibility issues like not using semantic HTML and not having proper heading hierarchies, among others.

This automated audit is fairly surface level, so we encourage to you review the project and code in more detail with accessibility best practices in mind.

How does the CSS report work?

When a solution is submitted, we use stylelint to run an automated check on the CSS code.

We've added some of our own linting rules based on recommended best practices. These rules are prefixed with frontend-mentor/ which you'll see at the top of each issue in the report.

The report will audit all CSS, SCSS and Less files in your repository.

How does the HTML validation report work?

When a solution is submitted, we use html-validate to run an automated check on the HTML code.

The report picks out common HTML issues such as not using headings within section elements and incorrect nesting of elements, among others.

Note that the report can pick up “invalid” attributes, which some frameworks automatically add to the HTML. These attributes are crucial for how the frameworks function, although they’re technically not valid HTML. As such, some projects can show up with many HTML validation errors, which are benign and are a necessary part of the framework.

How does the JavaScript validation report work?

When a solution is submitted, we use eslint to run an automated check on the JavaScript code.

The report picks out common JavaScript issues such as not using semicolons and using var instead of let or const, among others.

The report will audit all JS and JSX files in your repository. We currently do not support Typescript or other frontend frameworks.

Oops! 😬

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

Log in with GitHub