How to overwrite --bottom-inset in Anki Mobile?

I want to place an element at the bottom of a card using this code:

.testElement {
  position: absolute;
  bottom: 0px;
}

It works in Anki Desktop, but in Anki Mobile the element doesn’t go all the way to the bottom:

This is because there is a 114px bottom-inset, which is set by the --bottom-inset variable inside the html tag:

<html class="iphone ios mobile" style="--top-inset: 0px; --bottom-inset: 114px;">

I tried overwriting the variable and changing the inset directly to 0px, but it has no effect:

:root {
    --bottom-inset: 0px !important;
    inset: 0px !important;
}

Even though the values are updated, the inset is still there. Is there a way to get rid of the inset?

I have no IOS, so I can’t tinker around. An idea would be, to change the styling by JavaScript when the document reached the “interactive” or “completed” readyState.

Like that:

function SetBottomInset()
   {
   if (document.readyState === 'completed')
      {
      document.querySelector('iphone ios mobile').style.--bottom.inset = '0px';
      }
   else
      {
         setTimeout(SetBottomInset, 99)
      }
}

Maybe also this here can help: Always bottom margin when using custom css for card

Thanks for your help, but that didn’t work. --bottom-inset gets overwritten, but the inset still remains. This is my script:

var htmlElement = document.querySelector(".iphone.ios.mobile")
  var testElement = document.getElementById("testID")
  testElement.innerHTML = "Initial values: <br/>" +
    "--bottom-inset = " + getComputedStyle(htmlElement).getPropertyValue("--bottom-inset") + "<br/>" +
    "html.inset = " + getComputedStyle(htmlElement).getPropertyValue("inset") + "<br/><br/>"

  function SetBottomInset() {
    if (document.readyState === "complete") {
      htmlElement.style.setProperty("--bottom.inset", "0px");
      // For testing purposes
      htmlElement.style.setProperty("background", "red");

      testElement.innerHTML = testElement.innerHTML +
        "Updated values: <br/>" +
        "--bottom-inset = " + getComputedStyle(htmlElement).getPropertyValue("--bottom-inset") + "<br/>" +
        "html.inset = " + getComputedStyle(htmlElement).getPropertyValue("inset")
    }
    else {
      setTimeout(SetBottomInset(), 99)
    }
  }
  SetBottomInset()

And this is the result:

For those who are interested, here is the full html code of the card as it is rendered in Anki Mobile:

