Blog posts under the scss tag https://webdevstudios.com/tags/scss/ WordPress Design and Development Agency Mon, 15 Apr 2024 16:01:34 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 https://webdevstudios.com/wp-content/uploads/2022/07/cropped-wds-icon.white-on-dark-60x60.png Blog posts under the scss tag https://webdevstudios.com/tags/scss/ 32 32 58379230 Sass Tips to Take Your Skills to the Next Level https://webdevstudios.com/2019/12/03/10-sass-tips/ https://webdevstudios.com/2019/12/03/10-sass-tips/#comments Tue, 03 Dec 2019 17:30:36 +0000 https://webdevstudios.com/?p=21296 If you’ve been using Sass for a while, but find yourself writing seemingly basic code that doesn’t look very different from vanilla CSS, then this article is for you. We’ll explore ten ways to put Sass to use, taking advantage of some of its more intermediate to advanced features. Year after year, I continue to Read More Sass Tips to Take Your Skills to the Next Level

The post Sass Tips to Take Your Skills to the Next Level appeared first on WebDevStudios.

]]>
If you’ve been using Sass for a while, but find yourself writing seemingly basic code that doesn’t look very different from vanilla CSS, then this article is for you. We’ll explore ten ways to put Sass to use, taking advantage of some of its more intermediate to advanced features. Year after year, I continue to be impressed with the language’s capabilities and would like to share some of the tricks I’ve learned. This article assumes you have at least some working experience with Sass. If not, get your hands dirty with one of the many great resources on the internet. The Sass documentation is a great place to start. They don’t call them Syntactically Awesome Style Sheets for nothing, so let’s get started on these 10 Sass tips created to take your skills to the next level.

1. Parent Selector

Select a parent from within the child selector.

SCSS

View the code on Gist.

Instead of having to make a new selector for .container .text outside of the .text block, you can just write your selector inside of .text, followed by the &.

Compiled CSS

View the code on Gist.

HTML

View the code on Gist.

View on CodePen.

 


2. Suffixes

Here’s a cool way to generate suffixes based on a particular class. Use &- followed by the desired suffix. In this case, &-pink will create .container-pink when it’s used inside of .container.

SCSS

View the code on Gist.

Compiled CSS

View the code on Gist.

HTML

View the code on Gist.

View on CodePen

 


3. String Interpolation

String interpolation will render the result of a SassScript expression as compiled CSS. In this basic example, we’re setting color variables, then rendering them out as CSS comments.

SCSS

Notice how we use string interpolation directly in the comment.

View the code on Gist.

Compiled CSS

View the code on Gist.

View on CodePen


4. Placeholders

Placeholders are similar to variables in that they aren’t compiled in the actual CSS. The benefit of this is that they keep your code clean by rendering only the output of the placeholder. They can be extended anywhere in your code. Placeholders can be useful when you want to extend some particular properties across multiple selectors. Start your placeholder with a percentage sign %, so for example you could write %my-placeholder, and extend it inside your selector with @extend.

SCSS

View the code on Gist.

Compiled CSS

View the code on Gist.

HTML

View the code on Gist.

View on CodePen


5. Default value in mixins

When using a mixin, you normally need to pass in every argument that will be required. The advantage of using a default value is that you aren’t required to pass an argument in, but you can always override the default you’ve set. In this Sass tip example, I’m overriding the defaults for the second h1 as I pass in an argument of darkcyan.

SCSS

View the code on Gist.

Compiled CSS

View the code on Gist.

HTML

View the code on Gist.

View on CodePen


6. Null

Let’s expand on what we just did with using a default value, except this time, we’ll use null as a default value. If no arguments are passed in, nothing will be compiled in the CSS for opacity, but if an argument is passed in, it will be compiled in the CSS. This is a nice trick because your CSS won’t be bloated with unused styles.

SCSS

View the code on Gist.

Compiled CSS

View the code on Gist.

HTML

View the code on Gist.

View on CodePen


7. Color Functions

Color functions open a world of options for manipulating colors. They are built into Sass and can be used to dynamically generate CSS based on your needs. Here, we instantiate our scale-color function, passing in a color, and a saturation percentage. There are many color functions, and I encourage you to experiment with them.

SCSS

View the code on Gist.

 

Compiled CSS

