Code Monkey home page Code Monkey logo

uniformcss's People

Contributors

jinsupark avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

uniformcss's Issues

how dose apply mixin work

how did you make it

@include apply("")

my api

utility api

$utilities: () !default;
$separator: \:;
$xs: "xs" !default;

$breakpoints: (
  $xs: 0,
  sm: 480px,
  md: 720px,
  lg: 960px,
  xl: 1200px,
) !default;

@function is-int($value) {
  @return type-of($value) == "number";
}

@each $mapName, $map in $utilities {
  $important: map-get($map, "important");
  $property: map-get($map, "property");
  $values: map-get($map, "values");
  $state: map-get($map, "state");
  $class: map-get($map, "class");
  $media: map-get($map, "media");
  $range: map-get($map, "range");

  $dash: "-";
  @if not $class {
    $dash: "";
  }
  $importantValue: "";
  @if $important {
    $importantValue: "!important";
  }

  $stateVal: "";
  $newState: "";
  @if $state {
    $stateVal: ":" + $state;
    $newState: $state + $separator;
  }

  @if $media {
    @each $break, $point in $breakpoints {
      @media screen and (min-width: #{$point}) {
        @each $name, $value in $values {
          $util-id: $break + $separator + $newState + $class + $dash + $name + $stateVal;
          @if ($break == null or $break == "" or $break == $xs) {
            $util-id: $newState + $class + $dash + $name + $stateVal;
          }
          .#{$util-id} {
            @each $props in $property {
              @each $start, $end in $range {
                @if (not is-int($name) or $name >= $start and $name <= $end) {
                  #{$props}: #{$value} #{$importantValue};
                }
              }
            }
          }
        }
      }
    }
  } @else {
    @each $name, $value in $values {
      $util-id: $newState + $class + $dash + $name + $stateVal;
      .#{$util-id} {
        @each $props in $property {
          @each $start, $end in $range {
            @if (not is-int($name) or $name >= $start and $name <= $end) {
              #{$props}: #{$value} #{$importantValue};
            }
          }
        }
      }
    }
  }
}

utilities

$utilities: map-merge(
  (
    "opacity": (
      class: "o",
      property: opacity,
      range: (10:100),
      important: false,
      values: (
        10: 0.1,
        20: 0.2,
        30: 0.3,
        40: 0.4,
        50: 0.5,
        60: 0.6,
        70: 0.7,
        80: 0.8,
        90: 0.9,
        100: 1,
      ),
    ),
    "border-radius": (
      class: "br",
      property: border-radius,
      important: false,
      values: (
        "none": 0,
        "xs": 2px,
        "sm": 5px,
        "md": 10px,
        "lg": 20px,
        "full": 50%,
      ),
    ),
    "display": (
      property: display,
      media: false,
      important: false,
      values: (
        "none": none,
        "block": block,
        "inline": inline,
        "inline-block": inline-block,
        "inline-flex": inline-flex,
        "inline-grid": inline-grid,
      ),
    ),
    "overflow": (
      class: "overflow",
      property: overflow,
      important: false,
      values: (
        "visible": visible,
        "hidden": hidden,
        "scroll": scroll,
      ),
    ),
  ),
  $utilities
);

Custom property fails to compile

Describe the bug
When I use this example for generating custom properties I get a compilation error:

Error: $map1: null is not a map.
    ╷
361 │                 $compiled-properties: map.merge($static-properties, $merged-properties);
    │                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ╵
  _index.scss 361:27        tree-constructor()
  _index.scss 549:1         @use
  src/sass/style.scss 47:1  root stylesheet

To Reproduce
Steps to reproduce the behavior:

  1. Copy example code from docs
  2. Paste into $config map within utitilities map
  3. See error in compiliation

Expected behavior
Expected compiling to just work and the new utility class to be available.

Additional context
Maybe I've formatted something incorrectly, so just in case, here is my .scss file contents:

$config: (
    delimiter: "\\:",
    pseudo-delimiter: ":",
    screen-delimiter: ":",
    utilities: (
      background-color: (
        pseudos: (hover, active, focus, focus-within, group-hover)
      ),
      border-color: (
        pseudos: (hover, active, focus, focus-within, group-hover)
      ),
      text-edge: (
        shorthand: text,
        properties: (text-edge),
        variants: (
          cap: cap alphabetic
        )
      )
    )
  )
);

Consider not setting `text-rendering` in `reset`

reset sets text-rendering to optimizeSpeed here. I suggest not setting it to anything anywhere.

First, I'm not sure that it really qualifies as a "reset" kind of setting at all; it's not quite the same as different browsers using different font families or font weights or margins for the same element.

Second, even if it does, I'm not sure that optimizeSpeed is the right choice. From Mozilla:

The browser emphasizes rendering speed over legibility and geometric precision when drawing text. It disables kerning and ligatures.

"Disabling kerning and ligatures" isn't, I think, something a reset should do.

The problem is that optimizeLegibility has different trade-offs, and isn't right either; I don't know how things stand today, but there was a time when it had (or could have) a significant impact on the rendering time of text-heavy pages.

If anything, auto is probably the best option. My understanding is that, with auto, browsers make different choices at different font sizes. But auto is the default, so there's no point in setting it to that!

(For what it's worth, Bootstrap doesn't set text-rendering anywhere.)

Consider trumpeting `apply` + `headless`

When I first saw what your framework was capable of, this is what I immediately thought of: that I could use it to very efficiently write traditional CSS — like the examples on your Extracting Components and Helper Mixins pages:

.parent {
  @include apply('p-40 shadow-2xs radius-2xl');
  &__child {
    @include apply('hover.opacity-50 p-24 md.p-64');
  }
}

That is remarkably concise. And maintainable. Combine it with your headless mode, and — holy cow.

That's something special.

(Maybe Tailwind can be used that way, but if it can, I missed it. Well — I know it can almost be used that way. I just don't remember seeing examples as terse and complex as yours.)

As an extra bonus, I even discovered that I could still "include" reset and standard with headless output, e.g.:

@use "uniform" as * with (
  $config: (
    output: headless,
    includes: (
        reset,
        standard
    ),
  ),
);

So with UniformCSS I can be far more productive; I can produce only the CSS I want; and all I need is a SASS compiler.

🤯

At the moment you document this, but in pieces; I think headless is only mentioned on the build settings page, and apply on the two pages I gave above.

I think you should consider pulling the all of those pieces together in one spot, to tell this story. Because this feels like something I haven't really seen before.

I should say: I'm mostly a mobile developer rather than a web developer. But when I do web development I tend to start with a CSS framework. No matter how good the framework is, I always end up having to eventually work around hard-coded assumptions. It seems like your framework — library? — might give me another option.

It's almost like a CSS framework construction kit.

Parity with tailwind

How close this frameworks gets to tailwind? For example, i can't see both flex "grids" and grids in the docs.

Checked sibling pseudo

Is your feature request related to a problem? Please describe.
So sometimes you have a radio set in a form that you want to treat more visually, rather than with plain radio buttons. A common CSS pattern for this situation is to wrap the radio inputs with label elements — so they can still be check via clicking — and then to use a :checked + or :checked ~ sibling selector to style the more visual representation when its accompanying radio is checked. Here's an example:

image

Describe the solution you'd like
Similar in spirit to the group-hover pseudos, it'd be neat to be able to have some sort of checked-sibling pseudo that you could use for situations like this. For that example above, I could imagine using it to apply the blue border when the sibling radio was checked. Something like:

<img src="..." class="shadow-sm border-2 border-transparent checked-sibling.border-blue" />

And the resulting CSS would look like:

:checked ~ .checked-sibling\.border-blue {
  --border-opacity: 1;
  border-color: rgba(var(--blue), var(--border-opacity));
}

Describe alternatives you've considered
I haven't been able to come up with any alternatives to this kind of pseudo that don't require me to either write some javascript behavior or some custom CSS. I'll probably end up implementing this with visible radios for now since I'm trying to go as far as possible without custom CSS.

Please add instructions for Vite

I couldn't figure out how to set this up with Vite via npm after I installed it. Vite couldn't find the scss file to import.

So, instead, I ended up cloning the repo, thinking this would work:

// main.scss
@use 'uniformcss/uniform' as *;

This resulted in errors.

Error: Can't find stylesheet to import.
  ╷
1 │ @forward "uniform/core";

Finally, I just moved uniform directory out of uniformcss directory.

This worked, but it's not ideal.

// main.scss
@use 'uniform' as *;

Typo in letter-spacing docs

Describe the bug
There are a couple typos on the letter-spacing / tracking docs.

To Reproduce
Steps to reproduce the behavior:

  1. Go to 'https://uniformcss.com/cheatsheet/letter-spacings/#visual-reference'
  2. See error

Expected behavior
Correct labeling:
tracking-tightest
tracking-tighter
tracking-tight

Screenshots
Screen Shot 2022-03-24 at 1 32 12 PM

Desktop (please complete the following information):

  • OS: macOS
  • Browser chrome
  • Version Version 99.0.4844.83 (Official Build) (arm64)

Documentation: grid-cols missing "s"

In the grid-template-column documentation the classes are missing an "s" at the end of them.
Current: grid-col-12
Corrected: grid-cols-12

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://uniformcss.com/api-reference/#grid-template-columns
  2. See error

Expected behavior
As mentioned above, I believe this should be grid-cols-xx

Screenshots
Screen Shot 2022-07-17 at 7 41 13 AM

Desktop (please complete the following information):

  • OS: Mac
  • Browser: Chrome
  • Version: 103.0.5060.114

Additional context
It is correct in the 'Basic Grid Usage' section.

Consider a cohesive responsive scaling strategy

To be clear: the framework will allow me to do exactly what I want to do. Everything that follows is just about improving the out-of-box experience.

===

It's taken me some time to work out a good responsive sizing strategy in UniformCSS. I think there are three main issues:

  • Some things are "t-shirt" sized; others are not.

  • The t-shirt sized things don't scale responsively the way you might expect.

  • The not-t-shirt sized things are defined in terms of rems (e.g., 0.625rem), but labelled in terms of pixels (e.g. size-10).

The first issue means that it takes some time and effort to work out a correspondence between the two kinds of scales — especially at different breakpoints. Not at all unusual, but perhaps unnecessary friction.

The second issue is easier to illustrate with an example.

To begin with, I wanted 18px font sizes on phones and 20px font sizes on desktops. Here's one way to get that:

body {
    @include apply("text-lg sm.text-xl");
}

And then, looking at the scales, I decided that I wanted a 7xl h1 size on desktops, and "something smaller" on phones. So:

h1 {
    @include apply("text-6xl sm.text-7xl");
}

That seems like it works. If you do the math, though, you'll see that I haven't just changed the size, I've also changed the ratio:

  • text-lg = 18px, text-6xl = 40px, 18:40 = 1:2.2
  • text-xl = 20px, text-7xl = 48px, 20:48 = 1:2.4

Not fatal, but not intended either. More importantly, if I'm trying to come up with a general solution to responsive sizing, I better not take that approach to re-sizing space, where changing proportions are more likely to be visible. (Think about something that has a 2:1 horizontal-to-vertical padding ratio — and then doesn't.)

What I would generally do — though not all CSS frameworks are very happy about this — is to base everything in rems, and scale my root font size at different breakpoints. Obviously that simplifies almost everything, e.g.:

h1 {
    @include apply("text-6xl");
}

body {
    @include apply("text-md");
}

and pushes responsive re-sizing into html. (It can also introduce new problems, but for the kinds of work I do these days it's usually a better starting point; there's less tweaking to do.)

The reason I didn't do that right away was the third issue. :-) I was already expending mental effort because the non-t-shirt sizes (e.g., size-10) were defined in terms of rems, and those rems were different from my body font sizes on phone and desktop. (That's an issue because, for example, I'd like to add rem-based bottom margins to h1, p, etc.) But even worse: they were labelled in pixels even though they were defined in rems. Thinking about all of those things at the same time exceeded my mental load limit!

===

Here are a few general suggestions:

  • Consider supporting both t-shirt sizes and non-t-shirt sizes where appropriate (e.g., maybe add non-t-shirt sizes to fonts, maybe add t-shirt sizes to sizings?); in my head, users would choose one approach or the other
  • Consider how t-shirt sizes scale — ideally, in a user-configurable way (minor third, major third, etc.)
  • Consider how t-shirt sizes re-size at different breakpoints (so that the scale is preserved)
  • Consider labelling rems as rems

To be clear: I'm not saying that all of those things must be done for any of this to be usable. Rather, I'm saying that there should be one cohesive story out of the box. If there's choice, all the better. But at least one.

Btw, it's very possible that you had a model in mind that just didn't occur to me (or I missed it in the docs). If so, please let me know!

===

As I said, everything I want to do I can. All of this is just about the out-of-box experience.

Here's what I'm going to try today:

  • I'm going to change the root font size at different breakpoints (default 18px, and 20px above sm)
  • I'm going to re-define the t-shirt sizing using a well-known scale (mostly just so that I can have a mental model of how things are scaling)
  • I'm going to add t-shirt sizing to the sizing module

I'll see how that goes.

Allow opting out of semantic colors

