Matteo Namoti

Matteo Namoti

1581926630

Top 10 Time-Saving CSS Tips When using Sass

These top 10 CSS best practices will help you save time and collaborate better with your team.

We sometimes think that we know all we need to know about SCSS and that we can give that extra time to get ahead on JavaScript.

I’m sorry to be the one breaking this to you, but you should pay more attention to your stylesheets. I’ve worked in projects where the code turned into spaghetti just because a few simple best practices weren’t applied. I quickly learned how precious some good tips can be when working with other people on a code base that can become quite large in no time.

That’s why, today, I’m sharing with you 10 SCSS best practices that will help you and your team.

Start using them, your teammates and the people who’ll later take over your code will thank you. (By the way… that’s one of the few ways you get extra points in the good place.)

Tip 1: Adopt the BEM Convention

Have you ever gotten into a project and didn’t know how to start reading or making sense of the CSS classes naming?

Yeah ♀️we’ve all been there. That’s why whenever I start a new project or join one, one of my first code style optimizations is implementing BEM and making sure that everyone follows it.

BEM stands for Block, Element, Modifiers. The added value that this CSS classes naming convention brings to the table is simple: it allows you to visualize how your template is styled in a structured way.

How it works is even simpler:

  1. You name the main blocks of your page like this for instance: class="button".

  2. Then, name the elements inside each block using two underscores (to show that it’s part of the block): class="button__icon".

  3. And in case you have a variant of that block, use two dashes to name a modifier: class="button button--red".

So in your template, it will look like this:

<button class="button button--blue">
	<img class="button__icon" src="http://www.bem-br.org/img/logo.png" alt="icon-blue"/>
	<p class="button__label">Use BEM</p>
</button>

<button class="button button--red">
	<img class="button__icon" src="http://www.bem-br.org/img/logo.png" alt="icon-red"/>
	<p class="button__label">Please use BEM</p>
</button>

Editing your styles will become much easier, because you’ll be able to visualize the structure of your code:

.button {
	border: none;
	margin: 20px;
	cursor: pointer;

	.button__icon {
		width: 20px;
		height: 20px;
	}

	.button__label {
		color: white;
		padding: 20px 40px;
		text-align: center;
		text-transform: uppercase;
		font-size: 16px;
	}

	// --> MODIFIERS: COLORS <--

	&--blue {
		background-color: blue;
	}

	&--red {
		background-color: red;
	}
}

Tip 2: Don’t Repeat Yourself, Use Variable Extrapolation for Your Block Class Names

If you follow the BEM convention (or are going to), here is another good practice you can follow to speed up your development time: using variable extrapolation. This way, you will not repeat yourself.

It’s pretty simple — you just define your block class in a variable (in the example above it was .button) and replace it using #{$c} in your CSS code.

Let’s use the example above, to see how it works:

$c: “.button” 

#{$c} {
	border: none;
	margin: 20px;
	cursor: pointer;

	&--blue {
		background-color: blue;
	}

	&--red {
		background-color: red;
	}

	#{$c}__icon {
		width: 20px;
		height: 20px;
	}

	#{$c}__label {
		color: white;
		padding: 20px 40px;
		text-align: center;
		text-transform: uppercase;
		font-size: 16px;
	}
}

It’s a small and simple improvement, but not having to rewrite your block class name every time (or just being able to update it in a single spot) speeds things up, improves code readability and makes the structure of your CSS code pop out.

Tip 3: Structure Your Project With InuitCSS

You can think of InuitCSS as a CSS framework. Even though it does not provide you with UI components or anything like that.

Instead, InuitCSS helps you normalize, configure, homogenize and structure your stylesheets.

Sounds abstract? Okay, let’s see how it does that.

First, go ahead and install InuitCSS using npm install inuitcss --save. Now all you have to do is get to know the InuitCSS-specific CSS directory structure that it provides and follow it to set structure you project’s assets:

  • /settings: This is where all your global variables, site-wide settings and configs go. For example, instead of declaring colors variables in every one of my stylesheets, I just put them and organize them in one single file under this folder.

  • /tools: The tools folder is where you define your project mixins and functions, most of the time, I use it to store the Sass mixin I use for responsive media queries.

  • /generic: Here, you can specify low-specificity CSS rules, like normalize.css and reset rulesets.

  • /elements: When you need to style unclassed HTML elements like links, pages, images, tables, and so on, you can simply create a stylesheet in this folder for that.

  • /objects: The objects folder is where you put your objects, abstractions, and design patterns like your layouts.

  • /components: This is where the style of specific UI components goes. Honestly, I never use it, simply because I code my projects with Vue.js and it uses single file components.

  • /utilities: The utilities folder is for all the high-specificity, very explicit selectors like the animations you need to use in your project.

It’s pretty neat, I know!

Tip 4: Use Datasets to Group Your Colors

If you’re using Sass loops, I definitely recommend using datasets, especially if it involves defining colors.

Let’s check this one in play by taking the example of social buttons. As you can probably guess, social buttons (Facebook, Twitter, etc.) have different colors.

So instead of having to write this:

// VARIABLES
$c: ".c-social-button";

#{$c} {
	border: none;
	border-radius: 4px;
	color: $white;
	user-select: none;
	cursor: pointer;

	// --> NETWORKS <--

	&--facebook {
		background: #3b5998;
	}

	&--google {
		background: #db4437;
	}

	&--messenger {
		background: #0084ff;
	}  

	&--twitter {
		background: #1da1f2;
	}
}

You can choose a more elegant way:

// VARIABLES
$c: ".c-social-button";
$networks: facebook, google, messenger, twitter;

// THE DATASET FOR SOCIAL COLORS
$socialColors: (
	facebook: #3b5998,
	google: #db4437,
	messenger: #db4437,
	twitter: #1da1f2
);

#{$c} {
	border: none;
	border-radius: 4px;
	color: $white;
	user-select: none;
	cursor: pointer;

	// --> NETWORKS <--
	@each $network in $networks {
		&--#{network} {
			background: map-get($socialColors, $network);
		}
	}
}

Tip #5: Adopt Veli’s Colorpedia Naming Convention

Okay, you get it and you know it: using terms like light, dark, medium and so on as a naming convention for your project colors is very limiting, simply because there are some projects where you’ll have a lot of color and this is not going to take you very far.

Instead of scratching my head about this one every time, I simply use Veli’s colorpedia. This way you’ll get to give your colors names that a human can understand while not being limited by the light/medium/dark spectrum.

Additional perks come with using Veli’s colorpedia Veli’s colorpedia — it provides you with matching colors and even tells you how a colorblind person sees it.

Some designers are just angels sent from heaven.

Tip 6: Avoid Using Mixins Everywhere

When you don’t have to use mixins, just don’t do it! Why?

Because when you use mixins, they have to be well-structured and maintained in a rigorous way. Using mixins for no good reason is the best way to get lost when the project grows. They can cause side effects and become hard to update when they are used in many places. So use them carefully.

If you don’t know whether and when to use a mixin, remember this one rule: Mixins are here to avoid repeating yourself by keeping a Single Source of Truth.

Also, as of today for example, we don’t have to use mixins to prefix CSS properties because we have plugins like PostCSS Autoprefixer that exist and do the heavy lifting for you.

Tip 7: Supercharge Your Media Queries with SASS MQ

Sass MQ is an open-source mixin crafted by developers working at The Guardian (fancy!). It’s amazing for two reasons:

  • It compiles keywords and px/em values to em-based queries, so when users zoom on your page, the content doesn’t get all scrambled up.

  • It provides fallbacks for older browsers like IE8.

It simply works by compiling this code:

$mq-breakpoints: (
	mobile: 320px,
	tablet: 740px,
	desktop: 980px,
	wide: 1300px
);

@import 'mq';

.foo {
	@include mq($from: mobile, $until: tablet) {
	background: red;
}

@include mq($from: tablet) {
	background: green;
	}
}

Into this:

@media (min-width: 20em) and (max-width: 46.24em) {
	.foo {
		background: red;
	}
}

@media (min-width: 46.25em) {
	.foo {
		background: green;
	}
}

Elegant, simple and useful. What’s not to like?

To start using it, just go ahead and follow the instructions on their GitHub page.

Tip 8: Use CSSComb

One more final thing to get you a clean CSS code. I know that each one of us has our own way of writing CSS code, but doing so will leave you steps behind when working with somebody else or a team on a project.

That’s why I use CSS Comb. I installed the extension on VSCode, and every time I start a new project I set a .csscomb.json file in its root.

This .csscomb.json file includes a configuration that transforms your CSS code and your teammate’s into one single format whenever you run the extension.

You can use my own CSS Comb configuration below, or configure your own just by choosing the way you want your CSS code to look.

Tip 9: Using Placeholders Can Often Be a Great Tool

In a project, I have a set of properties that define a dark background. I very often find myself having to type them over and over again. Here is how using a placeholder can come very handy:

// The placeholder selector
%darkbg {
	border: 1px  solid  #000000;
	background: #101010;
	box-shadow: 0  1px  5px  0  rgba(#404040, 0.6);
}

.my-dark-block-for-errors {
	@extend %darkbg;
	// Some other properties for errors
}

.my-dark-block-for-success {
	@extend %darkbg;
	// Some other properties for success
}

This will compile into the following css code:

.my-dark-block-for-errors, .my-dark-block-for-success {
	border: 1px  solid  #000000;
	background: #101010;
	box-shadow: 0  1px  5px  0  rgba(#404040, 0.6);
}

.my-dark-block-for-errors {
	// Some other properties for errors
}

.my-dark-block-for-success {
	// Some other properties for success
}

Notice how it made our two blocks extend the placeholder? No need to repeat ourselves now and to remember these properties anymore.

Tip 10: Take a Few Minutes to Browse Awesome-Sass.

Awesome-Sass is a curated list of awesome Sass and SCSS frameworks, libraries, style guides and articles. It is a fantastic resource that keeps getting updates as of today. It includes so many interesting resources and it will deepen your Sass skills just by browsing it for a few hours.

For instance, this is where I discovered the Sass Guidelines or Sassline.

I hope this article was useful. Sass will definitely save you time,

Thank you!

#sass #css #javascript #webdev #tips

What is GEEK

Buddha Community

Top 10 Time-Saving CSS Tips When using Sass
Chloe  Butler

Chloe Butler

1667425440

Pdf2gerb: Perl Script Converts PDF Files to Gerber format

pdf2gerb

Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.


pdf2gerb_cfg.pm

#Pdf2Gerb config settings:
#Put this file in same folder/directory as pdf2gerb.pl itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)


##############################################################################################
#configurable settings:
#change values here instead of in main pfg2gerb.pl file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)}Pdf2Gerb.pl ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
(
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
#traces:
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .012,
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .025,
    .030,  #heavy-current traces; be careful with these ones!
    .040,
    .050,
    .060,
    .080,
    .100,
    .120,
);
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
{
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects
};

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
{
    CIRCLE_ADJUST_MINX => 0,
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    CIRCLE_ADJUST_MAXY => 0,
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found
};

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
{
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
};
    
#number of elements in each shape type:
use constant
{
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
};
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
our %SHAPELEN =
(
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,
);

#panelization:
#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#############################################################################################
#junk/experiment:

#use Package::Constants;
#use Exporter qw(import); #https://perldoc.perl.org/Exporter.html

#my $caller = "pdf2gerb::";

#sub cfg
#{
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;
#}

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #https://www.perlmonks.org/?node_id=1072691; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code: https://github.com/swannman/pdf2gerb

License: GPL-3.0 license

#perl 

Sasha  Roberts

Sasha Roberts

1659500100

Reform: Form Objects Decoupled From Models In Ruby

Reform

Form objects decoupled from your models.

Reform gives you a form object with validations and nested setup of models. It is completely framework-agnostic and doesn't care about your database.

Although reform can be used in any Ruby framework, it comes with Rails support, works with simple_form and other form gems, allows nesting forms to implement has_one and has_many relationships, can compose a form from multiple objects and gives you coercion.

Full Documentation

Reform is part of the Trailblazer framework. Full documentation is available on the project site.

Reform 2.2

Temporary note: Reform 2.2 does not automatically load Rails files anymore (e.g. ActiveModel::Validations). You need the reform-rails gem, see Installation.

Defining Forms

Forms are defined in separate classes. Often, these classes partially map to a model.

class AlbumForm < Reform::Form
  property :title
  validates :title, presence: true
end

Fields are declared using ::property. Validations work exactly as you know it from Rails or other frameworks. Note that validations no longer go into the model.

The API

Forms have a ridiculously simple API with only a handful of public methods.

  1. #initialize always requires a model that the form represents.
  2. #validate(params) updates the form's fields with the input data (only the form, not the model) and then runs all validations. The return value is the boolean result of the validations.
  3. #errors returns validation messages in a classic ActiveModel style.
  4. #sync writes form data back to the model. This will only use setter methods on the model(s).
  5. #save (optional) will call #save on the model and nested models. Note that this implies a #sync call.
  6. #prepopulate! (optional) will run pre-population hooks to "fill out" your form before rendering.

In addition to the main API, forms expose accessors to the defined properties. This is used for rendering or manual operations.

Setup

In your controller or operation you create a form instance and pass in the models you want to work on.

class AlbumsController
  def new
    @form = AlbumForm.new(Album.new)
  end

This will also work as an editing form with an existing album.

def edit
  @form = AlbumForm.new(Album.find(1))
end

Reform will read property values from the model in setup. In our example, the AlbumForm will call album.title to populate the title field.

Rendering Forms

Your @form is now ready to be rendered, either do it yourself or use something like Rails' #form_for, simple_form or formtastic.

= form_for @form do |f|
  = f.input :title

Nested forms and collections can be easily rendered with fields_for, etc. Note that you no longer pass the model to the form builder, but the Reform instance.

Optionally, you might want to use the #prepopulate! method to pre-populate fields and prepare the form for rendering.

Validation

After form submission, you need to validate the input.

class SongsController
  def create
    @form = SongForm.new(Song.new)

    #=> params: {song: {title: "Rio", length: "366"}}

    if @form.validate(params[:song])

The #validate method first updates the values of the form - the underlying model is still treated as immutuable and remains unchanged. It then runs all validations you provided in the form.

It's the only entry point for updating the form. This is per design, as separating writing and validation doesn't make sense for a form.

This allows rendering the form after validate with the data that has been submitted. However, don't get confused, the model's values are still the old, original values and are only changed after a #save or #sync operation.

Syncing Back

After validation, you have two choices: either call #save and let Reform sort out the rest. Or call #sync, which will write all the properties back to the model. In a nested form, this works recursively, of course.

It's then up to you what to do with the updated models - they're still unsaved.

Saving Forms

The easiest way to save the data is to call #save on the form.

if @form.validate(params[:song])
  @form.save  #=> populates album with incoming data
              #   by calling @form.album.title=.
else
  # handle validation errors.
end

This will sync the data to the model and then call album.save.

Sometimes, you need to do saving manually.

Default values

Reform allows default values to be provided for properties.

class AlbumForm < Reform::Form
  property :price_in_cents, default: 9_95
end

Saving Forms Manually

Calling #save with a block will provide a nested hash of the form's properties and values. This does not call #save on the models and allows you to implement the saving yourself.

The block parameter is a nested hash of the form input.

  @form.save do |hash|
    hash      #=> {title: "Greatest Hits"}
    Album.create(hash)
  end

You can always access the form's model. This is helpful when you were using populators to set up objects when validating.

  @form.save do |hash|
    album = @form.model

    album.update_attributes(hash[:album])
  end

Nesting

Reform provides support for nested objects. Let's say the Album model keeps some associations.

class Album < ActiveRecord::Base
  has_one  :artist
  has_many :songs
end

The implementation details do not really matter here, as long as your album exposes readers and writes like Album#artist and Album#songs, this allows you to define nested forms.

class AlbumForm < Reform::Form
  property :title
  validates :title, presence: true

  property :artist do
    property :full_name
    validates :full_name, presence: true
  end

  collection :songs do
    property :name
  end
end

You can also reuse an existing form from elsewhere using :form.

property :artist, form: ArtistForm

Nested Setup

Reform will wrap defined nested objects in their own forms. This happens automatically when instantiating the form.

album.songs #=> [<Song name:"Run To The Hills">]

form = AlbumForm.new(album)
form.songs[0] #=> <SongForm model: <Song name:"Run To The Hills">>
form.songs[0].name #=> "Run To The Hills"

Nested Rendering

When rendering a nested form you can use the form's readers to access the nested forms.

= text_field :title,         @form.title
= text_field "artist[name]", @form.artist.name

Or use something like #fields_for in a Rails environment.

= form_for @form do |f|
  = f.text_field :title

  = f.fields_for :artist do |a|
    = a.text_field :name

Nested Processing

validate will assign values to the nested forms. sync and save work analogue to the non-nested form, just in a recursive way.

The block form of #save would give you the following data.

@form.save do |nested|
  nested #=> {title:  "Greatest Hits",
         #    artist: {name: "Duran Duran"},
         #    songs: [{title: "Hungry Like The Wolf"},
         #            {title: "Last Chance On The Stairways"}]
         #   }
  end

The manual saving with block is not encouraged. You should rather check the Disposable docs to find out how to implement your manual tweak with the official API.

Populating Forms

Very often, you need to give Reform some information how to create or find nested objects when validateing. This directive is called populator and documented here.

Installation

Add this line to your Gemfile:

gem "reform"

Reform works fine with Rails 3.1-5.0. However, inheritance of validations with ActiveModel::Validations is broken in Rails 3.2 and 4.0.

Since Reform 2.2, you have to add the reform-rails gem to your Gemfile to automatically load ActiveModel/Rails files.

gem "reform-rails"

Since Reform 2.0 you need to specify which validation backend you want to use (unless you're in a Rails environment where ActiveModel will be used).

To use ActiveModel (not recommended because very out-dated).

require "reform/form/active_model/validations"
Reform::Form.class_eval do
  include Reform::Form::ActiveModel::Validations
end

To use dry-validation (recommended).

require "reform/form/dry"
Reform::Form.class_eval do
  feature Reform::Form::Dry
end

Put this in an initializer or on top of your script.

Compositions

Reform allows to map multiple models to one form. The complete documentation is here, however, this is how it works.

class AlbumForm < Reform::Form
  include Composition

  property :id,    on: :album
  property :title, on: :album
  property :songs, on: :cd
  property :cd_id, on: :cd, from: :id
end

When initializing a composition, you have to pass a hash that contains the composees.

AlbumForm.new(album: album, cd: CD.find(1))

More

Reform comes many more optional features, like hash fields, coercion, virtual fields, and so on. Check the full documentation here.

Reform is part of the Trailblazer project. Please buy my book to support the development and learn everything about Reform - there's two chapters dedicated to Reform!

Security And Strong_parameters

By explicitly defining the form layout using ::property there is no more need for protecting from unwanted input. strong_parameter or attr_accessible become obsolete. Reform will simply ignore undefined incoming parameters.

This is not Reform 1.x!

Temporary note: This is the README and API for Reform 2. On the public API, only a few tiny things have changed. Here are the Reform 1.2 docs.

Anyway, please upgrade and report problems and do not simply assume that we will magically find out what needs to get fixed. When in trouble, join us on Gitter.

Full documentation for Reform is available online, or support us and grab the Trailblazer book. There is an Upgrading Guide to help you migrate through versions.

Attributions!!!

Great thanks to Blake Education for giving us the freedom and time to develop this project in 2013 while working on their project.


Author: trailblazer
Source code: https://github.com/trailblazer/reform
License:  MIT license

#ruby  #ruby-on-rails

Matteo Namoti

Matteo Namoti

1581926630

Top 10 Time-Saving CSS Tips When using Sass

These top 10 CSS best practices will help you save time and collaborate better with your team.

We sometimes think that we know all we need to know about SCSS and that we can give that extra time to get ahead on JavaScript.

I’m sorry to be the one breaking this to you, but you should pay more attention to your stylesheets. I’ve worked in projects where the code turned into spaghetti just because a few simple best practices weren’t applied. I quickly learned how precious some good tips can be when working with other people on a code base that can become quite large in no time.

That’s why, today, I’m sharing with you 10 SCSS best practices that will help you and your team.

Start using them, your teammates and the people who’ll later take over your code will thank you. (By the way… that’s one of the few ways you get extra points in the good place.)

Tip 1: Adopt the BEM Convention

Have you ever gotten into a project and didn’t know how to start reading or making sense of the CSS classes naming?

Yeah ♀️we’ve all been there. That’s why whenever I start a new project or join one, one of my first code style optimizations is implementing BEM and making sure that everyone follows it.

BEM stands for Block, Element, Modifiers. The added value that this CSS classes naming convention brings to the table is simple: it allows you to visualize how your template is styled in a structured way.

How it works is even simpler:

  1. You name the main blocks of your page like this for instance: class="button".

  2. Then, name the elements inside each block using two underscores (to show that it’s part of the block): class="button__icon".

  3. And in case you have a variant of that block, use two dashes to name a modifier: class="button button--red".

So in your template, it will look like this:

<button class="button button--blue">
	<img class="button__icon" src="http://www.bem-br.org/img/logo.png" alt="icon-blue"/>
	<p class="button__label">Use BEM</p>
</button>

<button class="button button--red">
	<img class="button__icon" src="http://www.bem-br.org/img/logo.png" alt="icon-red"/>
	<p class="button__label">Please use BEM</p>
</button>

Editing your styles will become much easier, because you’ll be able to visualize the structure of your code:

.button {
	border: none;
	margin: 20px;
	cursor: pointer;

	.button__icon {
		width: 20px;
		height: 20px;
	}

	.button__label {
		color: white;
		padding: 20px 40px;
		text-align: center;
		text-transform: uppercase;
		font-size: 16px;
	}

	// --> MODIFIERS: COLORS <--

	&--blue {
		background-color: blue;
	}

	&--red {
		background-color: red;
	}
}

Tip 2: Don’t Repeat Yourself, Use Variable Extrapolation for Your Block Class Names

If you follow the BEM convention (or are going to), here is another good practice you can follow to speed up your development time: using variable extrapolation. This way, you will not repeat yourself.

It’s pretty simple — you just define your block class in a variable (in the example above it was .button) and replace it using #{$c} in your CSS code.

Let’s use the example above, to see how it works:

$c: “.button” 

#{$c} {
	border: none;
	margin: 20px;
	cursor: pointer;

	&--blue {
		background-color: blue;
	}

	&--red {
		background-color: red;
	}

	#{$c}__icon {
		width: 20px;
		height: 20px;
	}

	#{$c}__label {
		color: white;
		padding: 20px 40px;
		text-align: center;
		text-transform: uppercase;
		font-size: 16px;
	}
}