When compiled, the hexidecimal color here is the result of the expression.

View the code on Gist.

HTML

View the code on Gist.

View on CodePen


8. @if to Change Contrast

Here’s a great Sass tip: Sass has control flow built into it. There are four types of control available to use: @if, @each, @for, and @while. Here, we use an @if conditional to determine if our colors meet the desired threshold for contrast; we then render the text color based on the outcome.

SCSS

View the code on Gist.

Compiled CSS

View the code on Gist.

HTML

View the code on Gist.

View on CodePen


9. @debug

When using Sass, there may be times when you need to know the value of an expression. If you use JavaScript, you have probably used console.log() to print the results of an expression to the console. The good news is that Sass has something similar. For example, it might be more work than it’s worth to figure out the saturation of #e1d7d2 yourself, but @debug is happy to do the math for you, right in the console!

SCSS

View the code on Gist.

Compiled CSS

View the code on Gist.

View on CodePen


10. Use @for to Build Your Own Utility Classes

You can even use loops in Sass. @for is one of the four types of control flow currently in Sass. Here, we’re going to generate some utility classes. We’re using the unquote function to return a string of "px", but without quotes. As you might be wondering, there’s also a quote function, which will return the same thing, but with quotes, of course. Note the use of string interpolation.

SCSS

View the code on Gist.

Compiled CSS

View the code on Gist.

HTML

View the code on Gist.

View on CodePen


Here’s a full list of all the CodePen examples for you to explore:

1. Parent Selector
2. Suffixes
3. String Interpolation
4. Placeholders
5. Default value in mixins
6. Null
7. Color Functions
8. @if To Change Contrast
9. @debug
10. Use @for To Build Your Own Utility Classes


Thank you!

Thanks for taking the time to read these Sass tips. I hope you’ve found some of these items that I’ve picked up over the years to be useful for your daily Sass workflow.

The post Sass Tips to Take Your Skills to the Next Level appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2019/12/03/10-sass-tips/feed/ 1 21296
Dev Shortie: A Better Process for Styling Websites https://webdevstudios.com/2019/01/31/process-for-styling-websites/ https://webdevstudios.com/2019/01/31/process-for-styling-websites/#comments Thu, 31 Jan 2019 17:00:04 +0000 https://webdevstudios.com/?p=19975 One thing I’ve noticed a lot lately with websites is that no matter how it looks, the style sheet is full of redundant, duplicate, or unnecessary styles. A lot of that, I imagine, comes from updates after a website goes live, where engineers that weren’t initially involved in its development are coming in blind. Another Read More Dev Shortie: A Better Process for Styling Websites

The post Dev Shortie: A Better Process for Styling Websites appeared first on WebDevStudios.

]]>
One thing I’ve noticed a lot lately with websites is that no matter how it looks, the style sheet is full of redundant, duplicate, or unnecessary styles. A lot of that, I imagine, comes from updates after a website goes live, where engineers that weren’t initially involved in its development are coming in blind. Another part of that might revolve around planning or distribution of tasks for a website’s construction.

Truth be told, there are probably dozens of reasons that the styles may not be as organized or clean as they could be. We can’t see the future and we can’t always be in constant communication with one another, but I’ve learned a thing or two over the last decade that I think might help keep things clean, organized, reusable, and readable.

Before We Start

A few setup notes here: I write my styles with SCSS. This is my preference. There are many other options out there—Less or Sass to name a couple—which will work in more or less the same way. I also typically use webpack or Gulp on older projects to compile and minify, auto-prefix, and concatenate my style sheets.

Organization and Breakdown

The organization is really up to the user. There is no one right way to organize your style sheets, but I’m going to share how I organize styles and why. The why is the more important aspect for the sake of reusability.

As far as I’m concerned, there are three parts of styling a website: utilities, global elements, and unique elements.

Utilities

Utilities are things like variables, functions, or Sass mixins to help you in building your website fast and efficiently, but is rarely utilized effectively. This is the most important area for improving our processes, but we’ll come back to that.

Global Elements

Global elements are parts of your website that are used universally across the site, or in my opinion, anything that may exist on two or more pages of your website in some capacity. These are things like your typography, your grid, input or button styles, card/graphic styles, icons, etc. The large majority of your website’s styles will fit into this category.

Unique Elements