I'm not seeing a way to opt out of Uniform's semantic colors like "success", "info", etc. And there also doesn't seem to be a way to override the default values within the config file. I would expect to be able to exclude these altogether via theme config, and likewise to be able to extend them as I do with all the other colors — though I personally only need the exclusion right now.

Without this, I'm left to write custom CSS to override the custom properties, which is less than ideal as I want to keep as much of this as possible within generated CSS via config. Additionally, when we can't exclude these it means they're present in our generated CSS and JSON (which we use for documentation), which isn't good since in our project we'd prefer to just use literal color names like green instead of success, so really we just don't want them present at all.

What do you think @jinsupark, possible to add a config option for excluding the semantic color utilities?

Documentation link broken

Describe the bug
On the API reference, there is a broken link, it makes it difficult to search for that particular property.

To Reproduce
Steps to reproduce the behavior:

  1. Go to 'uniformcss.com'
  2. Click on read the docs.'
  3. Click on API reference
  4. Scroll down to 'top (position property)'
  5. See error (broken link)

Expected behavior
On search, it's supposed to take me to the "top" section of the API reference, or on-click of the "top" link it should display the details, but it doesn't

@jinsupark

Consider generating `auto` variants where appropriate

Consider generating auto variants where appropriate — e.g., mx-auto, for old-style centering.

To be clear, it's already easy to get the generator to produce them, e.g.:

@use "uniform" as * with (
  $config: (
    utility: (
        margin-x: (
            extend: (
                variants: (
                    auto: auto
                )
            ),
        ),
    ),
  )
);

It might just be a better out-of-the-box experience if they're already there.

(I ran into this as soon as I started trying to markup an existing page.)

Allow setting important at the utility level

Is your feature request related to a problem? Please describe.
When using the a gutter utility class like gutter-y-16 to apply spacing between child items, there are time when overriding the spacing of a single element is necessary. Of course there's always the option to remove .gutter-y-16 and instead apply custom margins to all the child elements — this can be annoying though when all but one are the same value. It'd be really nice if there was a way to use a margin utility like mt-24 to override the margin on the one outlier in a group.

The problem today is that because of specificity, the .gutter-y-16 > * + * selector will always win over .mt-24.

Describe the solution you'd like
One option to address this situation could be to allow making some utilities use !important while allowing most to still go without it. For example, if all the margin utilities could be set to important: true that would allow me to override gutter margins for exceptions as they come up. Additionally, due to the nature of margin utilities there isn't really much risk in using !important as they're highly unlikely to collide in any unexpected ways.

Describe alternatives you've considered
Alternatives in my mind include:

  • Using gap + flex/flex-column utilities instead of gutter. With flex + gap you can use margin utilities to add extra space or negative margin utilities to cancel out gaps as needed. I think this is the best alternative, though technically browser support isn't quite fully there yet. Additionally, applying flex does impact the width of child elements unless you add extra classes.
  • When there is an exception, just remove gutter and manually space all the individual items
  • Adding the ability to make some utilities (like margin) use !important without doing it for all

Consider making `@include apply("")` do nothing, rather than producing an error

This is a small convenience thing, but it would be nice if:

.some-class {
    @include apply("");
}

did nothing rather than producing an error.

(In the process I'll describe later on today, I added classes to my HTML, and then added the classes to my CSS, and then started styling the classes. When I added the classes I added empty applys — but apparently you can't do that today. As I said: just a small convenience thing.)

Gutter utility overrides margins in all directions

Describe the bug
The .gutter-x-* and .gutter-y-* utility class names imply that they'll only affect either vertical or horizontal spacing between elements. Unfortunately, their output is set up to apply margin on all sides, setting a value of 0 on the sides it's not directly setting:

.gutter-y-1 > * + * {
  --gutter-top: 1;
  --gutter-bottom: 0;
  margin: calc(0.0625rem * var(--gutter-top)) 0 calc(0.0625rem * var(--gutter-bottom)) 0;
}

This means that any direct children of a gutter with additional margin utilities for the other sides will not take effect.

To Reproduce
Steps to reproduce the behavior:

  1. Apply .gutter-y-16 to a parent element with 2+ direct children
  2. Apply .mx-16 to one of the direct children
  3. See that the child element's .mx-16 margin is overridden by the overly broad margin declaration on gutter

Expected behavior
I would expect that .gutter-y-* would output only margin-top and margin-bottom. And likewise that x would only output margin-left and margin-right. Something more like this:

