-
Notifications
You must be signed in to change notification settings - Fork 2
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
[For discussion] Type & space scales #14
Comments
Whoops, just realized this is extremely similar to #5 — we may want to close one of these, I'll leave this one open for now though as there's a bit more information here. |
Recap of possible iterationsSeveral threads relating to type and spacing scales in Enhance Styles have been ongoing in the background over the past few months. The following is a list of the main considerations that have been discussed: Distinct type and space scalesAs discussed previously, providing an option to create distinct type and space scales would be useful. For example: export default {
typeScale: {
ratio: 'perfectFourth',
steps: 6,
},
spaceScale: {
ratio: 'minorThird',
steps: 12,
},
} Where one of either Imperative scalesThere have been some requests for type and space scales to support an imperative set of values, similar to Theme UI's theme specification. Considering the option to specify distinct type and space scales, this would look something like: export default {
typeScale: ['0.85rem', '1rem', '1.125rem', '1.25rem', '1.5rem', '2rem', '4rem'], // string values emitted in CSS as-is
spaceScale: [0, 2, 4, 8, 16, 32, 64, 128, 256], // integers emitted in CSS as pixels
} Again, if one of these two was undefined, we would generate the undefined scale to match the defined scale. Fluid scalesFinally, the ability to create fluid type and space scales (see Utopia) has been suggested. This allows for creating fluid type and space scales without defining breakpoints, which is becoming an increasingly popular and useful way to work with type and layout. This requires a fair bit more in terms of specification, i.e.:
export default {
typeScale: {
steps: 6,
viewportMin: 320,
viewportMax: 1500,
baseMin: 16,
baseMax: 22,
scaleMin: 1.25,
scaleMax: 1.33,
},
spaceScale: {
steps: 12,
viewportMin: 320,
viewportMax: 1500,
baseMin: 16,
baseMax: 32,
scaleMin: 1.5,
scaleMax: 2,
},
} ConsiderationsExplicit or implicit scale typesDifferentiating between imperative and parametric scales is straightforward, in that an imperative scale will always be specified as an array of values, whereas a parametric scale requires an object specifying a configuration. However, if we're going to consider offering both static and fluid parametric scales, we have two options to differentiate between them when generating those scales:
The implicit route is simpler for consumers as it saves them having to write (and remember) another configuration parameter. One benefit to relying on an explicit key to specify the variety of scale, however, would leave the door open for allowing users to request either a static or fluid scale without specifying the parameters themselves (which we could then fill in with a set of sane defaults). For example: export default {
typeScale: {
fluid: true, // generates a fluid type scale with our default parameters
},
spaceScale: {
fluid: true,
configuration: {
steps: 6,
viewportMin: 320,
viewportMax: 1500,
baseMin: 16,
baseMax: 32,
scaleMin: 1.5,
scaleMax: 2,
},
},
} Existing configurationThe existing configuration for the unified type and space scale is defined as: export default {
base: 18,
scale: {
ratio: 'perfectFourth',
steps: 12,
},
} A few questions regarding this:
Generated classesGenerated utility classes would need to follow different patterns for different types of scales, i.e.:
|
We should leave the existing |
@kristoferjoseph Sounds good to me. I think we'll have some edge cases to sort out — for example, what happens if a user specifies I think there's potentially more complexity to examine with the root
…or:
In these cases I guess we could either ignore the root |
Follow up - 2023/04/18The following summarizes some discussions over the past week: Imperative scale valuesImperative scales defined with integers would need to be interpreted and emitted as rem units in order to preserve typographic accessibility. E.g. a scale of However, encouraging the use of pixel values may not be something we want to do. This also creates a delta between styleguide input and output, which could be confusing and create unexpected behaviour for end users. To this end, I'm wondering if we want to avoid the complexity and ambiguity of imperative scales with Enhance Styles. If a user prefers to use an imperative, pixel based scale, going with a different styling library may be a better option for them. Multiple scales vs a larger/finer grained single scaleWe discussed the question of whether we really need/want the option to create dedicated font/spacing scales, or whether we just need a way to generate larger scales with more fine grained steps, which would be useful for both type and spacing. The tradeoff here is that we could end up with a ton of classes, some of which may never be used, and we're somewhat averse to post processing (i.e. getting into static analysis and tree shaking), which means this could end up really bloating the generated CSS. Also, at the end of the day, the user can themselves choose to use a single scale with many steps and small ratios, so this could end up just being a user decision (providing we offer the option of creating distinct type and spacing scales). |
Something I'm finding a bit finicky is landing on a scale that works equally well for both type sizes and layout spacing, as they both currently use the same scale intervals via
styleguide.json
. (This isn't a challenge unique to Enhance Styles, I've faced this many times with other parametric design implementations.)Specifically, I find that things get tough as the scale moves into the negative values (
text-1
,text-2
, etc). The values produced by certain scales at these intervals often results in type sizes that make legibility a challenge; however, those same values can be really useful for fine tuning layouts. Here's an example:In this instance, the positive intervals (
text1
,text2
…) work well, but the negative intervals would make most type too hard to read. On the flip side, those same intervals can make precise adjustments to margins, padding, etc where needed, which is nice.One workaround that I've tried is using a scale with very small intervals (for example, a minor third scale, with a 1.2 scale factor), which produces finer gradations (and thus more usable type sizes at the negative intervals). However, depending on the number of steps specified in the scale, this can produce either too few distinct options for type sizing at positive intervals (since the contrast between heading level sizes is quite minimal), or too many superfluous options for both type and layout spacing (thus reducing the effectiveness of using a parametric bounds in the first place, since many of the values produced will go unused).
One option that comes to mind is the ability to provide explicit intervals for the scale, and possibly the option to differentiate the type and layout scales. The existing
scale
configuration option could be persisted, but a new set of options could be provided as opt ins for folks who want to get more granular. For example:In this example, both
typeScale
andspaceScale
could take either an array of explicit values, or an object to specify a generated scale, as the existingscale
option currently works.This is just one idea off the top of my head, but wanted to spin up an issue to get the wheels turning. All input welcome!
The text was updated successfully, but these errors were encountered: