About This Web Design Portfolio Jenniina.fi

About the creation of the web design portfolio Jenniina.fi

About This Site jenniina.fi

My Web Design Portfolio

Some points on the making of this website

It is a WordPress site, with the theme Michelle by WebMan Design, as I was impressed by its predecessor Reykjavik’s accessibility.

Development environment

Some of the tools I use

  • Windows 10
  • WordPress 6
  • Local by Flywheel (having issues with speed, might switch back to XAMPP) MAMP
  • VS Code
  • Browsersync
  • WAVE
  • NVDA screen reader
  • Screaming Frog SEO Spider

Jenniina.fi Colors

I chose a warm honey yellow to start with and went with a complementary color scheme, keeping accessibility in mind.

jenniina.fi web design portfolio website colors
Website color artwork to illustrate which colors can or cannot be used together, according to WCAG 2.1 AA-level guidelines. L is for large text (and graphical/UI elements).

What’s with all the collapsibles?

I love collapsible elements

I have a particular love for the details element, as it is semantic HTML that is inherently interactive without any javascript, without being a form element. Also, being able to hide elements from view clears up visual clutter.

Making the Menu

I wanted a main navigation that would pop, and be in a style I had never used before. Since the contents of the menu wouldn’t change, as the page is a web design portfolio, I settled on the current style. I used a CSS grid for the navigation items and rotated the center part 45 degrees, placing the site logo on top of it in its own, identical grid. I used an edge clip to create the point at the bottom.

Making the Site Bilingual

English is the first language I ever spoke, and is still easier to communicate with in some ways, even though I’m completely Finnish. At least writing in English is easier, which is why I’m writing this web design portfolio in English first, before translating (most of) it into Finnish.

For creating the translated version of the site, I ended up choosing the plugin TranslatePress due to time constraints, though every word is still translated by me.

Code

Adding Dark Mode

I took note of Atanas Yonkov’s tutorial on how to implement dark mode. The code I chose to implement is as follows:

<?php
function jla_darkmode_javascript() { ?>
    <script defer>
        jQuery(function($) {
            //Create the cookie object
            var cookieStorage = {
                setCookie: function setCookie(key, value, time, path) {
                    var expires = new Date();
                    expires.setTime(expires.getTime() + time);
                    var pathValue = '';
                    if (typeof path !== 'undefined') {
                        pathValue = 'path=' + path + ';';
                    }
                    document.cookie = key + '=' + value + ';' + pathValue + 'expires=' + expires.toUTCString();
                },
                getCookie: function getCookie(key) {
                    var keyValue = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
                    return keyValue ? keyValue[2] : null;
                },
                removeCookie: function removeCookie(key) {
                    document.cookie = key + '=; Max-Age=0; path=/';
                }
            };
            $('.dlt-button').click(function() {
                //Show either moon or sun
                $('.dlt-button').toggleClass('active');
                //If dark mode is selected
                if ($('.dlt-button').hasClass('active')) {
                    //Add dark mode class to the body
                    $('body').addClass('dark-mode');
                    cookieStorage.setCookie('jlaiNightMode', 'true', 2628000000, '/');
                } else {
                    $('body').removeClass('dark-mode');
                    setTimeout(function() {
                        cookieStorage.removeCookie('jlaiNightMode');
                    }, 100);
                }
            })
            //Check Storage. Display user preference 
            if (cookieStorage.getCookie('jlaiNightMode')) {
                $('body').addClass('dark-mode');
                $('.dlt-button').addClass('active');
            }
        })
    </script>
<?php
}
add_action('wp_head', 'jla_darkmode_javascript');

This is the snippet I used to check whether a link is external to this web design portfolio and to add a class to it for targeted editing. I first used this technique on my conference website. I also added an aria-roledescription so that screenreaders will also read the link as external. The parts commented out are for opening the link in a new window, which I decided against doing on this site.

<?php
add_action('wp_head', function () {
?>
<script defer>
	document.addEventListener("DOMContentLoaded", function() {
        function linkopener(a) {
            //let trgt = a ? "_blank" : "_self";
            let link = document.links;
            for (let i = 0; i < link.length; i++) {
                if (link[i].href.search("localhost:8888/jlai") == -1) {
                    /*  link[i].addEventListener("click", function() {
                        this.target = trgt;
                        });
                        link[i].target = trgt;
                    */
                    link[i].className += 'link-external ';
                    link[i].setAttribute('aria-roledescription', 'external link');
                }
            }
        }; 
		linkopener(true);
	});
</script>
});

Entry Animations

Fade-in and slide-in animations: I used Intersection Observer to check whether elements with the “arrive” class are visible in order to add and remove classes for the animations to run. Mostly only used in the web design portfolio’s front page, but I did the same for images in general. The hide class is set here so that the content isn’t hidden from those without javascript enabled. For this reason I decided against toggle in favor of add and remove.

I also set a custom property here (–i), with a an inceasing value for each instance, to set a transition-delay for the animation with transition-delay: calc(100ms * var(–i));

<?php
add_action('wp_footer', function () { ?>

    <script defer>
        const observer = new IntersectionObserver((entries) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting) {
                    entry.target.classList.remove('unseen');
                    entry.target.classList.add('visible');
                }
            });
        });

        const hiddenElements = document.querySelectorAll('.arrive');
        hiddenElements.forEach((e) => e.classList.add('unseen')); //Is set here so that the content isn't hidden from those without javascript enabled
        hiddenElements.forEach((e, i) =>  e.style.setProperty('--i', i)); //gives an incrementing custom property for each instance, to calculate delay
        hiddenElements.forEach((e) => observer.observe(e));

        const hiddenThumbnails = document.querySelectorAll('.wp-block-image');
        hiddenThumbnails.forEach((e) => e.classList.add('unseen'));
        hiddenThumbnails.forEach((e) => observer.observe(e));
    </script>

<?php });

Comments?

Would you have chosen different methods to achieve the same results? Let me know what you would have done differently for this web design portfolio, I’d love to hear it!

Thank you for reading!
Jenniina