[Userscript] Vertical Reviews

thought it was something to do with the wk update…another script had broken and was updated… I’ll test on this end more…

hi, great script, always helpful!

could you update it to show in vertical mode in the new extra study mode?

Good idea. I’ve updated the script for this. v2.0.1 now supports extra study mode.


Never seen this script before! Great idea & can’t believe I never thought of that…

@lon this script is great, but the “vertical for short words” and “vertical for random short words” settings don’t seem to work with Reorder Omega enabled (only “always show vertically” works) - might it be an easy fix by you or Kumirei?
If not, no worries! :slight_smile:

Also @Kumirei, when this script is set to “always show vertically”, the Omega “Preset” text gets goes vertical as well, might that have a quick fix?


I’ll have a look at it tomorrow maybe


I imagine the text going vertical is because I apply a style rule tat everything in that part of the webpage needs to go vertical. That’s probably easy to fix.

I would need to investigate why it’s not working with the other options for short words. I don’t use that script, so I can’t guess what would be causing it. Maybe if the script is adding extra words, like I see in the screenshot, I’m counting the length of the word wrong so it never finds a “short” one.

1 Like

@Kumirei sorry for tagging you about this, all fixed so you don’t need to check anything in the end!

@lon Yep, you were right!
I modified the text-orientation CSS to only apply to the span inside the character id instead of anything in it so that it’ll only make the actual word vertical, and also changed the short() function to only take into account letters in that span. I also made it always take up 3 letters of height if vertical so that it’ll jump around a bit less!

Here’s the modified code just in case you want to update the script at some point (I don’t think I’ve broken anything, all seems to still be working :slight_smile:)

Modified code
// ==UserScript==
// @name        WaniKani Vertical
// @version     2.0.2
// @description Display WaniKani reviews with vertical text
// @author      @lonmcgregor
// @copyright   2021, lonm
// @license     MIT
// @namespace   lonm
// @homepageURL https://gist.github.com/LonMcGregor/972f523e601661475fd0600843f8fb55
// @include     https://www.wanikani.com/review/session
// @include     https://www.wanikani.com/extra_study/session*
// ==/UserScript==

function showControls(){
    // Choose between modes
    // Always = show all words vertically
    // Short = Show all short words vertically
    // Random = For short words, offer a 1:2 chance of showing them vertically
    const selector = document.createElement("select");
    selector.id = "lonm-verticaltextmod";
    selector.innerHTML = `<optgroup label="Controls for Vertical Text">
    <option value="always">Always show all reviews vertically</option>
    <option value="short">Show short reviews vertically</option>
    <option value="random">Show random short reviews vertically</option>
    selector.value = getSavedMode();
    selector.addEventListener("input", setSavedMode);

function getSavedMode(){
    // get the saved value. if its not set, default to random
    const storedvalue = localStorage.getItem("lonm-verticaltextmod");
    return storedvalue ? storedvalue : "random";

function setSavedMode(){
    // save the mode and update the page
    const storedvalue = document.querySelector("#lonm-verticaltextmod").value;
    localStorage.setItem("lonm-verticaltextmod", storedvalue);
    if(storedvalue === "always"){
    } else {

function addCss(){
    // Add custom css to the page to support the mod
    const alwaysvertical = `/* for the main page */
    .lonm-alwaysvertical #character {
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 1;
        float: right;
        width: 400px;
        height: 100vh !important;
    .lonm-alwaysvertical #character span {
        writing-mode: vertical-rl;
        text-orientation: upright;

    .lonm-alwaysvertical #information {
        width: calc(100% - 460px);

    .lonm-alwaysvertical #additional-content ul li {
        width: 15%;

    /* for the settings box */
    .lonm-alwaysvertical #reviews footer {
        position: fixed;
        bottom: 0;
        right: unset;
        left: 10px;
        z-index: 0;

    .lonm-alwaysvertical #reviews footer {
        position: fixed;
        bottom: 0;
        right: unset;
        left: 10px;
        z-index: 0;

    footer #lonm-verticaltextmod {
        background-color: #e1e1e1;
        border: none;
        color: #888888;
        width: 40px;
        height: 33px;
        margin-left: 10px;
        border-radius: 3px 3px 0 0;

    footer #lonm-verticaltextmod:focus {
        background-color: unset;
        color: unset;

    /* for random chances */
    body:not(.lonm-alwaysvertical) #character.vocabulary.vertical span {
        writing-mode: vertical-rl;
        text-orientation: upright;
        width: 100%;
        height: 3em;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 12px 0 10px 0;

	/* for extra reviews, to make the title not overlap */
	div#menu-bar-title {
		text-align: left;
		padding-left: 60px;
    const style = document.createElement("style");
    const tn = document.createTextNode(alwaysvertical);

function short(){
    // 3 characters or shorter word
    return document.querySelector("#character").querySelector('span').innerText.length <= 3;

function random(){
    // either we always want it true for short words, or a 1:2 random chance
    return getSavedMode() === "short" | Math.random() <= 0.5;

function chooseOrientation(){
    // When not always on, handle choosing whether to show it or not
    if(short() && random()){
    } else {

// Observe when going to next review item
const VerticalTextMutationObserver = new MutationObserver(chooseOrientation);

function init(){
    if(document.querySelector("#loading") && document.querySelector("#loading").style.display === 'none'){
        VerticalTextMutationObserver.observe(document.querySelector("#character").querySelector('span'), {childList: true, subtree: true, characterData: true});
    } else {
        setTimeout(init, 150);

setTimeout(init, 500);

Thanks for the help!

1 Like

Thanks. Fixes look good, so I merged them into the main script.


this bug started happening and even after a fresh install of firefox, still happening

could you fix it please?

1 Like

I’m having difficulty reproducing the bug. Are you using any other scripts? And what OS/fonts are installed?

1 Like

no fonts installed.

I have these scripts installed, but until days ago all same scripts and vertical was fine.

You have quite a lot - Have you tried running my script without any other scripts active? It might help me debug the problem if we could narrow down exactly which one was causing it.

In the meantime, if you are comfortable editing the script, on line 115 there is a rule that says
height: 3em;
You could try increasing the number, to see if that helps:
height: 4em;

1 Like

I have updated the script with changes to work with the latest wanikani update. Hopefully all should work. Let me know if there are problems.


Thank you, this script is always super nice to have!

1 Like

Thanks a lot for updating. :slight_smile:
Would you mind telling me which part is responsible for the space over and under the vertically aligned text though? I’d like to reduce it a bit as it’s cutting of the answer-input. Even for three characters there seems to be enough space left to reduce it a bit.

I’m not entirely sure what you mean abou it being cut off. Do you have a screenshot?

I got some vocab with two characters showing vertical this morning. Hopefully this explains it a bit better:

Maybe it’s a problem with my monitor size, so I guess you could also just point me to the line/part in the code and I can try myself to adjust a bit.

Thank you, yes, I see the problem. I had set it too high because the little “level up” popups behave different after the update. I’ve updated the script now and this should hopefully fix it and make the height be a bit more consistent.

1 Like