Getting an element's scrollWidth

Hi!

I’m new to Elm and I’m a bit stuck. I am trying to figure out whether a particular DOM element’s text fits into the element or whether it needs to be scrolled. In JavaScript I can compare the element’s clientWidth and the scrollWidth to do that - the clientWidth tells me how wide the element is, the scrollWidth tells me how wide it should be to show all its contents.

In Elm I seem to have 3 values:

  • scene.width
  • element.width
  • viewport.width

Unfortunately neither of these seem to give me the scrollWidth value from JavaScript.

Is there a way to get this value from within Elm?

1 Like

This little program might help illustrate what I’m trying to do:

module Main exposing (…)

import Browser
import Browser.Dom exposing (Element, Error)
import Html exposing (br, button, div, text)
import Html.Attributes exposing (id, style)
import Html.Events exposing (onClick)
import Task

– MAIN

main : Program () MyApp Msg
main =
Browser.element
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
}

– MODEL

type alias MyApp =
{ names : String, width1 : Float, width2 : Float, width3 : Float }

init : () → ( MyApp, Cmd Msg )
init _ =
( { names = “short text”, width1 = 0, width2 = 0, width3 = 0 }
, Browser.Dom.getElement “stop” |> Task.attempt GotElement
)

– UPDATE

type Msg
= SetText String
| GotElement (Result Error Element)

update msg model =
case msg of
SetText n →
( { model | names = n }
, Browser.Dom.getElement “stop” |> Task.attempt GotElement
)

    GotElement (Err err) ->
        ( model, Cmd.none )

    GotElement (Ok element) ->
        ( { model
            | width1 = element.scene.width
            , width2 = element.element.width
            , width3 = element.viewport.width
          }
        , Cmd.none
        )

– VIEW

view s =
div
[ id “stop”
, style “width” “100px”
, style “overflow” “hidden”
, style
“white-space”
“nowrap”
]
[ text s.names
, br
, text (String.fromFloat s.width1)
, br
, text (String.fromFloat s.width2)
, br
, text (String.fromFloat s.width3)
, br
, button [ onClick (SetText “Some much longer text”) ] [ text “update” ]
]

– SUBSCRIPTIONS

subscriptions _ =
Sub.none

None of the values that are shown match the scrollWidth as reported when inspecting the “stop” element in JavaScript.

Your outer container (div) has a fixed width.
Put the text in a div of its own without a fixed width. This inner div will/should collapse to the width of the text.
Give each div an id.
Using Browser.Dom.getElement id you can measure the width of each div.

If the Html package doesn’t play nicely using this approach, try elm-ui.

If you give the inner div a thin border, you can see if it is collapsing to the text as expected.

Hope this helps.

1 Like

Oh nice, that does seem to work indeed, even using the Html package.

Thank you very much!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.