Skip to main content

whisker_css/prop/
background.rs

1//! Background longhand properties.
2
3use crate::css::Css;
4use crate::data_type::{Color, LengthPercentage};
5use crate::data_type_ext::Position;
6use crate::keyword::{
7    BackgroundAttachment, BackgroundClip, BackgroundOrigin, BackgroundRepeat, BackgroundSize,
8};
9use crate::value::ImageRef;
10
11impl Css {
12    /// Sets `background-color`. Lynx default: `transparent`.
13    /// <https://lynxjs.org/api/css/properties/background-color>
14    pub fn background_color(self, v: Color) -> Self {
15        self.push("background-color", v)
16    }
17
18    /// Sets `background-image`. Accepts `url(...)` and `<gradient>`.
19    /// `none` clears any existing image.
20    /// <https://lynxjs.org/api/css/properties/background-image>
21    pub fn background_image(self, v: impl Into<ImageRef>) -> Self {
22        self.push("background-image", v.into())
23    }
24
25    /// Sets `background-repeat`.
26    /// <https://lynxjs.org/api/css/properties/background-repeat>
27    pub fn background_repeat(self, v: BackgroundRepeat) -> Self {
28        self.push("background-repeat", v)
29    }
30
31    /// Sets `background-position`.
32    /// <https://lynxjs.org/api/css/properties/background-position>
33    pub fn background_position(self, v: Position) -> Self {
34        self.push("background-position", v)
35    }
36
37    /// Sets `background-position-x` — horizontal component only.
38    /// <https://lynxjs.org/api/css/properties/background-position-x>
39    pub fn background_position_x(self, v: impl Into<LengthPercentage>) -> Self {
40        self.push("background-position-x", v.into())
41    }
42
43    /// Sets `background-position-y` — vertical component only.
44    /// <https://lynxjs.org/api/css/properties/background-position-y>
45    pub fn background_position_y(self, v: impl Into<LengthPercentage>) -> Self {
46        self.push("background-position-y", v.into())
47    }
48
49    /// Sets `background-size`.
50    /// <https://lynxjs.org/api/css/properties/background-size>
51    pub fn background_size(self, v: BackgroundSize) -> Self {
52        self.push("background-size", v)
53    }
54
55    /// Sets `background-origin`. Lynx default: `padding-box`.
56    /// <https://lynxjs.org/api/css/properties/background-origin>
57    pub fn background_origin(self, v: BackgroundOrigin) -> Self {
58        self.push("background-origin", v)
59    }
60
61    /// Sets `background-clip`. Lynx default: `border-box`.
62    /// <https://lynxjs.org/api/css/properties/background-clip>
63    pub fn background_clip(self, v: BackgroundClip) -> Self {
64        self.push("background-clip", v)
65    }
66
67    /// Sets `background-attachment`. Lynx default: `scroll`.
68    /// <https://lynxjs.org/api/css/properties/background-attachment>
69    pub fn background_attachment(self, v: BackgroundAttachment) -> Self {
70        self.push("background-attachment", v)
71    }
72
73    /// Sets `color` — the foreground color used by text and SVG strokes.
74    /// <https://lynxjs.org/api/css/properties/color>
75    pub fn color(self, v: Color) -> Self {
76        self.push("color", v)
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use crate::data_type::{Color, CssString, Gradient, NamedColor};
83    use crate::data_type::{ColorStop, Percentage};
84    use crate::data_type_ext::{Position, PositionKeyword};
85    use crate::ext::*;
86    use crate::keyword::*;
87    use crate::value::ImageRef;
88    use crate::Css;
89
90    #[test]
91    fn background_color() {
92        let s = Css::new().background_color(Color::Named(NamedColor::Black));
93        assert_eq!(s.to_string(), "background-color: black;");
94    }
95
96    #[test]
97    fn foreground_color() {
98        let s = Css::new().color(Color::Named(NamedColor::White));
99        assert_eq!(s.to_string(), "color: white;");
100    }
101
102    #[test]
103    fn background_image_url() {
104        let s = Css::new().background_image(ImageRef::Url(CssString::new("a.png")));
105        assert_eq!(s.to_string(), "background-image: url(\"a.png\");");
106    }
107
108    #[test]
109    fn background_image_gradient() {
110        let g = Gradient::linear_to_bottom([
111            ColorStop::new(NamedColor::Red.into()),
112            ColorStop::new(NamedColor::Blue.into()),
113        ]);
114        let s = Css::new().background_image(g);
115        assert_eq!(
116            s.to_string(),
117            "background-image: linear-gradient(to bottom, red, blue);"
118        );
119    }
120
121    #[test]
122    fn background_image_none() {
123        let s = Css::new().background_image(ImageRef::None);
124        assert_eq!(s.to_string(), "background-image: none;");
125    }
126
127    #[test]
128    fn background_repeat_and_position() {
129        let s = Css::new()
130            .background_repeat(BackgroundRepeat::NoRepeat)
131            .background_position(Position::Keywords(
132                PositionKeyword::Center,
133                PositionKeyword::Top,
134            ));
135        assert_eq!(
136            s.to_string(),
137            "background-repeat: no-repeat; background-position: center top;"
138        );
139    }
140
141    #[test]
142    fn background_position_axis() {
143        let s = Css::new()
144            .background_position_x(px(10))
145            .background_position_y(Percentage(50.0));
146        assert_eq!(
147            s.to_string(),
148            "background-position-x: 10px; background-position-y: 50%;"
149        );
150    }
151
152    #[test]
153    fn background_size_keywords() {
154        let s = Css::new().background_size(BackgroundSize::Cover);
155        assert_eq!(s.to_string(), "background-size: cover;");
156        let s = Css::new().background_size(BackgroundSize::Contain);
157        assert_eq!(s.to_string(), "background-size: contain;");
158        let s = Css::new().background_size(BackgroundSize::Auto);
159        assert_eq!(s.to_string(), "background-size: auto;");
160    }
161
162    #[test]
163    fn background_origin_and_clip() {
164        let s = Css::new()
165            .background_origin(BackgroundOrigin::ContentBox)
166            .background_clip(BackgroundClip::Text);
167        assert_eq!(
168            s.to_string(),
169            "background-origin: content-box; background-clip: text;"
170        );
171    }
172
173    #[test]
174    fn background_attachment() {
175        let s = Css::new().background_attachment(BackgroundAttachment::Fixed);
176        assert_eq!(s.to_string(), "background-attachment: fixed;");
177    }
178}