mdgriffith / design-discussion-elm-ui-2

A repo for discussing changes to Elm UI 2
17 stars 0 forks source link

Support for declarative responsive design #20

Open gampleman opened 4 years ago

gampleman commented 4 years ago

So far the recommendation for achieving responsive design has been to subscribe to resizes and use an initial size in Elm. While this works, it has some downsides:

The upside is of course some conceptual simplicity. However I wonder if we could achieve something quite nice with some symbolic operators. We already specify things in Length values, so some things could be specified as special Length values:

viewportWidth |> minus (px 30)

which could be compiled to:

calc(100vw - 30px)

However, I'm not sure this would be useful. However, I think we could also provide some responsive layout primitives:

rowIf (viewportWidth |> greaterThan (px 600)) attrs children

which could be compiled to:

.el23 { flex-direction: column; } 
@media (width > 600px) { .el23 { flex-direction: row; } }  

similarly one could have hiddenIf. These kinds of techniques could also work for responsive text size.

Finally worth noting that this wouldn't remove the previous technique, but for many usecases it could make it unnecessary.

Also see #16 for some further ideas on this.

schoening commented 2 years ago

I quite like the https://chakra-ui.com/docs/features/responsive-styles approach:

<>
  <Box
    height={{
      base: "100%", // 0-48em
      md: "50%", // 48em-80em,
      xl: "25%", // 80em+
    }}
    bg="teal.400"
    width={[
      "100%", // 0-30em
      "50%", // 30em-48em
      "25%", // 48em-62em
      "15%", // 62em+
    ]}
  />
  {/* responsive font size */}
  <Box fontSize={["sm", "md", "lg", "xl"]}>Font Size</Box>
  {/* responsive margin */}
  <Box mt={[2, 4, 6, 8]} width="full" height="24px" bg="tomato" />
  {/* responsive padding */}
  <Box bg="papayawhip" p={[2, 4, 6, 8]}>
    Padding
  </Box>
</>

Every style can be given an object or array and the style that matches the breakpoint size will be used.