It’s a small and simple improvement, but not having to rewrite your block class name every time (or just being able to update it in a single spot) speeds things up, improves code readability and makes the structure of your CSS code pop out.

Tip 3: Structure Your Project With InuitCSS

You can think of InuitCSS as a CSS framework. Even though it does not provide you with UI components or anything like that.

Instead, InuitCSS helps you normalize, configure, homogenize and structure your stylesheets.

Sounds abstract? Okay, let’s see how it does that.

First, go ahead and install InuitCSS using npm install inuitcss --save. Now all you have to do is get to know the InuitCSS-specific CSS directory structure that it provides and follow it to set structure you project’s assets:

  • /settings: This is where all your global variables, site-wide settings and configs go. For example, instead of declaring colors variables in every one of my stylesheets, I just put them and organize them in one single file under this folder.

  • /tools: The tools folder is where you define your project mixins and functions, most of the time, I use it to store the Sass mixin I use for responsive media queries.

  • /generic: Here, you can specify low-specificity CSS rules, like normalize.css and reset rulesets.

  • /elements: When you need to style unclassed HTML elements like links, pages, images, tables, and so on, you can simply create a stylesheet in this folder for that.

  • /objects: The objects folder is where you put your objects, abstractions, and design patterns like your layouts.

  • /components: This is where the style of specific UI components goes. Honestly, I never use it, simply because I code my projects with Vue.js and it uses single file components.

  • /utilities: The utilities folder is for all the high-specificity, very explicit selectors like the animations you need to use in your project.

It’s pretty neat, I know!

Tip 4: Use Datasets to Group Your Colors

If you’re using Sass loops, I definitely recommend using datasets, especially if it involves defining colors.

Let’s check this one in play by taking the example of social buttons. As you can probably guess, social buttons (Facebook, Twitter, etc.) have different colors.

So instead of having to write this:

// VARIABLES
$c: ".c-social-button";

#{$c} {
	border: none;
	border-radius: 4px;
	color: $white;
	user-select: none;
	cursor: pointer;

	// --> NETWORKS <--

	&--facebook {
		background: #3b5998;
	}

	&--google {
		background: #db4437;
	}

	&--messenger {
		background: #0084ff;
	}  

	&--twitter {
		background: #1da1f2;
	}
}

You can choose a more elegant way:

// VARIABLES
$c: ".c-social-button";
$networks: facebook, google, messenger, twitter;

// THE DATASET FOR SOCIAL COLORS
$socialColors: (
	facebook: #3b5998,
	google: #db4437,
	messenger: #db4437,
	twitter: #1da1f2
);

#{$c} {
	border: none;
	border-radius: 4px;
	color: $white;
	user-select: none;
	cursor: pointer;

	// --> NETWORKS <--
	@each $network in $networks {
		&--#{network} {
			background: map-get($socialColors, $network);
		}
	}
}

