Skip to content

Instantly share code, notes, and snippets.

@Cobertos
Created November 22, 2020 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cobertos/64a6ff454b90c0fad9d463773c455038 to your computer and use it in GitHub Desktop.
Save Cobertos/64a6ff454b90c0fad9d463773c455038 to your computer and use it in GitHub Desktop.
big sad
/**Function for creating elements with dynamic sizes. Adapted from rems/vw workflow
* like the one at https://www.smashingmagazine.com/2016/05/fluid-typography/
* but made to be applied more selectively.
* We should prefer fixed sizes over dynamic scaling sizes if possible as we get
* more control over sizing (especially for things like Google Search Console checks,
* matching comps better, and dealing with large amounts of dynamic content).
* There are still times you might want to use dynamic scaling sizes to get the
* most out of your whitespace at smaller sizes without a ton of breakpoints
*
* Changing the pixel to vw ratio here is hard without the right intuition. The
* default value below on making the px sizes 1:1 at 768px (1/$obile-break-point)
* so that 1px in is 1vw out at that size. If you only use scaling sizes on mobile
* then your elements will also never get bigger than your px value.
* If you're having issues with sizes being too low you could consider using (1/640px)
* so that your pixel ratio is 1:1 at 640px (which is what HelloWorld did).
* If you wanted to add a constant offset to the line while also decreasing the
* slope, it gets super complicated... you can experiment with:
* min-pixel-size: 200/768;
* @return calc([hash]{[dollar]px/1px * ((1 - [dollar]min-pixel-size)/768)}vw + [hash]{[dollar]min-pixel-size/100}px);
* Making a table might help in tweaking this as well...
*
* @param {number} px The px size to convert
* @returns {number} The converted vw size
*/
@function px2vw($px) {
@if type-of($px) != 'number' or unit($px) != 'px' {
@return $px; //We don't support this
}
// | px in | vw out | res | px actual |
// |:-----:|:--------:|:---:|:---------:|
// | 16 | 0.020833 | 350 | 7.291667 |
// | 16 | 0.020833 | 500 | 10.41667 |
// | 16 | 0.020833 | 768 | 16 |
@return $px/1px * (1px/$mobile-break-point) * 1vw;
}
/**Mixin for create a property with dynamic sizes up to the mobile cutoff. Any
* px passed in value will become a px2vw
* @param {string} $prop The property name
* @param {...any} $vals The values that the property to be set to. This can take
* space separated and command separate properties without quotes. For example,
* something like transition could be passed as
* `vwProp(border, 2px solid #FFF, 3px dashed #00F);
* and would render
* border: px2vw(2px) solid #FFF, px2vw(3px) dashed #00F;
* @include macro {
* border: 2px solid #FFF, 3px dashed #00F;
* }
*/
@mixin vwProp($prop, $vals...) {
//Sass lists are immutable so we have to make a new list of lists
//I really hate sass...
$newVals: ();
@each $val in $vals {
@if type-of($val) == 'list' {
$newVal: ();
@each $val2 in $val {
$newVal: append($newVal, px2vw($val2));
}
}
@else {
$newVal: px2vw($val);
}
$newVals: append($newVals, $newVal);
}
#{prop}: $newVals;
@include macro {
#{prop}: $newVals;
}
}
/**Mixin for elements with dynamic font-size based on viewport. Meant to work with
* a rems/vw workflow (see cRems() and cPrt()).
* You can also read more about this technique at
*
*
* Tweaking the 2.5vw is a bit tough, but was originally chosen so that at 640px,
* the font size would be 16px (a common base font size for a given screen resolution).
* To intuitively tweak this value, 2.5vw is a good starting place. Thinking back
* to linear algebra, 2.5vw is the slope of how fast the font size changes if you
* plotted it at a line. A higher value means a higher slope and the font size will
* get bigger much quicker (and might be too big before the macro breakpoint).
* A smaller value will get bigger slower, and might end up being too small at
* small resolutions.
* If you thought about adding a fixed number like calc(2.5vw + 10px), this works
* to correct smallness on the low end but it might be hard to work with... Try it out!
* Note, for aesthetic reasons, you may want to keep some things fixed between
* different viewports instead of scaling, use your judgement!
*/
@mixin dynamic-font-size {
//Percentage of viewport font-size (it helps to write out the conversions)
//768px it will be 19.2px
//500px it will be 12.5px
//350px it will be 7.5px
font-size: 2.5vw; //Percentage of viewport, so at 768, it will be 0.025 * 768 = 19.2
@include macro {
font-size: 16px; //Static font size on desktop
}
}
/**Calculates a rems value given a pixel value $fontSize for a rems/vw workflow. In this
* case our base font size is 16px
* You can read more on this technique on a site like
* https://www.smashingmagazine.com/2016/05/fluid-typography/
* Example:
* ```
* left: cRems(20px);
* ```
* @param {number} $fontSize The size to convert in px
* @param {number} $baseFontSize The size of the body font
* @returns {number} The converted rems size
*/
@function cRems($fontSize, $baseFontSize: 16px) {
@return $fontSize/$baseFontSize * 1rem;
}
/**Calculates a rems value using a given percentage $pct. In this case our base
* percentage used on body is 2.5vw. Useful for taking a percentage of the
* screen width and applying all the same scaling/stopping points our rems
* experience
* Example:
* ```
* width: cPct(20); //20 percent of the viewport width
* ```
* @param {number} $pct The percentage to convert, without the trailing %
* @returns {number} The converted rems size
*/
@function cPct($pct) {
@return $pct / 2.5 * 1rem;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment