Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parent method in conditional CSS #79

Open
malcheg opened this issue Apr 11, 2016 · 3 comments
Open

Parent method in conditional CSS #79

malcheg opened this issue Apr 11, 2016 · 3 comments

Comments

@malcheg
Copy link
Contributor

malcheg commented Apr 11, 2016

Use case: we need to use button hovers on desktop only, so we can detect desktop devices and add class "no-touch" to html tag.
CSS should be:

.no-touch .link:hover {...}

It would be fine, if we had some parent() method for ampersand, e.g.

val link = style(
  ...,
  &.hover.parent(".no-touch")(
    ...
  )
)
@japgolly
Copy link
Owner

I can't remember if there's a way to do this with the existing DSL or not.

If not, the good news is that it will be trivial to add as the underlying mechanics are already in place to support it. It might just need a PR to wire it up with a prepend value.
https://github.com/japgolly/scalacss/blob/master/core/src/main/scala/scalacss/Style.scala#L35-L42

So you'd just want to end up with a value of sel like (".no-touch " + _).

@djneades
Copy link

I wanted this functionality too, and independently re-invented it as an unsafeParent method, very similar to the existing unsafeRoot and unsafeChild methods. I was going to file a new issue, but discovered this one already existed :-)

This is what I came up with, which would be an trivial addition to DslBase:

  /** Enables a parent CSS selector to be added to the style, along the lines of the SASS `parent-selector &` construct.
    *
    * Parent selectors are useful for customizing styles based upon a CSS class added to a parent element (e.g. for language localization, or for browser-specific customization).
    *
    * Use `unsafeParent` like this:
    *
    * {{{
    * val styleWithJaCustomizations = style(
    *   // common styles here ...
    *   unsafeParent(".ja")(
    *     color(pink)
    *   )
    * )
    * }}}
    *
    * This will generate something along the lines of:
    *
    * {{{
    * .Css_Container-styleWithJaCustomizations {
    *   // common styles here ...
    * }
    *
    * .ja .Css_Container-styleWithJaBrowserCustomizations {
    *   color: pink;
    * }
    * }}}
    *
    * @param p The name of the parent CSS selector.
    * @param t The content to be included under the parent selector.
    * @return An [[Style.UnsafeExt]] object that will emit the desired CSS.
    */
  def unsafeParent(p: String)(t: ToStyle*)(implicit c: Compose): Style.UnsafeExt = unsafeExt(p + " " + _)(t: _*)

Until this feature is implemented in DslBase (presumably placed next to unsafeChild), end-users may wish to add a trait like the following to their project, and then extend that rather than scalacss.StyleSheet.Inline:

import scalacss.internal.Compose
import scalacss.internal.DslBase.ToStyle

trait AugmentedStylesheetInline extends scalacss.StyleSheet.Inline {
  import dsl._
  def unsafeParent(p: String)(t: ToStyle*)(implicit c: Compose): Style.UnsafeExt = unsafeExt(p + " " + _)(t: _*)
}

@ioleo
Copy link

ioleo commented Jul 4, 2020

@japgolly What is the status of this? The issue is quite old, perhaps this feature is already implement? If so please point me to the right place. Otherwise, what do you think about including this into the library? I've extended it a bit:

import scalacss.internal.{Compose, StyleA}
import scalacss.internal.DslBase.ToStyle

trait AugmentedStylesheetInline extends scalacss.StyleSheet.Inline {
  import dsl._

    def ancestor(p: StyleA)(t: ToStyle*)(implicit c: Compose): Style.UnsafeExt = unsafeParent(s".${p.htmlClass}")(t: _*)

    def parent(p: StyleA)(t: ToStyle*)(implicit c: Compose): Style.UnsafeExt = unsafeParent(s".${p.htmlClass} >")(t: _*)

    def unsafeParent(p: String)(t: ToStyle*)(implicit c: Compose): Style.UnsafeExt = unsafeExt(p + " " + _)(t: _*)
}

Named it just parent and ancestor as it will fail at compile if given style (css class) is removed. Or maybe by "safe" you mean something more?

In any case, I can make a PR, unless there is a reason you wouldn't want such change introduced?
Cheers

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

No branches or pull requests

4 participants