Unique elements are exactly what they sound like: some part of your website that may only exist on one part of your website. This might be something as small as that one element that shows up only on the homepage or something bigger like all single post template—shared elements that only exist in one area of your website. They can, in this case, be reusable, but aren’t part of the global scope.

Here’s where we tend to get messed up. Things that exist on a single post template, to continue the example, will also exist in the Global Elements and will probably be rendered in part by Sass mixins or variables in use. In fact, most of that template will probably be informed by the global styles unless, for some reason, it’s completely different. We might start to dirty up our code when we don’t clearly acknowledge inherency and don’t take a larger advantage of our utilities.

Styles start to get a little dirty because there isn’t sufficient effort to educate incoming developers about how things are built or what elements are used, which is why it’s infinitely important to document your code.

Comment and Document

I don’t mean you need to write up a Github Wiki for every bit of code you write, but DocBlocks are important just as they are writing JavaScript or PHP, etc. At the very least we need to explain why things might go against the typically expected standards, overwrite global styles or if an !important is required, for example.

I take advantage of VSCode’s snippets to ensure that all of my SCSS start with a comment. At the least to determine what selector is used. We can’t always adhere to a BEM style structure, or inherently understandable class names, so it’s important to define what’s being styled if, at the least, there’s nothing else special about that block of code.

I might document minimally like:

// h2.
.title {
	font-weight: bold;
} // .title.

If there’s something more involved in the block of styles, I might add a more specific note like this:

// Post Title. Overwrite parent theme.
.entry-title {
	color: $color-red !important; // Force override parent theme.
	font-weight: bold;
	text-decoration: none;
} // .entry-title.

Of course I would do my best to style a selector in a parent theme before deciding an !important is required, but hopefully, you get my point.

I also find myself styling some object with multiple elements nested together; I separate those by an element comment to ensure each bit of styles are covered. This is a slimmed down example. Normally, I’d only implement this strategy on larger chunks of SCSS, but as an example.

//-----------------------------------------
// BLog River Post
//-----------------------------------------

//--------------------------------------------------------------
// Post River Card
//--------------------------------------------------------------

// article.
.post {
	border: 1px solid $color-gallery;
	background: $color-white;
	padding: 1.5625rem;

	//-----------------------------------------
	// Post Title and Meta
	//-----------------------------------------

	// header.
	.post-title {
		font-weight: bold;

		// span.
		.date {
			color: $color-alto;
			font-weight: 400;
		} // .date.
	} // .post-title.

	//-----------------------------------------
	// Post Entry
	//-----------------------------------------

	// div.
	.post-entry {
		margin-bottom: 0;

		// p. Inherits global styles.
		p {

			// Links in post entry.
			a {
				color: $color-sunshine; // Color differs from global link color.
			} // a
		} // p.
	} // .post-entry.

	//-----------------------------------------
	// Post Footer
	//-----------------------------------------

	// footer.
	.post-footer {
		font-size: 0.875rem;
	} // .post-footer.
} // .post.

This isn’t an immense amount of extra work in order to make sure that all of your selectors, class names and styles are documented and anything that differs from the global scope are noted. Anyone coming in after the fact should be able to gain a fairly decent understanding of what this is styling and of each element.

Intermission

At this point, we’ve organized our styles simply and documented our code fairly well. The level of organization and documentation will be dependent on your company’s code standards and general workflow and preference, but this is generally pretty simple and clean so far. The next missing element in creating a more efficiently styled website is the use of built-in and custom Sass functions and mixins.

Mixins

Mixins allow you to declare some SCSS that you want to reuse throughout the website. You can tie in Sass loops or functions to increase its extendability or functionality, but a general mixin might look like this:

@mixin card-style {
	border: 1px solid $color-gallery;
	background: $color-white;
	padding: 1.5625rem;
}

And then it is used by simply calling @include card-style. This is a quick and easy way of adding easily-reusable styles to ensure that cards are consistent from page to page on your new website. I personally believe that you really shouldn’t vary from these styles for consistency’s sake—you shouldn’t have more than one similar-looking card styles on your site. But in the event that you want to extend this mixin, you could add some additional options, variables, or checks and take that simple mixin to something like this:

@mixin card-style($border: $color-alto, $background: $color-white, $padding: 1.5625rem) {
	border: 1px solid $border;
	background: $background;
	padding: $padding;
}

