Using SASS with user-specified colors
Alright I dug into the Sass docs and it looks like it would be possible to do using their functions, but it seems like it'd be overly complicated and introduce problems later anyways.
The best way I have found to do this is to generate the user-specific template when they update their settings. This works better anyways, as a request is never delayed while waiting on the parser.
# unless cached_copy_exists
template = %Q{
@import '/path/to/color_scheme';
@import '/path/to/layout';
}
output = Sass::Engine.new(template, :syntax => :scss).render
# output rendered CSS to file for inclusion in HTML template
In order to allow custom colors, user-input could be assembled into SASS css variables in a string and prepended to the template file being passed to the Sass parsing/rendering engine.
Update:
Per request, here's a more fleshed-out example of how this works, focusing just on using Sass variables and a pre-coded Sass stylesheet (simplified to isolate this specific problem):
# config/routes.rb
resources :stylesheets, only: [:show]
# app/controllers/stylesheets_controller.rb
class StylesheetsController < ApplicationController
layout nil
def show
styles = Stylesheet.find(params[:id])
base_stylesheet_path = Rails.root.join('app', 'assets', 'profile.scss')
# Build the string of SCSS we'll pass to the Sass rendering engine
@sass = <<-SASS
#{styles.to_sass}
@import "#{base_stylesheet_path}";
SASS
# Cache for long time
response.headers['Cache-Control'] = "public, max-age=#{1.year}"
respond_to do |format|
format.css
end
end
end
# app/views/stylesheets/show.css.erb
<%= raw Sass::Engine.new(@sass :syntax => :scss).render -%>
# app/models/stylesheet.rb
class Stylesheet < ActiveRecord::Base
serialize :variables, JSON
def to_sass
# Convert a hash of variables into SCSS
variables.each_pair.map do |name, value|
"$#{name}: #{value};"
end.join("\n")
end
end
# example for the stylesheet model
stylesheet = Stylesheet.new
stylesheet.variables[:primary_color] = "#0000ff"
stylesheet.save
How to obtain the SASS function that associates two specific colours?
You can use online tool to find that for you such as Sass Colour Function Calculator.
In your example:
$light-green: #99E2D0;
$dark-green: darken(saturate($light-green, 44.27), 47.84);
Use SASS to create a list of classes from a list of colors with color in the class name
Hmmm, I'm not sure what you meant by "you want that output", as that's not valid CSS. The way you have it here only works for named colors, and won't work with hex values.
$color1: red;
$color2: yellow;
$color3: green;
$colors-list: $color1 $color2 $color3;
@each $current-color in $colors-list {
.#{$current-color}-bg {
background-color: $current-color;
}
.trans-#{$current-color}-bg {
background-color: rgba($current-color, 0.9);
}
}
Output:
.red-bg {
background-color: red;
}
.trans-red-bg {
background-color: rgba(255, 0, 0, 0.9);
}
.yellow-bg {
background-color: yellow;
}
.trans-yellow-bg {
background-color: rgba(255, 255, 0, 0.9);
}
.green-bg {
background-color: green;
}
.trans-green-bg {
background-color: rgba(0, 128, 0, 0.9);
}
Edit
To use with hex values you can use a map:
$color-map: (
red: #f00,
green: #0f0,
blue: #00f
);
@each $name, $color in $color-map {
.#{$name}-bg {
background: $color;
}
.#{$name}-bg-transparent {
background-color: rgba($color, 0.9);
}
}
Output:
.red-bg {
background: #f00;
}
.red-bg-transparent {
background-color: rgba(255, 0, 0, 0.9);
}
.green-bg {
background: #0f0;
}
.green-bg-transparent {
background-color: rgba(0, 255, 0, 0.9);
}
.blue-bg {
background: #00f;
}
.blue-bg-transparent {
background-color: rgba(0, 0, 255, 0.9);
}
Can't use default Bootstrap colors in Sass
use like this
@import "style/variables";
@import "node_modules/bootstrap/scss/bootstrap";
@import "style/my_other_SCSS
in variables.scss
$border-radius: 1rem;
in my_other_SCSS.scss
aside a {
color: $success;
}
this will work.
Adding different colors to linear-gradient using SASS
You can use a @for loop to help you with that case.
You create an empty string.
Then you fill that string by concatenating one line at a time. hsl(x, 100%, 50%),
Then you use that variable in your rule.
$colors : '';
@for $i from 0 through 36 {
@if ($i == 36) {
$colors : $colors + 'hsl(' + 10 * $i + ', 100%, 50%)' // Don't add the ',' if $i == 36, the last item
}
@else {
$colors : $colors + 'hsl(' + 10 * $i + ', 100%, 50%),'
}
}
input[type="range"]::-webkit-slider-runnable-track {
background: linear-gradient(
to right,
#{$colors}
);
}
Related Topics
Ruby Equivalent of PHP's ".=" (Dot Equals) Operator
In Ruby/Rails, How to Sort on a Date Value Where the Date Can Sometimes Be Null
Interested in What the "<<" Does
Ruby Regex Gsub a Line in a Text File
How Does Inheritance Work in Ruby
How to Force a Cucumber Scenario to Fail
Ruby Inside JavaScript Block [Slim Template]
Retrieve Number from the String Pattern Using Regular Expression
"Encoding::Invalidbytesequenceerror" Error Occurs in Rails 3.1.0
Errno::Econnreset: Connection Reset by Peer in Rails Using Rest-Client
Possible to Use Stylesheet.Css.Erb in Rails
Call Ruby Script from Powershell
How to Preserve Case with Http.Get
Ruby on Rails: How to Add a CSS File with Rails Project
Capybara Synchronize with Has_No_Css
How to Read Only X Number of Bytes of the Body Using Net::Http