Tip #5: Adopt Veli’s Colorpedia Naming Convention

Okay, you get it and you know it: using terms like light, dark, medium and so on as a naming convention for your project colors is very limiting, simply because there are some projects where you’ll have a lot of color and this is not going to take you very far.

Instead of scratching my head about this one every time, I simply use Veli’s colorpedia. This way you’ll get to give your colors names that a human can understand while not being limited by the light/medium/dark spectrum.

Additional perks come with using Veli’s colorpedia Veli’s colorpedia — it provides you with matching colors and even tells you how a colorblind person sees it.

Some designers are just angels sent from heaven.

Tip 6: Avoid Using Mixins Everywhere

When you don’t have to use mixins, just don’t do it! Why?

Because when you use mixins, they have to be well-structured and maintained in a rigorous way. Using mixins for no good reason is the best way to get lost when the project grows. They can cause side effects and become hard to update when they are used in many places. So use them carefully.

If you don’t know whether and when to use a mixin, remember this one rule: Mixins are here to avoid repeating yourself by keeping a Single Source of Truth.

Also, as of today for example, we don’t have to use mixins to prefix CSS properties because we have plugins like PostCSS Autoprefixer that exist and do the heavy lifting for you.

Tip 7: Supercharge Your Media Queries with SASS MQ