This will output the same value as the card-style mixin above, but it also offers the ability to provide a custom border, background, and padding values if we like.

The goal here would be to create mixins for global elements or globally-utilized styles and document their usage. This ensures that styles for like elements are consistent, but it also cuts down on the amount of code actually needing to be written; and therefore, cuts down on the amount of time required for a project to some extent.

Extending Your Markup

Mixins are quick and easy, but there are many other ways that you can help quickly style your website by leveraging more complex mixins. Let’s take a look at a mixin that can be used to output presentational background and color classes that we can utilize directly in the markup.

I’d start by creating a new Sass map. Something like this:

$theme-colors: (
	alto: $color-alto,
	black: $color-black,
	gallery: $color-gallery,
	white: $color-white,
);

This gives me an iterable list of colors we can loop through in our mixin, which would look like this at a very simple level:

@mixin colors($colors: $theme-colors) {

	@each $name, $color in $colors {

		// Create background color classes.
		.background-#{$name} {
			background-color: $color;
		}

		// Create color classes.
		.color-#{$name} {
			color: $color;
		}
	}
}

This can be called once and, for each color, generate a background class and color class name for use anywhere in your markup.

<footer class="site-footer background-gallery"></footer>

This would render a selector with a background color that matches our variable.

I should note that my recommendation is that only colors that will be used should be added to this Sass map. Otherwise, you’re left with unused styles in your style sheet just taking up precious bytes of space.

Summation

Really the use of mixins or functions is endless. The goal here is to create as much reusable code as possible. The more you reuse, the more consistent your website will be when it’s built and when you inevitably add or update features in the future. Incoming devs can now leverages a well-documented pre-existing library of styles in which to pull from to help avoid adding new or redundant code into your repo and keeping things clean.

The post Dev Shortie: A Better Process for Styling Websites appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2019/01/31/process-for-styling-websites/feed/ 3 19975
Get Loopy with Sass https://webdevstudios.com/2017/02/07/get-loopy-sass/ https://webdevstudios.com/2017/02/07/get-loopy-sass/#respond Tue, 07 Feb 2017 17:00:53 +0000 http://webdevstudios.com/?p=16553 Whether you use Sass/SCSS, Less, or Stylus to compile your CSS, one thing’s for certain; it just makes life much easier. These preprocessors give us access to variables, necessary calculations, and powerful mixins that allow us to take our front-end workflow to the next level. As time passes the projects I tackle tend to present Read More Get Loopy with Sass

The post Get Loopy with Sass appeared first on WebDevStudios.

]]>
Whether you use Sass/SCSS, Less, or Stylus to compile your CSS, one thing’s for certain; it just makes life much easier. These preprocessors give us access to variables, necessary calculations, and powerful mixins that allow us to take our front-end workflow to the next level.

As time passes the projects I tackle tend to present questions that require unique answers — answers that don’t always need a PHP or programmatic approach; found in the lesser known (or utilized) parts of Sass: control directives. Similar to PHP or Javascript, Sass has if(), @if, @else, @else if, @for, @each, and @while that we can use to conditionally define or loop through styles using booleans or multiple variable checks. Why not save time and energy and make our compiler do the heavy lifting? You could even, in theory, automate the styles for an entire page or global elements. Let’s start off with the basics and end with a bang, then get into something more advanced.

if()

if() is a boolean expression that only returns one of two possible values: true or false, and it works like this.

if(true/false, true, false);

So a use case for this might be:

$boolean: false;

.text-color {
    $color: if($boolean, #000, #fff);
    color: $color;
} // .text-color

Which would output this:

.text-color {
    color: #fff;
} // .text-color

That’s pretty simple. I’ve found this useful when building two containers with same styles, with the exception that their colors are inverted. Using if() checks I can define either white or black depending on div-specific boolean variables.

@if and @else

@if is different than if(), though it is still a boolean, if() is a singular check, while @if evaluates a statement and runs code depending on the outcome. When used in conjunction with@else you can create a loop to allow for multiple checks for true as well as a default should all prior nested statements prove false.

Let’s build on the example above:

$text: #fff;
$boolean: false;

.text-color {

// Internal variables.
$color: if($boolean, #000, #fff);

// Determine background-color.
@if $text == #000 {
    background-color: #fff;
} @else {
    background-color: #000;
}

color: $color;
} // .text-color 

Notice here we’re using ==, but just like Javascript or PHP you have the whole list of operators to choose from including arithmetic (+ - * / %), equality (== !=), logical (and or not), and comparison (> >= < <=) to determine whether or not a statement is true or false.

Bonus: If you want to up your game check out string and color operations.

Which would output this CSS:

.text-color {
    background-color: #000;
    color: #fff;
} // .text-color

Though it does essentially the same thing, we allow for multiple conditionals and multiple possible outcomes with a few lines of code and one variable. A real time saver, and in my opinion, easier to read than a standard if() clause.

We can also do multiple @if checks with @else if, for example:

@if $text == #000 {
    background-color: #fff;
} @else if $text == #fc0 {
    background-color: #69ace5;
} @else if $text == #273143 {
    background-color: #ccc;
} @else {
    background-color: #000;
}

Tip: Remember that numbers, letters, and variables are case sensitive when doing checks.

@for

For those of you familiar with Javascript and jQuery, this might not be unfamiliar, but who knew?

@for can be used two ways looping from x “through” y or from x “to” y. “through” starts and iterates to and including the last item while “to” iterates and does not include that one last iteration.

Here’s a simple @for loop to help us generate helper classes for a grid framework:

@for $i from 1 through 4 {
    $width: 1 / $i;

    .col-#{$i} {
        width: $width;
    } // .col-#{$i}
} // end @for

This would output to:

.col-1 { width: 100%; }
.col-2 { width: 50%; }
.col-3 { width: 33.33%; }
.col-4 { width: 25%; }

Perhaps a more advanced usage might be to define the number of columns before you loop. You could also define mixins inside of the loop. Let’s take bourbon for instance.

$num-columns: 4;

@for $i from 1 through $num-columns {

    .col-#{$i} {
        @include span-columns( $num-columns / $i );
    } // .col-#{$i}
} // end @for

Would output to this:

.col-1 { 
    float: left;
    display: block;
    width: 100%;
}
.col-2 { 
    float: left;
    display: block;
    width: 48.8217%;
    margin-right: 2.35765%;
}
.col-3 { 
    float: left;
    display: block;
    margin-right: 2.35765%;
    width: 31.76157%;
}
.col-4 { 
    float: left;
    display: block;
    margin-right: 2.35765%;
    width: 23.23176%;
}

Note: If I was creating a grid, I might even add conditionals to make .col-1 output @include fill-parent; or even add &:nth-child(x);to remove the margin-right from the last item in a column row.

@each

each() works like you’d expect: @each $variable in <list or map>. You can loop through custom-defined class names to define a color or image (example below), which makes styling similar items a snap.

$type: action, western;

@each $movie in $type {
    .#{$movie}-container {
        background-image: url("assets/images/#{$movie}-bg.jpg");
    } // .#{$movie}-container
} // end @each

Output:

.action-container {
    background-image: url("assets/images/action-bg.jpg");
} // .action-container

.western-container {
    background-image: url("assets/images/western-bg.jpg");
} // .western-container

I would say, super helpful. You can go one step further and define multiple variables within a map.

$type: (action, #fc0), (western, #8a472c);

@each $movie, $color in $type {
    .#{$movie}-container {
        background-image: url("assets/images/#{$movie}-bg.jpg");
        color: $color;
    } // .#{$movie}-container
} // end @each

Which becomes:

.action-container {
    background-image: url("assets/images/action-bg.jpg");
    color: #fc0;
} // .action-container

.western-container {
    background-image: url("assets/images/western-bg.jpg");
    color: #8a472c;
} // .western-container

Using Sass maps is super helpful within loops. Check those out here.

@while

I rarely use @while loops. You can accomplish most everything you might need to achieve with @if or @each directives. That said, they are sometimes useful. Particularly within a @mixin since they run if a condition is met avoiding extra code.

$num: 4;

@while $num > 0 {
    .block-#{$num} {
        content: "#{$num}";
    } // .block-#{$num}
    
    // Reset loop and go again.
    $num: $num - 1;
} // end @while

This outputs:

.block-4 {
    content: "4";
} // .block-4

.block-3 {
    content: "3";
} // .block-3

.block-2 {
    content: "2";
} // .block-2

.block-1 {
    content: "1";
} // .block-1

Advanced Usage

Separately, any of these can be a major help, but you generate more markup to turn a @mixin into something like a function for Sass.

Here’s an example with documentation, which outputs a standard hamburger button.

//-----------------------------------------
// Make the Hamburger Icon
//-----------------------------------------
@mixin generate_hamburger($width, $height, $space, $color, $position, $radius, $speed) {    

  // Start variables.
  $gutter: $height + $space;
  
    // Determine position left right or center.
    @if $position == right {
        float: right;
    } @else if $position == left {
        float: left;
    } @else {
        margin-left: auto;
    margin-right: auto;
    }
    margin-bottom: $height + $space;
    margin-top: $height + $space;
    position: relative;
    text-indent: -9999em;
  
  // All bar sizes.
  &,
  &::before,
  &::after {
    background-color: $color;
    
    // Border radius?
    @if $radius != 0 {
      border-radius: $radius;
    }
    height: $height;
    transition: all $speed ease-in-out;
    width: $width;
  } // &, &::before, &::after
  
  // Top/bottom bars.
  &::before,
  &::after {
    content: "";
    left: 0;
    position: absolute;
  } // &::before, &::after
  
  // Top bar.
  &::before {
    top: -$gutter;
  } // &::before
  
  // Bottom bar.
  &::after {
    bottom: -$gutter;
  } // &::after
}

//-----------------------------------------
// Usage
//-----------------------------------------
.menu-toggle {
    @include generate_hamburger(30px, 5px, 5px, #000, null, 5px, 0.3s);
} // <div class="menu-toggle"></div>

You could take this even further to add a focus state with some animation doing like this. We’ll add a is-active class and some js to help us along.

//-----------------------------------------
// Make the Hamburger Icon
//-----------------------------------------
@mixin generate_hamburger($width, $height, $space, $color, $position, $radius, $speed) {    

  // Start variables.
  $gutter: $height + $space;
  
    // Determine position left right or center.
    @if $position == right {
        float: right;
    } @else if $position == left {
        float: left;
    } @else {
        margin-left: auto;
    margin-right: auto;
    }
    margin-bottom: $height + $space;
    margin-top: $height + $space;
    position: relative;
    text-indent: -9999em;
  
  // All bar sizes.
  &,
  &::before,
  &::after {
    background-color: $color;
    
    // Border radius?
    @if $radius != 0 {
      border-radius: $radius;
    }
    height: $height;
    transition: all $speed ease-in-out;
    width: $width;
  } // &, &::before, &::after
  
  // Top/bottom bars.
  &::before,
  &::after {
    content: "";
    left: 0;
    position: absolute;
  } // &::before, &::after
  
  // Top bar.
  &::before {
    top: -$gutter;
  } // &::before
  
  // Bottom bar.
  &::after {
    bottom: -$gutter;
  } // &::after
  
  // Active state.
  &.is-active{
    @include activate_hamburger(#675aac);
  } // &.is-active
}

// If active.
@mixin activate_hamburger($color) {

  // Top/bottom bars.
  &::before,
  &::after {
    background-color: $color;
  } // &::before, &::after

  // Top bar.
  &::before {
    top: -1px;
    transform: rotate(45deg);
  } // &::before

  // Bottom bar.
  &::after {
    bottom: 1px;
    transform: rotate(-45deg);
  } // &::after
}

//-----------------------------------------
// Usage
//-----------------------------------------
.menu-toggle {
    @include generate_hamburger(30px, 5px, 5px, #000, null, 5px, 0.3s);
} // <div class="menu-toggle"></div>

See the Pen Hamburger Mixins by jomurgel (@jomurgel) on CodePen.

Conclusion

Sometimes it’s the little things. With the goal to optimize load times, increase proficiency, and generate dynamic content easily, it’s a no-brainer that utilizing control directives in Sass is the way to go. At the very least, it can cut your dev time in half on certain tasks. I wholeheartedly recommend taking a deep dive into Sass and the power of if(), @if, @else, @else if, @for, @each, and @while.

We’d love to know how people use loops in new and exciting ways. Let us know in the comments below.

The post Get Loopy with Sass appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2017/02/07/get-loopy-sass/feed/ 0 16553