Skip to content

Add flow-relative CSS properties #82

Open

Description

@raquo

Such as:

  • margin-block, margin-block-start, margin-block-end
  • margin-inline, margin-inline-start, margin-inline-end
  • padding-block, padding-block-start, padding-block-end
  • padding-inline, padding-inline-start, padding-inline-end
  • inset
  • inset-block, inset-block-start, inset-block-end
  • inset-inline, inset-inline-start, inset-inline-end
  • etc

For example, margin-block-start is basically equivalent to margin-top except it's aware of flow direction and text direction.

There's more to these than just dimensional props, see this spec – note the TOC on the left, the new values for text-align, the new logical keyword, etc.

cc @Lasering

Activity

  1. raquo commented on Jul 7, 2022

    @raquo
    OwnerAuthor

    Main question is how to encode these props. We could spell out each property like we do for e.g. marginTop, marginBottom, etc. but then the myriad of new props would "pollute" autocomplete.

    Few people use these new props (and actually test their websites to make sure they work with the different text directions), so I'm not sure if that's a good tradeoff. And in general I loathe having to define repetitive props.

    Alternatively, we could make those props nested, such as margin.blockStart or borderColor.inlineEnd. We would also need to add old ones like margin.top for consistency I guess. I don't think I'm ready to completely replace the existing props like marginTop with margin.top, both options might need to co-exist for a while.

  2. Lasering commented on Jul 8, 2022

    @Lasering
    Contributor

    Regarding the logical keyword, I think its best to not include it for now since issue 1 on the spec clearly defines it as unstable.

    I don't see the autocomplete "pollution" as a problem but rather as a feature it helps with the discoverability. But I do understand why it isn't the most good looking option.

    Making the props nested could be a very elegant solution. Here is a very rough idea (does not handle things like border-block-start-width):

    object Setter {
      def instance[T](name: String): Setter[T] = (value: T) => s"$name: $value"
    }
    trait Setter[T] {
      def :=(value: T): String
    }
    
    class TopBottomLeftRight[T](prefix: String) {
      val top: Setter[T] = Setter.instance(s"$prefix-top")
      val bottom: Setter[T] = Setter.instance(s"$prefix-bottom")
      val left: Setter[T] = Setter.instance(s"$prefix-left")
      val right: Setter[T] = Setter.instance(s"$prefix-right")
      
      // (top and bottom, left and right).
      def :=(t: (T, T)): String = s"$prefix: ${t._1} ${t._2}"
      // (top, left and right, bottom).
      def :=(t: (T, T, T)): String = s"$prefix: ${t._1} ${t._2} ${t._3}"
      // (top, right, bottom, left)
      def :=(t: (T, T, T, T)): String = s"$prefix: ${t._1} ${t._2} ${t._3} ${t._4}"
    }
    
    class BlockInline[T](prefix: String) extends Setter[T] {
      override def :=(value: T): String = s"$prefix: $value"
      // (start, end)
      def :=(t: (T, T)): String = s"$prefix: ${t._1} ${t._2}"
      
      val start: Setter[T] = Setter.instance(s"$prefix-start")
      val end: Setter[T] = Setter.instance(s"$prefix-end")
    }
    
    class FourSidesProperty[T](prefix: String) extends TopBottomLeftRight[T](prefix) with Setter[T] {
      override def :=(value: T): String = s"$prefix: $value"
      
      val block: BlockInline[T] = new BlockInline(s"$prefix-block")
      val inline: BlockInline[T] = new BlockInline(s"$prefix-inline")
    }
    
    @main def main(): Unit =
      val margin: FourSidesProperty[Int] = new FourSidesProperty[Int]("margin")
      val padding: FourSidesProperty[Int] = new FourSidesProperty[Int]("padding")
      
      println(margin := 5)
      println(margin := (5, 25, 5))
      println(margin.top := 5)
      println(margin.block := 5)
      println(margin.block.start := 5)
      println(margin.inline.end := 5)
      println(padding.inline.end := 5)
    margin: 5
    margin: 5 25 5
    margin-top: 5
    margin-block: 5
    margin-block-start: 5
    margin-inline-end: 5
    padding-inline-end: 5
    

    Even the documentation could be easily done via interpolation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions