#framework:
Explore tagged Tumblr posts
jcmarchi · 2 months ago
Text
Tailwind’s @apply Feature is Better Than it Sounds
New Post has been published on https://thedigitalinsider.com/tailwinds-apply-feature-is-better-than-it-sounds/
Tailwind’s @apply Feature is Better Than it Sounds
Tumblr media Tumblr media
By this point, it’s not a secret to most people that I like Tailwind.
But, unknown to many people (who often jump to conclusions when you mention Tailwind), I don’t like vanilla Tailwind. In fact, I find most of it horrible and I shall refrain from saying further unkind words about it.
But I recognize and see that Tailwind’s methodology has merits — lots of them, in fact — and they go a long way to making your styles more maintainable and performant.
Today, I want to explore one of these merit-producing features that has been severely undersold — Tailwind’s @apply feature.
What @apply does
Tailwind’s @apply features lets you “apply” (or simply put, copy-and-paste) a Tailwind utility into your CSS.
Most of the time, people showcase Tailwind’s @apply feature with one of Tailwind’s single-property utilities (which changes a single CSS declaration). When showcased this way, @apply doesn’t sound promising at all. It sounds downright stupid. So obviously, nobody wants to use it.
/* Input */ .selector @apply p-4; /* Output */ .selector padding: 1rem;
To make it worse, Adam Wathan recommends against using @apply, so the uptake couldn’t be worse.
Confession: The `apply` feature in Tailwind basically only exists to trick people who are put off by long lists of classes into trying the framework.
You should almost never use it 😬
Reuse your utility-littered HTML instead.https://t.co/x6y4ksDwrt
— Adam Wathan (@adamwathan) February 9, 2020
Personally, I think Tailwind’s @apply feature is better than described.
Tailwind’s @apply is like Sass’s @includes
If you have been around during the time where Sass is the dominant CSS processing tool, you’ve probably heard of Sass mixins. They are blocks of code that you can make — in advance — to copy-paste into the rest of your code.
To create a mixin, you use @mixin
To use a mixin, you use @includes
// Defining the mixin @mixin some-mixin() color: red; background: blue; // Using the mixin .selector @include some-mixin(); /* Output */ .selector color: red; background: blue;
Tailwind’s @apply feature works the same way. You can define Tailwind utilities in advance and use them later in your code.
/* Defining the utility */ @utility some-utility color: red; background: blue; /* Applying the utility */ .selector @apply some-utility; /* Output */ .selector color: red; background: blue;
Tailwind utilities are much better than Sass mixins
Tailwind’s utilities can be used directly in the HTML, so you don’t have to write a CSS rule for it to work.
@utility some-utility color: red; background: blue;
<div class="some-utility">...</div>
On the contrary, for Sass mixins, you need to create an extra selector to house your @includes before using them in the HTML. That’s one extra step. Many of these extra steps add up to a lot.
@mixin some-mixin() color: red; background: blue; .selector @include some-mixin(); /* Output */ .selector color: red; background: blue;
<div class="selector">...</div>
Tailwind’s utilities can also be used with their responsive variants. This unlocks media queries straight in the HTML and can be a superpower for creating responsive layouts.
<div class="utility1 md:utility2">…</div>
A simple and practical example
One of my favorite — and most easily understood — examples of all time is a combination of two utilities that I’ve built for Splendid Layouts (a part of Splendid Labz):
vertical: makes a vertical layout
horizontal: makes a horizontal layout
Defining these two utilities is easy.
For vertical, we can use flexbox with flex-direction set to column.
For horizontal, we use flexbox with flex-direction set to row.
@utility horizontal display: flex; flex-direction: row; gap: 1rem; @utility vertical display: flex; flex-direction: column; gap: 1rem;
After defining these utilities, we can use them directly inside the HTML. So, if we want to create a vertical layout on mobile and a horizontal one on tablet or desktop, we can use the following classes:
<div class="vertical sm:horizontal">...</div>
For those who are new to Tailwind, sm: here is a breakpoint variant that tells Tailwind to activate a class when it goes beyond a certain breakpoint. By default, sm is set to 640px, so the above HTML produces a vertical layout on mobile, then switches to a horizontal layout at 640px.
If you prefer traditional CSS over composing classes like the example above, you can treat @apply like Sass @includes and use them directly in your CSS.
<div class="your-layout">...</div>
.your-layout @apply vertical; @media (width >= 640px) @apply horizontal;
The beautiful part about both of these approaches is you can immediately see what’s happening with your layout — in plain English — without parsing code through a CSS lens. This means faster recognition and more maintainable code in the long run.
Tailwind’s utilities are a little less powerful compared to Sass mixins
Sass mixins are more powerful than Tailwind utilities because:
They let you use multiple variables.
They let you use other Sass features like @if and @for loops.
@mixin avatar($size, $circle: false) width: $size; height: $size; @if $circle border-radius: math.div($size, 2);
On the other hand, Tailwind utilities don’t have these powers. At the very maximum, Tailwind can let you take in one variable through their functional utilities.
/* Tailwind Functional Utility */ @utility tab-* tab-size: --value(--tab-size-*);
Fortunately, we’re not affected by this “lack of power” much because we can take advantage of all modern CSS improvements — including CSS variables. This gives you a ton of room to create very useful utilities.
Let’s go through another example
A second example I often like to showcase is the grid-simple utility that lets you create grids with CSS Grid easily.
We can declare a simple example here:
@utility grid-simple display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); gap: var(--gap, 1rem);
By doing this, we have effectively created a reusable CSS grid (and we no longer have to manually declare minmax everywhere).
After we have defined this utility, we can use Tailwind’s arbitrary properties to adjust the number of columns on the fly.
<div class="grid-simple [--cols:3]"> <div class="item">...</div> <div class="item">...</div> <div class="item">...</div> </div>
To make the grid responsive, we can add Tailwind’s responsive variants with arbitrary properties so we only set --cols:3 on a larger breakpoint.
<div class="grid-simple sm:[--cols:3]"> <div class="item">...</div> <div class="item">...</div> <div class="item">...</div> </div>
This makes your layouts very declarative. You can immediately tell what’s going on when you read the HTML.
Now, on the other hand, if you’re uncomfortable with too much Tailwind magic, you can always use @apply to copy-paste the utility into your CSS. This way, you don’t have to bother writing repeat and minmax declarations every time you need a grid that grid-simple can create.
.your-layout @apply grid-simple; @media (width >= 640px) --cols: 3;
<div class="your-layout"> ... </div>
By the way, using @apply this way is surprisingly useful for creating complex layouts! But that seems out of scope for this article so I’ll be happy to show you an example another day.
Wrapping up
Tailwind’s utilities are very powerful by themselves, but they’re even more powerful if you allow yourself to use @apply (and allow yourself to detach from traditional Tailwind advice). By doing this, you gain access to Tailwind as a tool instead of it being a dogmatic approach.
To make Tailwind’s utilities even more powerful, you might want to consider building utilities that can help you create layouts and nice visual effects quickly and easily.
I’ve built a handful of these utilities for Splendid Labz and I’m happy to share them with you if you’re interested! Just check out Splendid Layouts to see a subset of the utilities I’ve prepared.
By the way, the utilities I showed you above are watered-down versions of the actual ones I’m using in Splendid Labz.
One more note: When writing this, Splendid Layouts work with Tailwind 3, not Tailwind 4. I’m working on a release soon, so sign up for updates if you’re interested!
0 notes
389 · 1 year ago
Photo
Tumblr media
PORTO ROCHA
1K notes · View notes
bartleby-company · 3 months ago
Photo
Tumblr media
(vía Another America 50 by Phillip Toledano)
79 notes · View notes
70sscifiart · 2 years ago
Photo
Tumblr media
One of my favorites by Paul Lehr, used as a 1971 cover to "Earth Abides," by George R. Stewart. It's also in my upcoming art book!
1K notes · View notes
taizooo · 9 months ago
Quote
もともとは10年ほど前にTumblrにすごくハマっていて。いろんな人をフォローしたらかっこいい写真や色が洪水のように出てきて、もう自分で絵を描かなくて良いじゃん、ってなったんです。それで何年も画像を集めていって、そこで集まった色のイメージやモチーフ、レンズの距離感など画面構成を抽象化して、いまの感覚にアウトプットしています。画像の持つ情報量というものが作品の影響になっていますね。
映画『きみの色』山田尚子監督×はくいきしろい対談。嫉妬し合うふたりが語る、色と光の表現|Tokyo Art Beat
155 notes · View notes
nevver · 7 months ago
Photo
Tumblr media Tumblr media Tumblr media
No one wants to be here and no one wants to leave, Dave Smith (because)
111 notes · View notes
giftofgabber · 19 days ago
Text
don’t call me whiny baby if you didn’t care about my whiny baby feelings already, which you didn’t care about!!! shocker!!!
53 notes · View notes
jcmarchi · 5 months ago
Text
What on Earth is the `types` Descriptor in View Transitions?
New Post has been published on https://thedigitalinsider.com/what-on-earth-is-the-types-descriptor-in-view-transitions/
What on Earth is the `types` Descriptor in View Transitions?
Have you ever stumbled upon something new and went to research it just to find that there is little-to-no information about it? It’s a mixed feeling: confusing and discouraging because there is no apparent direction, but also exciting because it’s probably new to lots of people, not just you. Something like that happened to me while writing an Almanac’s entry for the @view-transition at-rule and its types descriptor.
You may already know about Cross-Document View Transitions: With a few lines of CSS, they allow for transitions between two pages, something that in the past required a single-app framework with a side of animation library. In other words, lots of JavaScript.
To start a transition between two pages, we have to set the @view-transition at-rule’s navigation descriptor to auto on both pages, and that gives us a smooth cross-fade transition between the two pages. So, as the old page fades out, the new page fades in.
@view-transition navigation: auto;
That’s it! And navigation is the only descriptor we need. In fact, it’s the only descriptor available for the @view-transition at-rule, right? Well, turns out there is another descriptor, a lesser-known brother, and one that probably envies how much attention navigation gets: the types descriptor.
What do people say about types?
Cross-Documents View Transitions are still fresh from the oven, so it’s normal that people haven’t fully dissected every aspect of them, especially since they introduce a lot of new stuff: a new at-rule, a couple of new properties and tons of pseudo-elements and pseudo-classes. However, it still surprises me the little mention of types. Some documentation fails to even name it among the valid  @view-transition descriptors. Luckily, though, the CSS specification does offer a little clarification about it:
The types descriptor sets the active types for the transition when capturing or performing the transition.
To be more precise, types can take a space-separated list with the names of the active types (as <custom-ident>), or none if there aren’t valid active types for that page.
Name: types
For: @view-transition
Value: none | <custom-ident>+
Initial: none
So the following values would work inside types:
@view-transition navigation: auto; types: bounce; /* or a list */ @view-transition navigation: auto; types: bounce fade rotate;
Yes, but what exactly are “active” types? That word “active” seems to be doing a lot of heavy lifting in the CSS specification’s definition and I want to unpack that to better understand what it means.
Active types in view transitions
The problem: A cross-fade animation for every page is good, but a common thing we need to do is change the transition depending on the pages we are navigating between. For example, on paginated content, we could slide the content to the right when navigating forward and to the left when navigating backward. In a social media app, clicking a user’s profile picture could persist the picture throughout the transition. All this would mean defining several transitions in our CSS, but doing so would make them conflict with each other in one big slop. What we need is a way to define several transitions, but only pick one depending on how the user navigates the page.
The solution: Active types define which transition gets used and which elements should be included in it. In CSS, they are used through :active-view-transition-type(), a pseudo-class that matches an element if it has a specific active type. Going back to our last example, we defined the document’s active type as bounce. We could enclose that bounce animation behind an :active-view-transition-type(bounce), such that it only triggers on that page.
/* This one will be used! */ html:active-view-transition-type(bounce) &::view-transition-old(page) /* Custom Animation */ &::view-transition-new(page) /* Custom Animation */
This prevents other view transitions from running if they don’t match any active type:
/* This one won't be used! */ html:active-view-transition-type(slide) &::view-transition-old(page) /* Custom Animation */ &::view-transition-new(page) /* Custom Animation */
I asked myself whether this triggers the transition when going to the page, when out of the page, or in both instances. Turns out it only limits the transition when going to the page, so the last bounce animation is only triggered when navigating toward a page with a bounce value on its types descriptor, but not when leaving that page. This allows for custom transitions depending on which page we are going to.
The following demo has two pages that share a stylesheet with the bounce and slide view transitions, both respectively enclosed behind an :active-view-transition-type(bounce) and :active-view-transition-type(slide) like the last example. We can control which page uses which view transition through the types descriptor.
The first page uses the bounce animation:
@view-transition navigation: auto; types: bounce;
The second page uses the slide animation:
@view-transition navigation: auto; types: slide;
You can visit the demo here and see the full code over at GitHub.
The types descriptor is used more in JavaScript
The main problem is that we can only control the transition depending on the page we’re navigating to, which puts a major cap on how much we can customize our transitions. For instance, the pagination and social media examples we looked at aren’t possible just using CSS, since we need to know where the user is coming from. Luckily, using the types descriptor is just one of three ways that active types can be populated. Per spec, they can be:
Passed as part of the arguments to startViewTransition(callbackOptions)
Mutated at any time, using the transition’s types
Declared for a cross-document view transition, using the types descriptor.
The first option is when starting a view transition from JavaScript, but we want to trigger them when the user navigates to the page by themselves (like when clicking a link). The third option is using the types descriptor which we already covered. The second option is the right one for this case! Why? It lets us set the active transition type on demand, and we can perform that change just before the transition happens using the pagereveal event. That means we can get the user’s start and end page from JavaScript and then set the correct active type for that case.
I must admit, I am not the most experienced guy to talk about this option, so once I demo the heck out of different transitions with active types I’ll come back with my findings! In the meantime, I encourage you to read about active types here if you are like me and want more on view transitions:
0 notes
389 · 1 year ago
Photo
Tumblr media
PORTO ROCHA
773 notes · View notes
theroyalweekly · 3 months ago
Photo
Tumblr media
Beautiful photo of the Princess of Wales departing Westminster Abbey after attending the Commonwealth Day Service. --
84 notes · View notes
mellowlike · 7 months ago
Photo
Tumblr media
齋藤飛鳥
60 notes · View notes
goodvibesandmemes · 1 year ago
Text
GENERAL MEMES: Vampire/Immortal Themed 🩸🦇🌹
↳ Please feel free to tweak them.
Themes: violence, death, blood, murder, depression/negative thoughts
SYMBOLS: ↳ Use “↪”to reverse the characters where applicable!
🦇 - To catch my muse transforming into a bat 🌞 - To warn my muse about/see my muse in the sunlight. 🩸 - To witness my muse drinking blood from a bag. 🐇 - To witness To catch my muse drinking blood from an animal. 🧔🏽 - To witness To catch my muse drinking blood from a human. 🦌 - For our muses hunt together for the first time. 🏃🏿‍♀️ - To see my muse using super speed. 🏋🏼‍♂️ - To see my muse using their super strength. 🧛🏻‍♂️ - To confront my muse about being a vampire. 🌕 - For my muse to lament missing the sun. ⏰ - For my muse to tell yours about a story from their long, immortal life. 🤛🏽 - To offer my muse your wrist to drink from. 👩🏿 - For my muse to reminisce about a long lost love. 👩🏽‍🤝‍👩🏽 - For your muse to look exactly like my muse's lost love. 👄 - For my muse to bite yours. 👀 - For my muse to glamour/compel yours. 🧄 - To try and sneakily feed my muse garlic to test if they're a vampire. 🔗 - To try and apprehend my muse with silver chains. 🔪 - To try and attack my muse with a wooden stake. 👤 - To notice that my muse doesn't have a reflection. 🌹 - For my muse to turn yours into a vampire. 🌚 - For my muse and yours to spend time together during the night. 🧛🏼‍♀️ - For my muse to tell yours about their maker/sire.
SENTENCES:
"I've been alive for a long time [ name ], I can handle myself." "I'm over a thousand years old, you can't stop me!" "Lots of windows in this place, not exactly the greatest place for a vampire." "Do you really drink human blood? Don't you feel guilty?" "Vampires are predators, [ name ] hunting is just part of our nature, you can't change that." "You just killed that person! You're a monster!" "Tomorrow at dawn, you'll meet the sun [ name ]." "Can you make me like you?" "Do you really want to live forever?" "You say you want to live forever, [ name ], but forever is a long time, longer than you can imagine." "What was it like to live through [ historic event / time period ]?" "Did people really dress like that when you were young?" "What were you like when you were human?" "We’re vampires, [ name ], we have no soul to save, and I don’t care." "How many people have you killed? You can tell me, I can handle it." "Did you meet [ historic figure ]?" "Everyone dies in the end, what does it matter if I... speed it along." "Every time we feed that person is someone's mother, brother, sister, husband. You better start getting used to that if you want to survive this life." "[ she is / he is / they are ] the strongest vampire anyone has heard of, no one knows how to stop them, and if you try you're going to get yourselves killed." "Vampire hunters are everywhere in this city, you need to watch your back." "Humans will never understand the bond a vampire has with [ his / her / their ] maker, it's a bond like no other." "Here, have this ring, it will protect you from the sunlight." "I get you're an immortal creature of the night and all that, but do you have to be such a downer about it?" "In my [ centuries / decades / millennia ] of living, do you really think no one has tried to kill me before?" "Vampires aren't weakened by garlic, that's a myth." "I used to be a lot worse than I was now, [ name ], I've had time to mellow, to become used to what I am. I'm ashamed of the monster I was." "The worst part of living forever is watching everyone you love die, while you stay frozen, still, constant." "I've lived so long I don't feel anything any more." "Are there more people like you? How many?" "Life has never been fair, [ name ], why would start being fair now you're immortal?" "You want to be young forever? Knock yourself out, I just hope you understand what you're giving up." "You never told me who turned you into a vampire. Who were they? Why did they do it?" "I could spend an eternity with you and never get bored." "Do you really sleep in coffins?" "There are worse things for a vampire than death, of that I can assure you [ name ]." "You need to feed, it's been days. You can drink from me, I can tell you're hungry." "The process of becoming a vampire is risky, [ name ], you could die, and I don't know if I could forgive myself for killing you." "I'm a vampire, I can hold a grudge for a long time, so believe me when I say I will never forgive this. Never." "You were human once! How can you have no empathy?" "You don't have to kill to be a vampire, but what would be the fun in that." "You can spend your first years of immortality doing whatever you want to whoever you want, but when you come back to your senses, it'll hit you harder than anything you've felt before." "One day, [ name ], everything you've done is going to catch up to you, and you're never going to forgive yourself." "Stop kidding yourself, [ name ], you're a vampire, a killer, a predator. You might as well embrace it now because you can't keep this up forever." "You can't [ compel / glamour ] me, I have something to protect me." "When you've lived as long as me, there's not much more in life you can do." "You want me to turn you? You don't know what you're asking me to do." "You really have to stop hissing like that, it's getting on my nerves." "I'm going to drive this stake through your heart, [ name ], and I'm going to enjoy it."
172 notes · View notes
shitakeo33 · 8 months ago
Quote
よく「発明は1人でできる。製品化には10人かかる。量産化には100人かかる」とも言われますが、実際に、私はネオジム磁石を1人で発明しました。製品化、量産化については住友特殊金属の仲間たちと一緒に、短期間のうちに成功させました。82年に発明し、83年から生産が始まったのですから、非常に早いです。そしてネオジム磁石は、ハードディスクのVCM(ボイスコイルモーター)の部品などの電子機器を主な用途として大歓迎を受け、生産量も年々倍増して、2000年には世界で1万トンを超えました。
世界最強「ネオジム磁石はこうして見つけた」(佐川眞人 氏 / インターメタリックス株式会社 代表取締役社長) | Science Portal - 科学技術の最新情報サイト「サイエンスポータル」
81 notes · View notes
nevver · 1 year ago
Photo
Tumblr media Tumblr media
Arts & Architecture, Sander Patelski
267 notes · View notes
whencyclopedia · 4 months ago
Photo
Tumblr media
The Delian League, Part 2: From Eurymedon to the Thirty Years Peace (465/4-445/4 BCE)
This text is part of an article series on the Delian League.
The second phase of the Delian League's operations begins with the Hellenic victory over Mede forces at Eurymedon and ends with the Thirty Years Peace between Athens and Sparta (roughly 465/4 ��� 445/4 BCE).The Greek triumph at Eurymedon resulted in a cessation of hostilities against the Persians, which lasted almost six years. Whether or not this peace or truce followed from some formal treaty negotiated by Cimon, son of Miltiades, remains unknown.
Nevertheless, the Greek success at Eurymedon proved so decisive, the damage inflicted on Persia so great, and the wealth confiscated so considerable that an increasing number of League members soon began to wonder if the alliance still remained necessary. The Persians, however, had not altogether withdrawn from the Aegean. They still had, for example, a sizeable presence in both Cyprus and Doriscus. They also set about to build a great number of new triremes.
REDUCTION OF THASOS & THE BATTLE OF DRABESCUS
A quarrel soon erupted between the Athenians and Thasians over several trading ports and a wealth-producing mine (465 BCE). Competing economic interests compelled the rich and powerful Thasos to revolt from the Delian League. The Thasians resisted for almost three years. When the polis finally capitulated, the Athenians forced Thasos to surrender its naval fleet and the mine, dismantle defensive walls, pay retributions, and converted the future League contributions to monetary payments: 30 talents annum. Some League members became disaffected with the Athenian reduction of Thasos. Several poleis observed the Athenians had now developed a penchant for using "compulsion." They started to see Athens acting with both "arrogance and violence." On expeditions, furthermore, the other members felt they "no longer served as equals" (Thuc. 1.99.2).
The Athenians, meanwhile, attempted to establish a colony on the Strymon river to secure timber from Macedon, which shared its borders with the west bank. The location also proved a critical strategic point from which to protect the Hellespont. The Thracians, however, repelled the League forces at Drabescus. The Athenians soon realized the threats from both Thrace and Macedon made permanent settlements in the region difficult as they were essentially continental powers, and the League fleet could not reach them easily. Designs for the region, however, would not change, and the Athenians would return there again.
The Delian League had by this time demonstrated an inherent conflict from its beginnings: on the one hand, it engaged in heroic struggles against the Mede and extended its influence, reaping enormous benefits (especially for its poorer members). On the other hand, it also suppressed its members and soon demanded obedience from them.
The League engaged from the outset in a form of soft imperialism, collecting and commanding voluntary naval contributions and tribute while Athens used those resources and led all expeditions, enforcing continued membership but also showing little or no interest to interfere with the internal mechanisms of any member polis (unless it openly rebelled).
Continue reading...
35 notes · View notes