Sass MQ is an open-source mixin crafted by developers working at The Guardian (fancy!). It’s amazing for two reasons:

  • It compiles keywords and px/em values to em-based queries, so when users zoom on your page, the content doesn’t get all scrambled up.

  • It provides fallbacks for older browsers like IE8.

It simply works by compiling this code:

$mq-breakpoints: (
	mobile: 320px,
	tablet: 740px,
	desktop: 980px,
	wide: 1300px
);

@import 'mq';

.foo {
	@include mq($from: mobile, $until: tablet) {
	background: red;
}

@include mq($from: tablet) {
	background: green;
	}
}

Into this:

@media (min-width: 20em) and (max-width: 46.24em) {
	.foo {
		background: red;
	}
}

@media (min-width: 46.25em) {
	.foo {
		background: green;
	}
}

Elegant, simple and useful. What’s not to like?

To start using it, just go ahead and follow the instructions on their GitHub page.

Tip 8: Use CSSComb

One more final thing to get you a clean CSS code. I know that each one of us has our own way of writing CSS code, but doing so will leave you steps behind when working with somebody else or a team on a project.

That’s why I use CSS Comb. I installed the extension on VSCode, and every time I start a new project I set a .csscomb.json file in its root.

This .csscomb.json file includes a configuration that transforms your CSS code and your teammate’s into one single format whenever you run the extension.

You can use my own CSS Comb configuration below, or configure your own just by choosing the way you want your CSS code to look.

Tip 9: Using Placeholders Can Often Be a Great Tool

In a project, I have a set of properties that define a dark background. I very often find myself having to type them over and over again. Here is how using a placeholder can come very handy:

