03 Mar 2021
It’s time to learn something new. I’ve spent time working with flexbox, but haven’t explored CSS Grid. Let’s go.
I’ve noticed the most common claim to use CSS Grid is to have a 2 dimensional layout or both columns AND rows, instead of just columns OR rows.
This is the element that contains the grid. Define this by giving the element the css property
display: grid for block level grid, or
inline-grid for inline. Similar to display inline-block.
Grid Container Properties
grid-template - A shorthand for the following
- grid-template-columns, grid-template-rows
This determine the number and shape of the grid. These two rules state that there should be two columns, each with a width of 100px, and two rows, each with their height set to auto.
grid-template-columns: 100px 100px;
grid-template-rows: auto auto;
If you want gaps between the rows and column use
grid-row-gap. There is a shorthand for both properties,
- grid-template-areas This is used to spread content into multiple grid cells. Repeating the name of a grid area causes the content to span those cells.
"sidebar | . | none | ...";
- grid-area This prop is used by the grid-template-area. Give the elements this property and a name
Put it all together and it will look something like this
grid-template-columns: 100px 100px 100px 100px;
"header header header header"
"sidebar main main ."
"footer footer footer footer";
Positioning of items in the grid
Just like flexbox, the parent can specify the position of it’s children, or grid item.
- justify-items Aligns grid items along the row axis
justify-items: start | end | center | stretch;
- align-items Aligns grid items along the column axis
align-items: start | end | center | stretch;
- place-items First value sets align-items and second value sets justify-items
place-items: start end;
- justify-content Used to horizontal align the items in the grid, similar to flexbox.
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
- align-content Used to vertical align the items in the grid, similar to flexbox.
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
- place-content Sets both the align-content and justify-content properties.
place-items: start end;
Grid Items (children)
These are the children (direct descendents) of the grid container element.
Grid Item Properties
Determines the grid items location, can use a grid number or name. Can also include how many grids to span. You can think of this as the item box, and you can determine how many rows and columns it will span.
grid-row as the shorthand
grid-column-start: <number> | <name> | span <number> | span <name> | auto;
grid-column-end: <number> | <name> | span <number> | span <name> | auto;
grid-row-start: <number> | <name> | span <number> | span <name> | auto;
grid-row-end: <number> | <name> | span <number> | span <name> | auto;
grid-column: 3 / span 2;
grid-row: third-line / 4;
justify-self: start | end | center | stretch;
- align-self Aligns item vertically
align-self: start | end | center | stretch;
Now the ultimate test…try it out!
Tic Tac Toe
03 Mar 2021
An overview of development with accessibility in mind
The goal of the web was for everyone to have access to it, and should provide a positive experience from all uses from all types of visual, auditory, neurological, physical, speech, and cognitive backgrounds.
Web accessibility means websites are designed and developed so people with disabilities can use them. Often times, these websites even benefit those without disabilities, and creates a better user experience.
Visual impairment includes partial or total inability to see or perceive color contrasts
Hearing impairment includes users with reduced ability to hear
Motor skills and physical disabilities includes those with difficulty moving parts of their bodies and amking precise movements with the mouse
Photosensitive seizures, such as epilepsy, often triggered by flashing lights
Cognitive disabilities, includes users with varies levels of cognitive ability, and conditions such as dementia and dyslexia can affect this.
To work around these issues, people will use assistant technology to browse the internetr. This includes screen readers that vocalize the text on the page, speech recognition software the convert speech to text, braille terminals, and even alternitive style keyboards.
As developers, we can develop with accessibility in mind, know the best strategies to convey meaning correctly through to both the users and to assistive technology.
Make sure your site is keyboard friendly
A user should be able to access all pages, links, content, etc without the use of a mouse.
Make sure all clickable/ user interactive content is accessible with the Tab key, and should be able to jump around the website with this key.
Make sure all content is easily accessible
This can be a problem if a page contains dynamic content, which means content can change without a page refresh. Many screen readers will only “read” the site as it appears on first load.
Make users aware of when content on the page changes
Aria landmarks, these are tags you add to content in order to clearly define it on the page. You can create a dynamic content tag, such as “live region”, which enables screen readers to understand content as it changes. Another example is the main navigation header, by adding role=”navigation”, we mark it as a navigation region. However, no need to use role with HTML elements with semantic meaning, such as <ul>, try to only use with span and div. These roles will override the element’s native role.
Common Aria landmarks:
banner ( HTML5
<header>) contains the site-oriented content of each page, like the logo, usually located at the top of the page. There should only be one banner landmark per page.
complementary ( HTML5
<aside>) a section of content that complements the main content but also retains its meaning when separated from the main content
contentinfo ( HTML5
<footer>) contains content usually found in the footer of a page, like copyright and privacy statements. There should only be one contentinfo landmark per page.
form ( HTML5
<form>) contains form input elements which can be edited and submitted by the user
main ( HTML5
<main>) the main content of the page. There should only be one main landmark per page.
navigation ( HTML5
<nav>) a collection of navigation links to navigate the site or page, this can let users skip directly to specific navigations
search ( HTML5
<form> or div) a search tool
application ( HTML5
<div>) represents a unique software unit, and keyboard commands are handled by the application rather than the browser itself. This role should be used sparingly.
``aria-label` can also be added and can give more detailed information about the role type, however, not all screen readers will read the text in aria-label
<div id="nav" role="navigation" aria-label="main navigation">
<div id="nav" role="navigation" aria-label="product navigation">
aria-labelledby is used when a landmark can be labelled by another on screen element.
<div role="navigation" aria-labelledby="nav-heading">
<h2 id="nav-heading">Learn About This Product</h2>
Older browsers like IE11 doesn’t always recognize HTML5 elements and map them to a landmark role. In these cases, you can add the role manually.
Add alt text to all images
Also called alt attribute, alt descriptions, or alt tags, is accessed by screen readers to “read” the picture. Also, using this attribute can also help improve site’s SEO ( search engine crawling for info).
Choose colors carefully
Color contrast is important! Make sure text stands out against the background.
React storybook has an ally addon https://storybook.js.org/addons/@storybook/addon-a11y
Correct header definitions can help improve flow and understanding.
- You should only use one H1 per page – usually as the page title. This can be followed by subheadings starting with H2, which can then be nested further with H3, followed by H4. These should always be used in order so you should avoid using an H4 directly after an H2 (and so on).
Design your forms for accessibility
Don’t use tables for anything except tabular data
For example, you should never use a table for layouts, lists, or anything else. This can be confusing to screen readers and similar devices.
Enable resizable text that doesn’t break your site
Most browsers and devices let users resize text.
- avoid using absolute units, such as pixel
Separate content and style
use html for content, css for styles, more efficient for readers
- title every page
- use HTML5 semantic markup
- Use relative values for fonts
- Identify language (e.g., <html lang=“en”>)
- Be consistent in content that is similar on multiple pages, such as navigation
- Use headers and labels wisely, be informative
- Let users know where they are (ex. breadcrumbs, page numbers, etx)
- Use Appropriate Labels, Titles, and Values with Forms
- provide informative instructions with content that needs user input
- Provide Alternative Text for Images
- Avoid surprises, if content changes, inform the user
- Don’t create time limits on user inputs
For a more detailed checklist, visit https://webaim.org/standards/wcag/checklist
03 Mar 2020
A collection of tips I’ve collected over the years
bundle update --conservative
bundle 1.0.22 install
force ruby to use this version of bundler gem install bundler 1.17.2 -v install a bundler version
terminal ps -ef
finds all processes running on computer
| grep pipe to grep, finds word in associated file or command ps -ef | grep puma kill -9 kill process kill -9 15140
git log –all –grep=”" filter commits git log --all --grep="event stream" git branch -D `git branch --list '*'` remove branches starting with .. git branch -D `git branch --list 'SN*'`
tail -f path/to/log
watch the log tail -f log/development.log
when yarn lock has merge conflicts git rebase origin/master
git checkout origin/master – yarn.lock yarn install
git add yarn.lock git rebase –continue
23 May 2019
Upgrading to Webpacker 4 took a few extra steps for me. For those of you who also have to do some tweaking after using the babel-upgrade gem, this guide is for you!
Upgrade to Webpacker 4
bundle update webpacker
yarn upgrade @rails/webpacker --latest
yarn upgrade webpack-dev-server --latest
There is a gem that does all the changes for you, but I still had some changes to make after https://github.com/babel/babel-upgrade
Update packages in package.json, the above repo outlines the changes well.
Choose your configuration
In babel 7, the working directory is considered the root. For a project wide configuration, use a babel.config.is file in the root directory. If you have babel config for a package that is not the root, place a .babelrc file in the root of the package. You can have both types of config in a project. Config Files · Babel Babel has two parallel config file formats, which can be used together, or independently. Project-wide configuration… babeljs.io
First, what are polyfills? Polyfills enable us to write modern code, which will work in older browsers
The way babel works is that it takes the syntax, let’s say ES6, and transpiles it to syntax all browsers can understand. Such as let and const turning into var
A polyfill defines a new object or method in browsers that don’t support that object or method. There are a variety of polyfills, some examples include Map and Promise
Make sure to include @babel/polyfill as a dependency, not devDependency!
Update package renames
For all plugins, make sure to find out if it has been renamed! Yarn install and happy hacking!
23 Feb 2019
Often times software design is described as layers of a cake. These different layers are common in Object Oriented Programming, where not only is there MVC, but service objects, form objects and more. The cake needs to be sliced vertically as well. These vertical layers/sub systems are often called Bounded Contexts. The bounded context is a central pattern in Domain Driven Design. This is a solution for dealing with large models and teams. The idea is to have smaller models and clear data ownership. Think about which attributes change together in response to certain actions, and who changes those attributes. If something is bound within certain conditions, it might be its own context.
The pitfall developers fall into is adding one more attribute, one more column because we don’t see how it fits into the whole system at that time.
Application design should not be coupled directly to UI, though common in CRUD apps. It may be that the user might change different aspects on certain occasions, like a password, profile photo, address, etc. These CAN have their own submit buttons, or auto-save.
When deciding how to modularize a class, ask the following questions:
Why are they in the same db table and ActiveRecord model? Is it because they are updated on the same page?
Naming. For example, encrypted_password is not very similar to last_login_date, or avatar_image_url Coupling in updates; which attribute are often updated together business wise. Transitional consistency - which attributes need to be updated together in the same transaction. What happens if there is an error and only one command finishes, are there any consequences? Those classes with attributes that cooperate together and need to be updated together to abide by business rules are called Aggregates
When you extract attributes into smaller classes, you’ve created a bounded context!
Sometimes there is a class that can read from other things, but the problem with this is that the class is reliant on the other classes, and limited in what in what it can do. For instance, it can not remove without deleting the other record. Another solution is for data to be published from one bounded context and consumed by another bounded context, resulting in its own storage. Usually this is used when the context needs less data than what was published. Since the Active Record API is so wide, it is easy to expose data from other pats without an interface, such as using associations. This makes it difficult to know which parts of the app are reading the data. So how do you expose data from one part to another via an interface? Create an interface connecting the two parts (contexts).
describe, quantify, or measure an entity, such as Product or Order. Value objects have no identity, are are compared by the values they encapsulate, are are immutable. They are meant to pass information around, instead of passing solely attributes.
a domain object with a unique identity, usually mutable, can have a lifecycle, and attributes/value objects describing it.
a graph of domain objects you could load from the database, often seen as a cluster of objects. So if we change them, they should fully work or fail and rollback. Aggregates are used to protect business logic/requirements. The idea is to have small clusters of objects that do not easily cross each other.