Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found

Submitted

Minimalist Portfolio w/ Vue Router

Fraser Watt 1,790

@fraserwat

Desktop design screenshot for the Minimalist portfolio website coding challenge

This is a solution for...

  • HTML
  • CSS
  • JS
3intermediate
View challenge

Design comparison


SolutionDesign

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 🤷‍♂️

Community feedback

@pikapikamart

Posted

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

2

Fraser Watt 1,790

@fraserwat

Posted

@martpika this (and your feedback on my other project) is - as ever! - soo good and thorough! Made a few changes, going to work through the rest this evening

1
Fraser Watt 1,790

@fraserwat

Posted

@martpika Sorted!! Thanks again for the super detailed feedback.

HOME

  • On the aria-current attribute, it seems like this is added automatically by the Vue router. You're right though, having it announced twice is not ideal - I've updated the top left corner icon to have aria-live="off" to stop it getting announced. Thought this would be better than removing from the accessibility tree totally with aria-hidden? What do you think?
  • Re aria-label on nav elements, this makes sense, but what is the rationale behind the best practice here?
  • Re the "focus on new pages" issue, this is a good spot. In the end I did the following in the App.vue file, idk if its done slightly differently in whatever framework you usually use:
  watch: {
    $route() {
      window.scrollTo(0, 0);
      document
        .getElementById("app")
        .firstElementChild.firstElementChild.focus();
    },
  },

This way whenever the app routes to a new page you're resetting the focus to the first element (the logo link to the homepage).

0

@pikapikamart

Posted

@fraserwat Hey, glad to be back in here and great that you are already refactoring some codes!

  • For the website-link aria-current, don't use aria-hidden on the link since that will remove the website-logo link itself. Is there any option in vue where you can "not" apply the aria-current on the website-logo-link? That's a bit weird behavior to be honest.
  • The reason for using aria-label for nav elements is to distinguish them for other nav elements. For example on your site, since there are 2 nav being used, one on the header and one on the footer. Instead of just screen-reader announcing when traversing in a nav element, navigation landmark... for both nav, if you used like:
`<nav aria-label="primary" />
<nav aria-label="footer" />

This will instead read as primary navigation landmark and footer navigation landmark distinguishing what nav is the user is in. You use this as well when you have like a breadcrumbs on the site, breadcrumbs are links that helps user know what section are they are in in a particular page.

services - business-registration - sole-proprietorship

Something like that, and since those are links of the site, you will like:

<nav aria-label="breadcrumbs" />
  • That is great, just tried it right now and navigating inside the footer links the user on the page and focus is set properly. Always have that where you are doing a multi page, because if you don't, screen-reader user can't really navigate on the new page where they are at.
0

Please log in to post a comment

Log in with GitHub
Discord logo

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