By default subscript (<sub></sub>
) and superscript (<sup></sup>
) tags are styled with vertical-align: sub
, respectively vertical-align: super
by most browsers.
However, without adaptations, this will probably break your line-heights.
A common suggestion is to style those two tags accordingly:
sup, sub {
vertical-align: baseline;
position: relative;
top: -0.4em; /* can be adapted according to preferences */
}
sub {
...
You have some SVG files you want to use as icons on your website. How would you embed them?
Common options are:
<img src='path-to-icon.svg'>
<svg>$ICON</svg>
background-image: url(path-to-icon.svg)
or even background-image: url(data:$ICON)
.All of these have drawbacks:
background-image
do not allow to recolor the image using CSS.<svg>
are unnecessary work for the server and are...In esbuild, you usually import other files using relative paths:
import './some-related-module'
import `../../utils/some-utility-module`
import `../../../css/some-css.sass`
This is totally fine if you import closely related files, but a bit clunky when you're trying to import some "global" module, like a utility module. When moving a file, your imports also need to change.
To get around this, esbuild support a mechanism first introduced in TypeScript called "path aliases". It works like this:
First, you create a file called `js...
Jasmine specs for the frontend often need some DOM elements to work with. Because creating them is such a common task, we should have an efficient way to do it.
Let's say I need this HTML structure:
<ul type="square">
<li>item 1</li>
<li>item 2</li>
</ul>
This card compares various approaches to fabricating DOM elements for testing.
While you can use standard DOM functions to individually create and append elements, this is extremely verbose:
let list = document.createElement('...
tl;dr
In Chrome DevTools in the Layouts tab you have handy options to debug CSS Flexbox and Grid. Including:
- Display size and lines along with labels
- Changing their attributes
- Change how overlay is colored and fastly switch nested elements in the Elements panel
This guide will only cover some example gif recordings on how to use with Grid, since it's basically straight forward to apply this for Flexbox by yourself afterwards.
For this purpose a the link to documentation and a simple code pen have been added...
While in CSS zero is usually referenced without specifying a unit (e.g. padding: 0
), you must not use a unitless zero in calc
functions.
You would probably not write something like calc(1rem + 0)
yourself, but it might be the result of a CSS preprocessor (like Sass) or when using custom properties.
The following is invalid:
.example {
--extra-padding: 0;
padding: calc(1rem + var(--extra-padding));
}
That is simply because it is unsupported, as per docum...
tl;dr
The Chrome DevTools are a neat collection of tools for the daily work as a web developer. If you're lucky, you'll maybe find some handy stuff in here.
TLDR: sass >= 1.35.0
has the option quietDeps
to silence deprecation warnings from dependencies.
quietDeps: If true, the compiler must not print deprecation warnings
for stylesheets that are transitively loaded through an import path or importer.
You might have seen deprecation warnings like this during assets compilation:
DEPRECATION WARNING: Using / for division is deprecated and will be removed in Dart Sass 2.0.0.
Recommendation: math.div($grid-gutter-width, 2)
More info and automated migrator: https://sass-la...
When writing a Sass function, you may run into an error message that may be confusing:
@function rules may not contain style rules.
What Sass is trying to tell you is that a line in your Sass function is computing a result that is neither assigned to a variable nor returned.
Keep in mind that all functions in Sass return something, Sass does not mutate objects.
When you build a JSON API you need to come up with a style to represent attributes, pagination, errors or including associated objects. Instead of reinventing the wheel, you may reuse successful API designs.
JSON:API specifies common features found in most JSON APIs, like pagination, ordering and nested resources. The spec looks very similar to how one would build an API with Rails and uses similar patterns. Even if you don't plan on supporting the whole spec, it can still make sense to know how th...
tl;dr
The
:is()
pseudo selector - specificity of its most specific argument - matches against a comma-separated list of selectors.
Compound selectors like ...
.datepicker .prev, .datepicker .next, .datepicker .switch
padding-bottom: 1rem
ul li, ol li
list-style-type: none
can be simplified by using the :is()
pseudo selector ...
.datepicker :is(.prev, .next, .switch)
padding-bottom: 1rem
:is(ul, ol) li
list-style-type: none
Hint
The specificity of
:is()
is equals t...
tl;dr
The
:where()
pseudo selector - zero specificity - matches against a comma-separated list of selectors.
Compound selectors like ...
.datepicker .prev, .datepicker .next, .datepicker .switch
padding-bottom: 1rem
ul li, ol li
list-style-type: none
can be simplified by using the :where()
pseudo selector ...
.datepicker :where(.prev, .next, .switch)
padding-bottom: 1rem
:where(ul, ol) li
list-style-type: none
Hint
The specificity of
:where()
is always zero!I...
The inset CSS property is a shorthand that corresponds to the top, right, bottom, and/or left properties. It has the same multi-value syntax of the margin shorthand.
<div class="outer">
<div class="inner">
Some text
</div>
</div>
.outer {
background-color: cyan;
position: relative;
width: 500px;
height: 500px;
}
https://jsfiddle.net/jqx68wem/
.inner {
background-color: darkCyan;
position: absolute;
top: 10px;
right: 10px;
bottom: 10p...
I recently had the problem that embedded code boxes crashed my layout.
It turned out that pre
s break out of their containers when using them inside a deeper nested flex layout.
For me it was a flex inside a flex item (fleXzibit).
<div class="flex">
<div class="flex-item">
...
<div class="nested-flex">
<div class="nested-flex-item">
<pre>A code example</pre>
</div>
</div>
...
</div>
</div>
The reason is that flexbox items default to `mi...
To ensure a consistent code style for JavaScript code, we use ESLint. The workflow is similar to integrating rubocop for Ruby code.
You can add the following lines to your package.json
under devDependencies
:
"devDependencies": {
"eslint": "^8.7.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-node"...
This are the steps I needed to do to add esbuild to an application that used the vanilla rails asset pipeline with sprockets before.
.nvmrc
with your preferred node version (and install it)jsbundling-rails
and foreman
to your Gemfile
:
gem 'jsbundling-rails'
group :development, :test do
gem 'foreman'
# ...
end
bundle install
bin/rails javascript:install:esbuild
in a console to prepare esbuild.yarn install
...When Capybara locates elements in the DOM, by default it allows only accessing visible elements -- when you are using a driver that supports it (e.g. Selenium, not the default Rack::Test
driver).
Consider the following HTML:
<div class="test1">One<div>
<div class="test2">Two</div>
With some CSS:
.test1 { display: block }
.test2 { display: none }
We will be using Capybara's find
below, but this applies to any Capybara finder methods.
visible: :visible
or visible: true
As described above, by defa...
An element with display: grid
can define its grid-template-columns
based on (preferred) child width using the repeat
function with auto-fill
or auto-fit
, like so:
grid-template-columns: repeat(auto-fit, 100px)
auto-fill
and auto-fit
behave differently if you use rules with dynamic sizing, like minmax(100px, 1fr)
. Simply put, auto-fill
will create as many columns as possible, including empty ones, while auto-fit
hides empty columns.
See the linked page for more details.
Modern versions of Capybara include a finder method #ancestor
which allows you to find a parental element using CSS or XPath.
If you previously did something like this:
field.find(:xpath, './ancestor::div[contains(@class, "form-group")]')
..and prefer CSS, you may rewrite it:
field.ancestor('div.form-group')
Both versions will return the outermost matching element. Use the #order
option find the closest parent:
field.ancestor('div.form-group', order: :reverse)
You want to use <input type="number">
fields in your applications.
However, your desktop users may encounter some weird quirks:
to_i
in Ruby) you'll end up with wrong values (like 1 instead o...Debugging in CSS means figuring out what might be the problem when you have unexpected layout results. We’ll look at a few categories bugs often fit into, see how we can evaluate the situation, and explore techniques that help prevent these bugs.
Event delegation is a pattern where a container element has a single event listener that handles events for all descendants that match a CSS selector.
This pattern was popularized by jQuery that lets you do this:
$('.container').on('click', '.message', function(event) {
console.log("A message element was clicked!")
})
This technique has some advantages:
Besides their default styling properties, HTML elements have a semantic meaning. For example, an h1
tag is usually styled with a larger font and bold, while it denotes "the single most important headline in its context".
While CSS enables us to style almost any HTML element like anything that is needed, choosing HTML elements corresponding to the meaning of their content has a few advantages: