schultek / jaspr

Modern web framework for building websites in Dart. Supports SPAs, SSR and SSG.
https://jasprpad.schultek.de
MIT License
1.14k stars 68 forks source link

Responsive web support #82

Closed mjablecnik closed 1 year ago

mjablecnik commented 1 year ago

I think about how to support creating web responsive pages in Jaspr. I realized that we didn't implement @media rules:

@media screen and (max-width: 900px) and (min-width: 600px), (min-width: 1100px) {
  div.example {
    font-size: 50px;
    padding: 50px;
    border: 8px solid black;
    background: yellow;
  }
}

Which are important for responsive web pages. Media rules can be only in CSS files or <style> tags. It is not possible to put it inline.

So probably we will need to add new special type of rule: MediaRule which will take @media parameters and add it into <style> element where every styles rule will describe styles for various size of app (phone, tablet, desktop, etc.):

class ExampleApp extends StatelessComponent {

    @override
    Iterable<Component> build(BuildContext context) sync* {

        yield Container(
            classes: ['test1'], 
            child: Text('Hello world'),
        );

        yield Container(
            classes: ['test2'], 
            child: Text('Hello world123'),
        );

        yield Style(rules: [
            MediaRule(
                maxWidth: 640.px, 
                rules: [
                    StyleRule(
                        selector: Selector.className('test1'), 
                        styles: Styles.combine([
                            Styles.text(color: Colors.red),
                            Styles.background(color: Colors.blue),
                            Styles.box(display: Display.block),
                        ]),
                    ),
                    StyleRule(
                        selector: Selector.className('test2'), 
                        styles: Styles.box(display: Display.none),
                    ),
                ],
            ),
            MediaRule(
                minWidth: 640.px, 
                maxWidth: 860.px, 
                rules: [
                    StyleRule(
                        selector: Selector.className('test1'), 
                        styles: Styles.combine([
                            Styles.text(color: Colors.orange),
                            Styles.background(color: Colors.green),
                            Styles.box(display: Display.block),
                        ]),
                    ),
                    StyleRule(
                        selector: Selector.className('test2'), 
                        styles: Styles.box(display: Display.none),
                    ),
                ],
            ),
            MediaRule(
                minWidth: 860.px, 
                maxWidth: 1960.px, 
                rules: [
                    StyleRule(
                        selector: Selector.className('test1'), 
                        styles: Styles.box(display: Display.none),
                    ),
                    StyleRule(
                        selector: Selector.className('test2'), 
                        styles: Styles.combine([
                            Styles.text(color: Colors.orange),
                            Styles.background(color: Colors.green),
                            Styles.box(width: 800.px, display: Display.block),
                        ]),
                    ),
                ],
            ),
        ]);

    }
}

@schultek What do you think about it?

schultek commented 1 year ago

Yes we should definitely add something like this.