Summary
<html class="iphone ios mobile" style="--top-inset: 0px; --bottom-inset: 0px;">
<head>
  <meta name="viewport" id="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=10,user-scalable=1">
  <link type="text/css" rel="stylesheet" href="res/web/css/reviewer.css">
  <script src="res/web/js/vendor/jquery.min.js"></script>
  <script type="text/javascript" src="res/web/js/mathjax.js"></script>
  <script type="text/javascript" src="res/web/js/vendor/mathjax/tex-chtml.js"></script>
  <script src="/_anki/js/vendor/mathjax/input/tex/extensions/noerrors.js" charset="UTF-8"></script>
  <script src="/_anki/js/vendor/mathjax/input/tex/extensions/mathtools.js" charset="UTF-8"></script>
  <script src="/_anki/js/vendor/mathjax/input/tex/extensions/mhchem.js" charset="UTF-8"></script>
  <style>
    .missing-media {
      background: white;
      color: black;
      border: 1px solid grey;
      border-radius: 5px;
      padding: 0.5em;
      margin-top: 2em;
      font-size: 14px;
      display: none;
    }

    li {
      text-align: start;
    }

    pre {
      text-align: left;
    }
  </style>
  <style type="text/css">
    .CtxtMenu_InfoClose {
      top: .2em;
      right: .2em;
    }

    .CtxtMenu_InfoContent {
      overflow: auto;
      text-align: left;
      font-size: 80%;
      padding: .4em .6em;
      border: 1px inset;
      margin: 1em 0px;
      max-height: 20em;
      max-width: 30em;
      background-color: #EEEEEE;
      white-space: normal;
    }

    .CtxtMenu_Info.CtxtMenu_MousePost {
      outline: none;
    }

    .CtxtMenu_Info {
      position: fixed;
      left: 50%;
      width: auto;
      text-align: center;
      border: 3px outset;
      padding: 1em 2em;
      background-color: #DDDDDD;
      color: black;
      cursor: default;
      font-family: message-box;
      font-size: 120%;
      font-style: normal;
      text-indent: 0;
      text-transform: none;
      line-height: normal;
      letter-spacing: normal;
      word-spacing: normal;
      word-wrap: normal;
      white-space: nowrap;
      float: none;
      z-index: 201;
      border-radius: 15px;
      /* Opera 10.5 and IE9 */
      -webkit-border-radius: 15px;
      /* Safari and Chrome */
      -moz-border-radius: 15px;
      /* Firefox */
      -khtml-border-radius: 15px;
      /* Konqueror */
      box-shadow: 0px 10px 20px #808080;
      /* Opera 10.5 and IE9 */
      -webkit-box-shadow: 0px 10px 20px #808080;
      /* Safari 3 & Chrome */
      -moz-box-shadow: 0px 10px 20px #808080;
      /* Forefox 3.5 */
      -khtml-box-shadow: 0px 10px 20px #808080;
      /* Konqueror */
      filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color="gray", Positive="true");
      /* IE */
    }
  </style>
  <style type="text/css">
    .CtxtMenu_MenuClose {
      position: absolute;
      cursor: pointer;
      display: inline-block;
      border: 2px solid #AAA;
      border-radius: 18px;
      -webkit-border-radius: 18px;
      /* Safari and Chrome */
      -moz-border-radius: 18px;
      /* Firefox */
      -khtml-border-radius: 18px;
      /* Konqueror */
      font-family: "Courier New", Courier;
      font-size: 24px;
      color: #F0F0F0
    }

    .CtxtMenu_MenuClose span {
      display: block;
      background-color: #AAA;
      border: 1.5px solid;
      border-radius: 18px;
      -webkit-border-radius: 18px;
      /* Safari and Chrome */
      -moz-border-radius: 18px;
      /* Firefox */
      -khtml-border-radius: 18px;
      /* Konqueror */
      line-height: 0;
      padding: 8px 0 6px
        /* may need to be browser-specific */
    }

    .CtxtMenu_MenuClose:hover {
      color: white !important;
      border: 2px solid #CCC !important
    }

    .CtxtMenu_MenuClose:hover span {
      background-color: #CCC !important
    }

    .CtxtMenu_MenuClose:hover:focus {
      outline: none
    }
  </style>
  <style type="text/css">
    .CtxtMenu_Menu {
      position: absolute;
      background-color: white;
      color: black;
      width: auto;
      padding: 5px 0px;
      border: 1px solid #CCCCCC;
      margin: 0;
      cursor: default;
      font: menu;
      text-align: left;
      text-indent: 0;
      text-transform: none;
      line-height: normal;
      letter-spacing: normal;
      word-spacing: normal;
      word-wrap: normal;
      white-space: nowrap;
      float: none;
      z-index: 201;
      border-radius: 5px;
      /* Opera 10.5 and IE9 */
      -webkit-border-radius: 5px;
      /* Safari and Chrome */
      -moz-border-radius: 5px;
      /* Firefox */
      -khtml-border-radius: 5px;
      /* Konqueror */
      box-shadow: 0px 10px 20px #808080;
      /* Opera 10.5 and IE9 */
      -webkit-box-shadow: 0px 10px 20px #808080;
      /* Safari 3 & Chrome */
      -moz-box-shadow: 0px 10px 20px #808080;
      /* Forefox 3.5 */
      -khtml-box-shadow: 0px 10px 20px #808080;
      /* Konqueror */
    }

    .CtxtMenu_MenuItem {
      padding: 1px 2em;
      background: transparent;
    }

    .CtxtMenu_MenuArrow {
      position: absolute;
      right: .5em;
      padding-top: .25em;
      color: #666666;
      font-family: null;
      font-size: .75em
    }

    .CtxtMenu_MenuActive .CtxtMenu_MenuArrow {
      color: white
    }

    .CtxtMenu_MenuArrow.CtxtMenu_RTL {
      left: .5em;
      right: auto
    }

    .CtxtMenu_MenuCheck {
      position: absolute;
      left: .7em;
      font-family: null
    }

    .CtxtMenu_MenuCheck.CtxtMenu_RTL {
      right: .7em;
      left: auto
    }

    .CtxtMenu_MenuRadioCheck {
      position: absolute;
      left: .7em;
    }

    .CtxtMenu_MenuRadioCheck.CtxtMenu_RTL {
      right: .7em;
      left: auto
    }

    .CtxtMenu_MenuInputBox {
      padding-left: 1em;
      right: .5em;
      color: #666666;
      font-family: null;
    }

    .CtxtMenu_MenuInputBox.CtxtMenu_RTL {
      left: .1em;
    }

    .CtxtMenu_MenuComboBox {
      left: .1em;
      padding-bottom: .5em;
    }

    .CtxtMenu_MenuSlider {
      left: .1em;
    }

    .CtxtMenu_SliderValue {
      position: absolute;
      right: .1em;
      padding-top: .25em;
      color: #333333;
      font-size: .75em
    }

    .CtxtMenu_SliderBar {
      outline: none;
      background: #d3d3d3
    }

    .CtxtMenu_MenuLabel {
      padding: 1px 2em 3px 1.33em;
      font-style: italic
    }

    .CtxtMenu_MenuRule {
      border-top: 1px solid #DDDDDD;
      margin: 4px 3px;
    }

    .CtxtMenu_MenuDisabled {
      color: GrayText
    }

    .CtxtMenu_MenuActive {
      background-color: #606872;
      color: white;
    }

    .CtxtMenu_MenuDisabled:focus {
      background-color: #E8E8E8
    }

    .CtxtMenu_MenuLabel:focus {
      background-color: #E8E8E8
    }

    .CtxtMenu_ContextMenu:focus {
      outline: none
    }

    .CtxtMenu_ContextMenu .CtxtMenu_MenuItem:focus {
      outline: none
    }

    .CtxtMenu_SelectionMenu {
      position: relative;
      float: left;
      border-bottom: none;
      -webkit-box-shadow: none;
      -webkit-border-radius: 0px;
    }

    .CtxtMenu_SelectionItem {
      padding-right: 1em;
    }

    .CtxtMenu_Selection {
      right: 40%;
      width: 50%;
    }

    .CtxtMenu_SelectionBox {
      padding: 0em;
      max-height: 20em;
      max-width: none;
      background-color: #FFFFFF;
    }

    .CtxtMenu_SelectionDivider {
      clear: both;
      border-top: 2px solid #000000;
    }

    .CtxtMenu_Menu .CtxtMenu_MenuClose {
      top: -10px;
      left: -10px
    }
  </style>
