scalacss
scalacss copied to clipboard
Parent method in conditional CSS
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")(
...
)
)
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 " + _)
.
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: _*)
}
@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