.gutter-y-1 > * + * {
  --gutter-top: 1;
  --gutter-bottom: 0;
  margin-top: calc(0.0625rem * var(--gutter-top)); 
  margin-bottom: calc(0.0625rem * var(--gutter-bottom));
}

Change screen config to handle numerical values

I was wondering if you're able to add the feature to be able to use something like 2xl on the screens config without the output throwing an interpolation error:

screens: (
sm: 768px,
md: 1024px,
lg: 1280px,
xl: 1536px,
2xl: "screen size",
),

Having it output as .\2xl or [class="2xl"] would be amazing.

Custom delimiters in documentation

Is your feature request related to a problem? Please describe.
The project documentation is nice and helpful! But...when you use custom delimiters for your project, it can make using the docs challenging since the class values and such don't match what you're using in your own codebase. This is especially true for folks that are new to the system.

Describe the solution you'd like
It'd be super helpful if there was a way to enter your custom delimiters into the documentation site, similar to choosing a language. After entering those, the docs could show the appropriate delimiters across examples and such — it'd be really helpful. The same problem exists for other configurable aspects like colors, spacing scales, etc. but it seems like the basic syntax of the selectors is probably the area that might be most impactful.

Describe alternatives you've considered
Other alternatives I've considered, is making some way to auto-generate documentation within a project, based on the project's configuration. Like what if there was autocomplete available that mapped to your configuration of the system.

Easily swap out padding-based ratio for native aspect-ratio

Is your feature request related to a problem? Please describe.
Recently, I attempted to swap out the default ratio that uses padding for a custom ratio utility that uses aspect-ratio instead. It was a bit complex to do since ratio is a special utility.

Describe the solution you'd like
It depends, I am curious how often people prefer using the padding approach versus the new native aspect-ratio approach to do this sort of stuff?

If keeping the padding approach, I would suggest making ratio overridable in the theme settings.

If the padding approach was implemented prior to css aspect-ratio and no longer is relevant - I would recommend replacing padding/height with the new aspect-ratio property.

Additional context
Currently, I am using aspect-ratio to uniformly and exactly size various images and videos on a blog. Both methods work, aspect-ratio is just a lot easier to work with in varying layouts.

JSON output is wrapped in CSS comments

When using output: "json", the resulting output is invalid JSON due to wrapping comments like so:

/*! UniformCSS v1.3.0 | MIT License | github.com/ThinkUniform/uniformcss */
/*!
{ ... }
*/

Expected behavior
I would expect raw JSON to be output, that doesn't require me to manually remove wrapping comments.

Additional context
I've setup Uniform with my application using a config/_index.scss file that does something along these lines:

$output-mode: "css" !default;

@use "uniform" as * with (
  $config: (
    // Build settings - https://uniformcss.com/docs/build-settings/
    delimiter: "\\:",
    pseudo-delimiter: ":",
    screen-delimiter: ":",
    output: $output-mode,
    ...
  )
)

Then I have two separate stylesheets that I use, one (application.sass.scss) generates the CSS for my app:

// Generated utilities - configs + generation
@use "app/config/index";
@use "app/custom/button";
...

And the other (reference.sass.scss) generates the JSON for our internal CSS reference docs:

@use "app/config/index" with ( $output-mode: 'json' );

My build setup for reference.sass.scss drops the output in a css-utilities.json file that we consume to automatically generate documentation. But...with the current issue described up top, a manual intervention is required to remove the wrapping comments from the JSON output. What do you think of removing the wrapping comments @jinsupark?

Responsive gutters

Describe the bug
I have a set of classes: flex flex-col sm:flex-row sm:gutter-x-16 gutter-y-8 sm:gutter-y-0

But the margin-reset in the gutter-y-0 stops gutter-x-16, so there is no space between elements above sm. It works if only margin-bottom and margin-top are reseted.

Thank you for this library, it is awesome!

Norbert

List style positions has a typo

Describe the bug
Looks like a typo snuck in by pluralizing list-style-position to list-style-positions. You can see the property name on MDN here is list-style-position. But in /utilities/typography/core-list-style-position.scss it uses a pluralized form: list-style-position.

Ultimately this results in browsers not rendering the style, because the property is unrecognized.

To Reproduce

  1. Add a list style position utility class like list:outside to an element
  2. Open web inspector on that element
  3. See that the style isn't applied because it isn't recognized

Sidenote: @jinsupark for something like this would you prefer that I open a pull request or something instead? I haven't contributed to a project like this before, so it'd be helpful to understand your preferred process.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.