</head>

<body class="card card1 ">
  <div id="qa" style="opacity: 0;">
    <style>
      @import url("__closet-0.6.1.css");
      @import url("_editor_button_styles.css");

      .card {
        font-family: arial;
        font-size: 20px;
        text-align: left;
        color: black;
        background-color: white;
      }

      .card, #qa {
        transform: none;
      }

      body {
        margin: 0px;
        padding: 0px;
      }

      .testElement {
        position: absolute;
        bottom: 0px;
      }
    </style>Text Text Text

    <div style="background: green; color: white; width: 100%; height: 100px; font-size: 10px;" class="testElement"
      id="testID">Initial values: <br>--bottom-inset = 114px<br>html.inset = auto<br><br>Updated values:
      <br>--bottom-inset = 0px<br>html.inset = auto</div>
    <script>
      var htmlElement = document.querySelector(".iphone.ios.mobile")
      var testElement = document.getElementById("testID")
      testElement.innerHTML = "Initial values: <br/>" +
        "--bottom-inset = " + getComputedStyle(htmlElement).getPropertyValue("--bottom-inset") + "<br/>" +
        "html.inset = " + getComputedStyle(htmlElement).getPropertyValue("inset") + "<br/><br/>"

      function SetBottomInset() {
        if (document.readyState === "complete") {
          htmlElement.style.setProperty("--bottom-inset", "0px");
          // For testing purposes
          //htmlElement.style.setProperty("background", "red");

          testElement.innerHTML = testElement.innerHTML +
            "Updated values: <br/>" +
            "--bottom-inset = " + getComputedStyle(htmlElement).getPropertyValue("--bottom-inset") + "<br/>" +
            "html.inset = " + getComputedStyle(htmlElement).getPropertyValue("inset")
        }
        else {
          setTimeout(SetBottomInset(), 99)
        }
      }
      SetBottomInset()
    </script>
    <script>
      var htmlContent = document.documentElement.outerHTML
      var container = document.getElementById('htmlCodeContainer')
      container.textContent = htmlContent
    </script>
    <div id="htmlCodeContainer" style="
 font-size: small;
 white-space: pre;
 overflow-x: auto;
 background: #f9f9f9;
 border: 1px solid #ddd;
 margin-top: 20px;
 padding: 10px;">
    </div>
  </div>
  <div class="missing-media" style="display: none;">
    <div></div>
    <div>
      <a href="https://docs.ankimobile.net/syncing.html#missing-images">More Info</a>
    </div>
  </div>

  <script src="res/web/js/reviewer.js"></script>
  <script src="res/web/js/reviewer_extras_bundle.js"></script>
  <script>anki.addBrowserClasses();</script>


  <script>
    const bridgeCommand = function (msg) {
      try {
        webkit.messageHandlers.bridgeCommand.postMessage(msg);
      } catch (err) {
        console.log(`error sending message: ${err}`);
      }
    }
  </script>
</body>
</html>
1 Like

The solution in that post was to enable “Minimalist mode”, but that’s not available on iOS.

1 Like

The webview extends to the bounds of the screen, and has insets and margins applied so that content at the start/end is not displayed under the top and bottom bars. When manually positioning, you’ll need to account for those bars in your calc()ulations.