// The placeholder selector
%darkbg {
	border: 1px  solid  #000000;
	background: #101010;
	box-shadow: 0  1px  5px  0  rgba(#404040, 0.6);
}

.my-dark-block-for-errors {
	@extend %darkbg;
	// Some other properties for errors
}

.my-dark-block-for-success {
	@extend %darkbg;
	// Some other properties for success
}

This will compile into the following css code:

.my-dark-block-for-errors, .my-dark-block-for-success {
	border: 1px  solid  #000000;
	background: #101010;
	box-shadow: 0  1px  5px  0  rgba(#404040, 0.6);
}

.my-dark-block-for-errors {
	// Some other properties for errors
}

.my-dark-block-for-success {
	// Some other properties for success
}

Notice how it made our two blocks extend the placeholder? No need to repeat ourselves now and to remember these properties anymore.

Tip 10: Take a Few Minutes to Browse Awesome-Sass.

Awesome-Sass is a curated list of awesome Sass and SCSS frameworks, libraries, style guides and articles. It is a fantastic resource that keeps getting updates as of today. It includes so many interesting resources and it will deepen your Sass skills just by browsing it for a few hours.

For instance, this is where I discovered the Sass Guidelines or Sassline.

I hope this article was useful. Sass will definitely save you time,

Thank you!

#sass #css #javascript #webdev #tips

Lokesh Kumar

1603438098

Top 10 Trending Technologies Must Learn in 2021 | igmGuru

Technology has taken a place of more productiveness and give the best to the world. In the current situation, everything is done through the technical process, you don’t have to bother about doing task, everything will be done automatically.This is an article which has some important technologies which are new in the market are explained according to the career preferences. So let’s have a look into the top trending technologies followed in 2021 and its impression in the coming future in the world.

  1. Data Science
    First in the list of newest technologies is surprisingly Data Science. Data Science is the automation that helps to be reasonable for complicated data. The data is produces in a very large amount every day by several companies which comprise sales data, customer profile information, server data, business data, and financial structures. Almost all of the data which is in the form of big data is very indeterminate. The character of a data scientist is to convert the indeterminate datasets into determinate datasets. Then these structured data will examine to recognize trends and patterns. These trends and patterns are beneficial to understand the company’s business performance, customer retention, and how they can be enhanced.

  2. DevOps
    Next one is DevOps, This technology is a mixture of two different things and they are development (Dev) and operations (Ops). This process and technology provide value to their customers in a continuous manner. This technology plays an important role in different aspects and they can be- IT operations, development, security, quality, and engineering to synchronize and cooperate to develop the best and more definitive products. By embracing a culture of DevOps with creative tools and techniques, because through that company will gain the capacity to preferable comeback to consumer requirement, expand the confidence in the request they construct, and accomplish business goals faster. This makes DevOps come into the top 10 trending technologies.

  3. Machine learning
    Next one is Machine learning which is constantly established in all the categories of companies or industries, generating a high command for skilled professionals. The machine learning retailing business is looking forward to enlarging to $8.81 billion by 2022. Machine learning practices is basically use for data mining, data analytics, and pattern recognition. In today’s scenario, Machine learning has its own reputed place in the industry. This makes machine learning come into the top 10 trending technologies. Get the best machine learning course and make yourself future-ready.

To want to know more click on Top 10 Trending Technologies in 2021

You may also read more blogs mentioned below

How to Become a Salesforce Developer

Python VS R Programming

The Scope of Hadoop and Big Data in 2021

#top trending technologies #top 10 trending technologies #top 10 trending technologies in 2021 #top trending technologies in 2021 #top 5 trending technologies in 2021 #top 5 trending technologies

anita maity

anita maity

1618667723

Sidebar Menu Using Only HTML and CSS | Side Navigation Bar

how to create a Sidebar Menu using HTML and CSS only. Previously I have shared a Responsive Navigation Menu Bar using HTML & CSS only, now it’s time to create a Side Navigation Menu Bar that slides from the left or right side.

Demo

#sidebar menu using html css #side navigation menu html css #css side navigation menu bar #,pure css sidebar menu #side menu bar html css #side menu bar using html css