Jump to content

Blogger

Blog Bot
  • Joined

  • Last visited

    Never

Blog Entries posted by Blogger

  1. by: Andy Clarke
    Mon, 25 Aug 2025 17:16:35 +0000

    When you picture placing images in long-form content — like articles, case studies, or reports — the standard approach is inline rectangles, breaking up blocks of text. Functional? Sure. Inspiring? Hardly.
    Why do so many long-form articles feel visually flat? Why do images so often seem bolted on, rather than part of the story? And how does that affect engagement, comprehension, or tone?
    Images in long-form content can (and often should) do more than illustrate. They can shape how people navigate, engage with, and interpret what they’re reading. They help set the pace, influence how readers feel, and add character that words alone can’t always convey.
    So, how do you use images to add personality, rhythm, and even surprise someone along the way? Here’s how I do it.
    Patty Meltt is an up-and-coming country music sensation. My brief: Patty Meltt is an up-and-coming country music sensation, and she needed a website to launch her new album and tour. She wanted it to be distinctive-looking and memorable, so she called Stuff & Nonsense. Patty’s not real, but the challenges of designing and developing sites like hers are.
    First, a not-so-long-form recap.
    You probably already know that grids make designs feel predictable, rhythmic, and structured, which helps readers feel comfortable when consuming long-form content. Grids bring balance. They help keep things aligned, organized, and easy to follow, which makes complex information feel less overwhelming.
    Complex information feels less overwhelming, but the result is underwhelming. But once I’ve established a grid, breaking it occasionally can be a powerful way to draw attention to key content, add personality, and prevent layouts from feeling formulaic or flat.
    Pulling images into margins creates a casual, energetic feel. For example, in long-form content, I might pull images into the margins or nudge them out of alignment to create a more casual, energetic feel. I could expand an image’s inline size out of its column using negative margin values:
    figure { inline-size: 120%; margin-inline-start: -10%; margin-inline-end: -10%; } Used sparingly, these breaks serve as punctuation, guiding the reader’s eye and adding moments of visual interest to the text’s flow.
    Text width or full-bleed
    Once we start thinking creatively about images in long-form content, one question usually comes to mind: how wide should those images be?
    The image sits within the column width. Should they sit flush with the edges of the text column?
    img { inline-size: 100%; max-inline-size: 100%; } The figure element expands to fill the viewport width. Or expand to fill the entire width of the page?
    figure { inline-size: 100vw; margin-inline-start: 50%; transform: translateX(-50%); } Both approaches are valid, but it’s important to understand how they serve different purposes.
    Book and newspaper layouts traditionally keep images confined to the text column, reinforcing the flow of words. Magazines, on the other hand, regularly break the grid with full-bleed imagery for dramatic effect.
    In articles, news stories, and reports, images set inside the column flow with the copy, giving a sense of order and rhythm. This works especially well for charts, diagrams, and infographics, where it’s important to keep things clear and easy to read. But in the wrong context, this approach can feel predictable and lacking in energy
    Stretching images beyond the content column to fill the full width of the viewport creates instant impact. These moments act like dramatic pauses — they purposefully break the reading rhythm, reset attention, and shift focus from words to visuals. That said, these images should always serve a purpose. They lose their impact quickly if they’re overused or feel like filler.
    Using a modular grid for multiple images
    So far, I’ve focused on single images in the flow of text. But what if I want to present a collection? How can I arrange a sequence of images that belong together?
    Instead of stacking images vertically, I can use a modular grid to create a cohesive arrangement with precise control over placement and scale. What’s a modular grid? It’s a structure built from repeated units — typically squares or rectangles — arranged horizontally and vertically to bring order to varied content. I can place individual images within single modules, or span multiple modules to create larger, more impactful zones.
    figure { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; } figure > *:nth-child(1) { grid-column: 1 / -1; } Modular grids also help us break free from conventional, column-based layouts, adding variety and keeping things visually interesting without relying on full-bleed images every time. They give me the flexibility to mix landscape and portrait images within the same space. I can vary scale, making some images larger for emphasis and others smaller in support. It’s a layout technique that groups related visuals, reinforcing the relationship between them.
    CSS Shapes and expressive possibilities
    Whatever shape the subject takes, every image sits inside a box. By default, text flows above or below that box. If I float an image left or right, the adjacent text wraps around the rectangle, regardless of what’s inside. When a subject fills its box edge to edge, this wrapping feels natural.
    But when the subject is cut out or has an irregular outline, that rectangular wrap can feel awkward.
    CSS Shapes solves that problem by allowing text to wrap around any custom shape I define. Letting text flow around a shape isn’t just decorative — it adds energy and keeps the page feeling lively. Using shape-outside affects the reading experience. It slows people down slightly, creates visual rhythm, and adds contrast to the steady march of regular text blocks. It also brings text and image into a closer relationship, making them feel part of a shared composition rather than isolated elements.
    Most shape-outside explanations start with circles or ellipses, but I think they should begin with something more expressive: wrapping text around an image’s alpha channel.
    img { float: left; width: 300px; height: auto; shape-outside: url('patty.webp'); shape-image-threshold: .5; shape-margin: 1rem; } No clipping paths. No polygons. Just letting the natural silhouette of the image shape the text. It’s a small detail that makes a design feel more considered, more crafted, and more human.
    Integrating captions into a design
    Captions don’t have to sit quietly beneath an image. They can play a far more expressive role in shaping how an image is perceived and understood. Most captions look like afterthoughts to me — small, grey text, tucked beneath a picture.
    But when I think more deliberately about their positioning and styling, captions become an active part of the design. They can help guide attention, highlight important points, and bring a bit more personality to the page.
    No rule says captions must sit below an image. Why not treat them as design elements in their own right? I might position a caption to the left or right of an image.
    figure { display: grid; grid-template-columns: repeat(6, 1fr); gap: 1rem; } figure img { grid-column: 1 / 6; } figcaption { grid-column: 6; } Or let it overlap part of the picture itself:
    figure { display: grid; grid-template-columns: repeat(6, 1fr); gap: 1rem; } figure img { grid-column: 1 / 6; grid-row: 1; } figcaption { grid-column: 5 / -1; grid-row: 1; } Captions connect images and text. Done well, they can elevate as well as explain. They don’t have to look conventional either; you can style them to look like pull quotes or side notes.
    I might design a caption to echo a pull quote, or combine it with graphic elements to make it feel less like a label and more like part of the story it’s helping to tell.
    The power of whitespace
    Until now, I’ve concentrated on the images themselves — how they’re captioned, positioned, and sized. But there’s something else that’s just as important: the space around them.
    Whitespace isn’t empty space; it’s active. It shapes how content feels, how it flows, and how it’s read. The margins, padding, and negative space around an image influence how much attention it attracts and how comfortably it sits within a page.
    Tight spacing creates tension. Tighter spacing is useful when grouping images, but it also creates tension. In contrast, generous margins give an image more breathing room.
    figure { margin-block: 3rem; } Generous margins create pauses. Like a line break in a poem or a pause in conversation, whitespace slows things down and gives people natural moments to pause while reading.
    Conclusion
    Images in long-form content aren’t just illustrations. They shape how people experience what they’re reading — how they move through it, how it feels, and what they remember. By thinking beyond the default rectangle, we can use images to create rhythm, personality, and even moments of surprise.
    Whether it’s by breaking the grid, choosing full-bleed over inline, wrapping text, or designing playful captions, it’s about being deliberate. So next time you’re laying out a long article, don’t wonder, “Where can I put an image?” Ask, “How can this image help shape someone’s experience?”
    Getting Creative With Images in Long-Form Content originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  2. by: Chris Coyier
    Mon, 25 Aug 2025 16:17:42 +0000

    I’m not terribly good at picking a good color palette out of thin air. My go-to is a dark look with bright colored accents, but I’m wildly envious whenever I see a beautiful website with great looking colors that are very far away from what I could pull off.
    Sometimes, a little inspiration can go a long way. Here’s some!
    Color Lisa
    Flexoki
    Mildliner Reference
    Kind of Rebeccapurple
    The story of how the new CSS logo came together, including a journey through lots of colors, only to land on definitely the right choice.
    Hued
    Gradient Generator
    Offers fairly advanced settings for a tool like this, including easing and interpolation modes.
  3. Rethinking DevOps

    by: Avimanyu Bandyopadhyay
    Mon, 25 Aug 2025 12:50:39 +0530

    Ever since I started working with diverse web-apps at Linux Handbook and High On Cloud, the DevOps term has grabbed my attention many a time since that is something we specifically cover at Linux Handbook.
    We've covered tutorials on many tools related to DevOps but we've never really tried to explore the actual concept in depth. Since Linux Handbook is dedicated to Linux Servers, we also need to explore their important role in the DevOps field.
    But before we do so, it is essential to understand what DevOps really is. DevOps is an extremely popular buzzword and you will find multiple definitions of it across the web. But based on my own experiences, I have arrived at the following conclusive definition and thoughts henceforth. This is an attempt to revisit existing DevOps norms and rethink them in the form of a new model that I propose here.
    What is DevOps?
    DevOps is a continuous simplification process of maintaining a delicate balance among functionality, usability and security of an application both in terms of its Development and Operations.
    How to ensure that?
    Ensuring that an application evolves efficiently while also being operational is a continuous challenge for DevOps Engineers. To do that, the most fundamental components of DevOps need to be continuously monitored.
    Application Development Life Cycle (ADLC)
    Creating a new application? You start right here!
    Application Development Life Cycle is the fundamental motivation behind the development of any application. Unless the development process is not carefully and consistently monitored, you cannot be absolutely sure of its flawless development. An application will always be under ADLC until it is production ready.
    ADLC is an essential software engineering principle which consists of six essential stages. The development of an application involves the following steps:
    Concept Plan: Shaping the core idea behind the application. Programming: This is when the application is created and developed. Documentation: An excellent application is useless without careful (human readable) documentation. Testing for Quality Assurance: Making sure the end product is functional, usable and secure. Debugging: Bugs reported during testing are fixed. Development Release: The first version of the application is released. Until and unless a stable release is available, this cycle will continue to exist. Once a software is released as a production-ready stable version, it no longer falls under ADLC. It eventually falls under System Development Life Cycle (SDLC).
    System Development Life Cycle (SDLC)
    A part of our DevOps community might say that both ADLC and SDLC are one and the same. But in the real-world scenario, what I see is ADLC and SDLC are quite different.
    System Development Life Cycle is the fundamental motivation behind both the development and operation of an application. It involves the continuous development of the application after its first stable release and ensures its continuous operability.
    Concept Plan: Revisiting the core idea behind the application. Programming: This is when the application is further developed. Documentation: Continuous update of human readable documentation. Testing new releases for quality: Making sure the new end product is functional, usable and secure. Debugging: Bugs reported during testing are fixed. Development Release: For a new application(version-wise or as the app itself), a development release evolves into its first stable release in this stage. Stable Release: The latest stable version is released as a product with fixes related to bugs/security along-with new features. Deployment: The stable product is deployed on server(s). Maintenance & Monitoring: Consistent and periodic monitoring of servers and the applications that run on them. A community powered open model will always have smoothest maintenance. The last step in the cycle is truly achievable only with an Open Source model. It is the greatest deciding factor in terms of the evolution of any application.
    An application that does not yet have a stable release cannot be regarded as completed. As soon as an application is completely built, ADLC evolves into SDLC. Why?
    ADLC is purely a Development Model SDLC is both a Development and Operations Model Do you get my point now? Under ADLC, an application is not production ready, which is why it would still be under barebone development. Therefore, we cannot call it DevOps. Only when the first stable release is out, it evolves into SDLC which is DevOps because a production-ready application will then onwards become continuously operational.
    As it is evident from the two abbreviations and the diagram above, an application is very different from an entire system. An application is but a part of a complete systemic process. This is what differentiates SDLC from ADLC. So, ADLC is actually a subset of SDLC.
    SDLC needs to be continuously pivoted by us as a community, keeping in mind the delicate balance among functionality, usability and security.
    Presenting the new DevOps Triangle
    This diagram is never the same because SDLC is never stationary. It is SDLC that is being continuously pivoted within the triangle by the community based on the continuous feedback of developers, testers and users.
    Such a pivoting process is ever-changing according to the requirements of the application under deployment. This ever-changing model in the real world is the process of DevOps.
    Where SDLC lies within the triangle will always vary from application to application. The pivoted location is actually dependent on the nature of the application under deployment while being developed with a close eye on:
    Functionality: The primary function of the application. For example, the ability to send messages via Rocket.Chat.
    Usability: The ease of use of the application. For example, how conveniently you can send messages via Rocket.Chat.
    Security: Degree of security of the application. For example, a bug fix that addresses a Rocket.Chat vulnerability such as this one.
    A diverse community that backs an Open Source application need to always maintain a delicate balance among functionality, usability and security.
    But how actually?
    Humility in the Workplace: Ultimate Precision in Pivoting
    At the end of the day, developers, users and testers are all human. Be it local or virtual, DevOps cultures and workplaces need to adopt the simple idea of compassion. A workplace that practices kindness among co-workers is bound to enhance both ADLC and SDLC productivity!
    It's not just about web-apps, it's about people as well. They are the ones who are continuously creating, deploying and maintaining them. That is what community is all about and this is why DevOps is also a culture. The DevOps culture spans around managing not only a web app but also the people who make it a reality.
    An Open Source approach makes this entire process far more achievable than a proprietary one. This is what I have felt while working with this collective system of people, practices and technology.
    I look forward to continue sharing my thoughts in this genre through a series of articles to follow. What I feel is, be it a small, medium or large-scale enterprise, DevOps is applicable everywhere but in the form of personified models.
    This is just a small part of what I'm eager to explore through this series. Please share your thoughts in the comments section below. Thanks for visiting Linux Handbook!
  4. by: Sourav Rudra
    Sun, 24 Aug 2025 13:53:49 GMT

    Not everyone wants to spend their evening punching NPCs in the face or mowing down hordes of enemies after a long day. Sometimes you just want to chill, explore, solve puzzles, or build something cool.
    For me personally, Euro Truck Simulator 2 hits that sweet spot perfectly. There's something incredibly therapeutic about cruising down European highways, listening to tunes from the likes of AURORA, Tame Impala, and Glass Animals.
    Whether you're looking for creative sandbox experiences, thoughtful puzzle games, or just want to relax with some beautiful exploration, Steam has plenty of options for Linux gamers that don't involve combat.
    Here are 13 of the best non-violent games you can play right now on your Linux gaming rig.
    📋The games featured here are of different age ratings, and are a mix of native Linux titles and those that run well via Proton. Also, these games might be available on other platforms, like GOG.1. Firewatch [Native Linux]
    Steam Deck Status: Verified ✅
    Firewatch drops you into the Wyoming wilderness as Henry, a fire lookout trying to escape his troubled past. You spend your days monitoring for forest fires from your tower while building a relationship with your supervisor, Delilah, through radio conversations.
    The game unfolds as a mystery involving strange occurrences in the surrounding forest.
    The gorgeous hand-painted art style brings the wilderness to life in stunning detail, from golden sunsets to dense forest paths. Your choices in conversations with Delilah shape their relationship and affect how the story develops. While there are some tense moments and references to potentially violent events, the core experience remains peaceful and contemplative.
    📋Why this game? Perfect blend of gorgeous visuals, compelling narrative, and peaceful exploration that keeps you engaged without any violence.Firewatch2. Transport Fever 2 [Native Linux]
    Steam Deck Status: Verified ✅
    Transport Fever 2 is all about building transportation networks across different time periods, from the 1850s to the present day. You'll construct railways, manage bus routes, establish shipping lines, and build airports to connect cities and industries. The game focuses on economic simulation and logistics rather than any form of conflict.
    And if you're like me, you'll stick to Free Play mode and load up on mods to create the landscapes of your dreams, building a massive transportation network on procedurally generated or custom maps.
    📋Why this game? Complex transportation simulation that's both relaxing and challenging. Plus, with 650+ hours under my belt, I can definitely vouch for its addictive nature.Transport Fever 23. A Short Hike [Native Linux]
    Steam Deck Status: Verified ✅
    A Short Hike is exactly what it sounds like: a brief, peaceful journey to the top of a mountain. You play as a bird visiting Hawk Peak Provincial Park, helping other visitors and exploring the area at your own pace.
    The game can be completed in about an hour, but you're encouraged to take your time and enjoy the scenery. The pixel art style gives everything a cozy, nostalgic feel reminiscent of classic handheld games.
    You can collect golden feathers to increase your flight stamina, find hidden treasures, or just wander around talking to the various animal characters you encounter.
    📋Why this game? Pure relaxation in game form. Perfect for unwinding after a stressful day at work with its charming art style and peaceful exploration.A Short Hike4. Portal 2 [Native Linux]
    Steam Deck Status: Verified ✅
    Portal 2 is a first-person puzzle game where you use a portal gun to solve increasingly complex spatial challenges. The game takes place in Aperture Laboratories, where you navigate test chambers while being guided (and mocked) by GLaDOS, one of gaming's most memorable AI antagonists.
    The puzzles start simple but gradually introduce new mechanics like light bridges, laser redirection, and various gels that change surface properties. The cooperative campaign adds an entirely different set of challenges designed specifically for two players working together.
    📋Why this game? Brilliant puzzle design combined with exceptional writing and humor, offering pure problem-solving satisfaction without any combat.Portal 25. The Witness
    Steam Deck Status: Playable 🟡
    The Witness places you on a mysterious island filled with line-drawing puzzles that start simple and gradually become incredibly complex. Every puzzle follows the same basic mechanic of drawing a line from start to finish, but the rules change constantly as you discover new symbols and mechanics.
    The island itself is gorgeous, with distinct areas that each focus on teaching you different puzzle concepts. The game never explicitly explains the rules; you learn through experimentation and observation.
    📋Why this game? Hundreds of puzzles that start simple but will absolutely melt your brain as they get more complex. Great for people who like figuring things out.The Witness6. ABZÛ
    Steam Deck Status: Verified ✅
    ABZÛ is an underwater exploration game that feels more like interactive art than a traditional video game. You play as a diver exploring vast ocean environments filled with marine life, ancient ruins, and mysterious technology. The focus is entirely on peaceful exploration and discovery.
    The art direction is absolutely stunning, with vibrant underwater environments teeming with life. Schools of fish react dynamically to your presence, creating living, breathing ecosystems.
    📋Why this game? A meditative underwater journey that's pure visual and audio poetry, perfect for stress relief and contemplation.ABZÛ7. Euro Truck Simulator 2 [Native Linux]
    Steam Deck Status: Verified ✅
    Euro Truck Simulator 2 transforms long-haul trucking into a surprisingly engaging and relaxing experience. You build your own trucking business, delivering cargo across a meticulously recreated Europe while managing fuel, rest stops, and traffic regulations. It sounds mundane on paper but becomes genuinely addictive.
    The driving physics feel authentic without being overly complex, and the European highways are recreated with impressive attention to detail.
    The game's genius is in making routine activities feel meaningful. Planning efficient routes, managing your driver's rest schedule, and building your transportation company from the ground up create a surprisingly engaging loop.
    📋Why this game? Surprisingly therapeutic trucking simulation that turns mundane activities into engaging gameplay loops with hand-crafted European scenery.Euro Truck Simulator 28. Journey
    Steam Deck Status: Verified ✅
    Journey is a wordless adventure where you traverse a mysterious desert landscape toward a distant mountain. The game can be played solo or with anonymous online partners who might appear and disappear throughout your playthrough. Communication happens entirely through musical chimes and movement; no voice or text chat is available.
    The visual design is breathtaking, using a unique art style that makes every scene look like a painting in motion. The sand dunes shift and flow realistically, cloth physics create beautiful flowing scarves, and the lighting creates magical moments throughout the journey.
    📋Why this game? A beautiful, emotional experience that creates genuine human connections through innovative multiplayer design and stunning artistry.Journey9. Planet Coaster 2
    Steam Deck Status: Verified ✅
    Planet Coaster 2 is the ultimate theme park building simulation, giving you complete creative control over every aspect of your park. You can design custom roller coasters, create detailed themed areas, manage park operations, and watch guests react to your creations in real-time.
    If you've played RollerCoaster Tycoon, then this is basically that concept taken to the next level with modern graphics and way more detailed building tools.
    📋Why this game? Incredible creative freedom combined with an extensive park management system. Perfect for building the theme park of your dreams.Planet Coaster 210. Cook, Serve, Delicious! [Native Linux]
    Steam Deck Status: Verified ✅
    Cook, Serve, Delicious transforms restaurant management into a fast-paced, addictive arcade experience. You prepare orders by following on-screen prompts, with different dishes requiring different key combinations and timing.
    As your restaurant gains popularity, orders become more complex and numerous. The game starts simple with basic sandwiches and salads, but eventually you'll be managing elaborate multi-course meals while handling special customer requests.
    A remastered version of this is due in Q4 2025, so keep an eye out for that.
    📋Why this game? Perfectly balanced arcade-style restaurant management that turns cooking into an incredibly satisfying rhythm game.Cook, Serve, Delicious!11. GRIS
    Steam Deck Status: Verified ✅
    GRIS is an adventure about a young woman dealing with loss and trauma, told through gorgeous hand-painted visuals and expressive animation. The game starts in a colorless world that gradually gains vibrancy as you progress, with each new color representing different emotional stages.
    The platforming mechanics evolve alongside the emotional journey. You begin barely able to move, but gradually gain new abilities like transforming into a heavy block to break through barriers or collecting stars to create constellation paths to progress.
    The art style is absolutely breathtaking, resembling watercolor paintings brought to life through fluid animation.
    📋Why this game? A stunning artistic offering that uses interactive mechanics to tell a deeply personal story about healing and growth.GRIS12. Cities: Skylines [Native Linux]
    Steam Deck Status: Playable 🟡
    Cities: Skylines lets you build cities from scratch, starting with empty land and growing into whatever kind of metropolis you want. You handle the basic stuff like zoning residential and commercial areas, laying down roads, and making sure everyone has power and water. It's basically SimCity but way better.
    The traffic simulation is decent (needs mods to be better), so if you design terrible road layouts, you'll definitely feel it when everything grinds to a halt during rush hour. Citizens actually have individual routines and will complain if you screw up their commute or don't provide enough parks and services.
    With this game, you can spend hours just tweaking traffic flow, trying different public transit setups, or downloading community-made buildings and assets.
    📋Why this game? Deep, realistic city simulation that lets you build the urban paradise (or disaster) of your choice with incredible modding support.Cities: SkylinesSuggested Read 📖
    15 Co-Op Games for Linux Steam Gamers in 2025Squad up with your friends in these awesome co-op games!It's FOSSSourav Rudra
  5. Getting Started With Tmux

    by: Christopher Murray
    Sat, 23 Aug 2025 11:35:44 +0530

    With tmux, you can create multiple terminal sessions that can be opened (attached) and closed (detached) or displayed simultaneously, all from one window.
    Multiple Panes in TmuxLearning how to use a terminal multiplexer will save you a lot of headaches if you spend a lot of time in the terminal. This is especially true if your work involves accessing remote machines via command line only.
    Screen vs tmux
    Tmux is considered to be the next evolutionary step forward from the GNU Screen multiplexer.
    If you’re used to the screen command, you’ll find it easy to get started right away. There are many similarities between the two applications. We had a great response to our screen command article, and I feel like our readers will really enjoy using some of the updated features of tmux.
    📋If you are already comfortable with the screen command, you can quickly scan this article for the differences. For some commands, I may point out similarities or differences. Aside from these notes, this article will not presume any previous knowledge.If you are a little lost and don’t know what this article is about yet, that is totally fine. We’re going to walk through everything together. I will show you how to install tmux and how to perform basic operations.
    Install tmux
    Tmux is a popular application, and it should be available in your Linux distribution’s official repository. You can install it using the package manager of your distribution.
    On Debian and Ubuntu-based distributions, you can install it using the following command:
    sudo apt install tmux Using tmux
    As we touched on, tmux is a great application to make you more productive. It is a powerful piece of software, but it can be a little confusing to get started with.
    I will guide you through critical features one at a time. My goal is to ease you in and show you the basic functionality. There are so many ways to customize tmux, that we won’t be able to cover everything in this article. If you are curious about an article on advanced features and functionalities, let us know in the comment section!
    Create a session in tmux
    Open a terminal and use the following command:
    christopher@linuxhandbook:~$ tmux This should bring you into tmux. You will see a command prompt as usual, but you will now see a taskbar style menu on the bottom of the terminal that will say something like 0:bash*. The asterisk indicates that this is your active window.
    Starting a Tmux SessionLet’s create a couple of windows that you can switch between. You can do this by using the prefix [CTRL + b] + c.
    You should see on the taskbar that something named 1:bash has been added. Let’s add two more before you continue further.
    It should now look like the screenshot below. You should have a total of four new terminal windows (you’ll only see one window at a time).
    Different Tmux SessionsThe automatic window name
    Tmux can actually identify certain programs and rename your windows automatically (if you haven’t named your window explicitly). For example, if you run the top command in a window, you’ll notice that the window name is changed from bash to top.
    Tmux automatically renaming windowSession vs Window vs Pane (split) in tmux
    Before you go any further, you should know the difference between session, window, and pane in tmux.
    💡Consider the sessions as notebooks, windows as chapters, and window panes as its pages.A session can have multiple windows. A window is basically a terminal. You can split a window between several vertical and horizontal panes. This means a terminal window can have multiple terminals in it.
    You can create a tmux session for a specific topic/project. For example, if you manage three servers, maybe you can create one session for each server to perform tasks. Use a window for monitoring system resources and another for performing some maintenance tasks. The system monitoring window can have multiple panes to monitor memory, CPU, and disk usage.
    Sessions, Windows, and PanesSwitching between windows in a tmux session
    Remember that CTRL+b (simultaneously) is like your “tmux key”. It tells the software that you want to enter a command. Look at the table below to get started navigating the tmux interface.
    Go to Previous Window Go to Next Window Go to Nth Window [CTRL + b] + p [CTRL + b] + n [CTRL + b] + {0, 1, 2, 3, etc.} Now you can move “back and forth” or select a specific instance by its ID number. Try those things out until it feels comfortable.
    Ready? Awesome. Let’s check out some of the other functionalities.
    📋If you are an experienced Screen user, you may be used to using the [CTRL + a] prefix. Editing the configuration file allows you to change the prefix if you would like. I actually found the alternate key combo improved my efficiency, but I also understand old habits are hard to break.Switch using window list
    Another option uses [CTRL + b] + w. This gives you a visual overview of sessions. You can use the arrow keys to select the desired windows/panes.
    0:00 /0:07 1× Using interactive window switch in Tmux
    Name or rename windows in tmux
    You can name your current window with the following key combination:
    [CTRL + b] + , Rename a WindowName your tmux session
    You may find it helpful to name your sessions with meaningful titles to keep things organized. Let’s try naming your first session with tmux.
    You can name it anything that we want, but in this case, I will name it “free”. Enter the following command:
    tmux new -s free You should now have a new session of tmux running. If you look in the bottom-left area of the window, you will see the name of your session rather than the generic ‘bash’.
    Start a named sessionIf you already created a session, you may name it or rename it using the following key combination:
    [ctrl+b] + $ Rename current sessionDetach a session (come out of tmux session but keep it running in the background)
    Before you continue, let’s begin running free with the watch command, which will update the results every 2 seconds.
    watch free If you are not familiar with free or watch, I recommend that you check out the watch and free command. Knowledge of their functionality, however, is not essential for using them with tmux.
    Okay, so once the program begins, go ahead and detach the session. Use this key combination:
    [ctrl + b] + d This should return you to a standard command prompt. Keep in mind that the tmux session is still running in the background, and you can enter it again whenever you want.
    Detached from a sessionList tmux sessions
    What happened to your session? It is still running in the background. You can re-open the session by name or by ID number, but what if you forget the session name?
    There is a list function built into tmux:
    tmux ls This will list all your current tmux sessions. Running it will produce output like this:
    christopher@linuxhandbook:~$ tmux ls free: 1 windows (created Sat Feb 29 03:16:31 2020) [80x23] As you can see, it also lists how many windows a session has.
    List SessionsRe-enter a session in Tmux (also known as attach)
    To reopen your tmux session, you can use the tmux command with attach or attach-session option like this:
    tmux attach -t session_name_or_number Here is an animation that shows all these steps until this point in the demonstration.
    Tmux Commands Animated Overview
    Creating multiple panes in tmux
    Now that you have an understanding of the basics, you can go further and create multiple panes.
    Horizontal (Left/Right) Vertical (Top/Bottom) [CTRL + b] + % [CTRL + b] + " Let’s get some practice with these commands by creating a vertical split followed by a horizontal split.
    [ctrl + b] + " [ctrl + b] + % If you’ve entered the commands in that order, you should have three panes that look this:
    Vertical and Horizontal SplitYou can use [CTRL + b] + space key to toggle the layout of the currently focused pane.
    Layout changeSwitching between panes
    To switch between the splits you can use the tmux prefix [CTRL + b] + arrow keys.
    [ctrl+b] + arrow keys This cycles the panes in the direction you choose. The selected pane will be highlighted in green.
    Switching panesZoom into a pane
    You can also “zoom” into a selected pane with the [CTRL +b ] + z. This will bring the selected screen to full size. To exit the zoom mode, hit [CTRL + b] + z again.
    Zoom into paneKilling or closing panes
    This is an important one. You can close a pane (splits) by using the prefix [CTRL + b] + x.
    It will ask you for the confirmation:
    kill-pane 0? (y/n) Close a PaneKilling or closing windows in tmux
    In order to close the current window (tabs), use:
    [ctrl + b] + & It will ask for your confirmation:
    kill-window window_name? (y/n) Terminate a WindowKilling sessions in tmux
    To kill the current tmux session you are using, you’ll have to kill all the windows first. That’s not very convenient, is it?
    You can selectively kill a tmux session using its name or number like this:
    tmux kill-session -t session_name_or_number Terminate a SessionIt will kill the session even if you are inside the session.
    If you want to kill all the sessions except the one you are currently using (or the last one you used), use this command:
    tmux kill-session -a Terminate all other sessions except the currently attached sessionTo kill all tmux sessions in one go, you can use this magical command:
    tmux kill-server Terminate all SessionsDownload tmux cheat sheet
    You learned the basics of tmux but remembering all the commands is not easy, specially in the beginning. This is why I am summarizing all the commands in the table below. You may also download it in PDF form.
    Commands and Key Combinations Explanation tmux Start new session tmux new -s name Start new session with name tmux ls List all the sessions tmux kill-session -t name Kill the mentioned session tmux kill-session -a Kill all sessions except the current or last used session tmux kill-server Kill all tmux sessions tmux attach -t name Attach/enter the mentioned session [CTRL + b] + d Detach/exit the current session [CTRL + b] + $ Name or rename current session [CTRL + b] + c Create new window [CTRL + b] + , Name or rename current window [CTRL + b] + w List all windows [CTRL + b] + & Kill the current window [CTRL + b] + n/p/N Move to next/previous/Nth window [CTRL + b] + % Create horizontal pane (New left and right panes) [CTRL + b] + “ Create vertical pane (New top and bottom panes) [CTRL + b] + space key Toggle the layout of the current panes [CTRL + b] + z Zoom into the current pane [CTRL + b] + x Kill the current pane Tmux cheatsheetKeyboard shortcuts for using tmuxtmux-cheatsheet.png475 KB.a{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.5px;}download-circleConclusion
    Thank you for following along with our introduction to tmux. As you can see, there are a wide variety of applications. I hope that this basic overview has given you some ideas about how you can use tmux to improve your workflow.
    We'll be covering the steps discussed here in a bit more detail, in their dedicated page. You can find them from the left sidebar of this page.
    As always, if you have any questions, please leave them below in the comment section.
  6. Using Git

    by: Abhishek Prakash
    Sat, 23 Aug 2025 11:30:14 +0530

    Git has become the default version control system in the IT world today. The young ones probably never even heard of SVN or Mercurial, let alone use it. Such is its popularity.
    You surely cannot ignore Git today.
    This is a collection of various short tutorials on doing things in Git. This will help you with your Git concept, one article a time.
  7. Learn Zsh

    by: Abhishek Prakash
    Sat, 23 Aug 2025 11:11:20 +0530

    While bash is the most widely available and popular shell, Zsh has a strong following among a certain section of developers and sysadmins.
    Though it has some awesome features, they would need some customization either manually or through plugins.
    This section is a collection of tips and tutorials that will help you learn and use Zsh more effectively.
    You'll learn the following:
    Why Zsh is awesome? Installing Zsh and making it default shell Configuring aliases in Zsh Enabling syntax highlighting in Zsh Enabling command history in Zsh Enabling autosuggestions based on command history Customizing Zsh prompt Setting environment variable in Zsh Using Powerlevel10k to get more out of it Using Oh My Zsh (coming soon) Best Zsh plugin (coming soon)
  8. Start Learning Vim

    by: Abhishek Prakash
    Fri, 22 Aug 2025 22:52:58 +0530

    Vim needs no introduction. If you are working in the command line, you have three main options for editing files:
    Vim Nano Emacs You can use either of the three but many people swear by Vim for its flexibility and extensibility.
    You can use Vim for basic file editing or you can use it as an IDE for full software development. Heck! Some people even use it for writing novels.
    This is a consolidation of Vim tips and tutorials, divided into three categories:
    Basic Vim tips: The absolute essentials any Vim user must know Other Vim tips: Some additional tips centered around the basic usage Advanced Vim tips: Taking your Vim knowledge to the next level
  9. by: Abhishek Prakash
    Fri, 22 Aug 2025 20:30:23 +0530

    Nano is perhaps one of the simplest terminal-based text editor.
    While it is still depended on keyboard, the shortcuts are simpler here when compared to Vim and Emacs.
    Nano also displays appropriate shortcuts on the bottom all the time, making it even easier to use. You don't need to remember all the shortcuts.
    Remember that in the keyboard shortcut suggestions, ^ means control and M means Alt.
    So, if you see:
    ^G: You press both Ctrl and G keys together M-Q: You press both Alt and Q keys together 💡When you feel lost, look at the bottom for hints. Or, you can press ^G (i.e. Ctrl+G) to open the help page.Although Nano is not as complicated as Emacs, Vi or Vim, there is still a learning curve involved. This is why I have organized some essential Nano tips in a proper order. This will teach you all the basics you need to start editing files in the Nano editor.
    What will you learn?
    You'll learn the following in this Nano course:
    Open files for editing Save and exit files Move around the editor Undo and redo actions Cut, copy and paste in the editor Search and replace text Delete lines I have also added an extra section with some additional tips to help you use Nano more effectively.
    What do you need?
    You need a Linux system with Nano installed on it. Most Linux distributions come with Nano preinstalled.
    Verify it by checking Nano version
    nano --versionIf you see an output like "nano command not found", you need to install it first. You can use your distribution's package manager to install it.
    With that set, let's learn how to use Nano to edit files.
  10. by: Amit Sheen
    Fri, 22 Aug 2025 13:14:31 +0000

    In the previous two chapters, we built a layered 3D text effect, added depth and color, and then brought it to life with motion. We explored static structure, animated variations, and even some clever decoration tricks. But everything so far has been hard-coded.
    This time, we’re going dynamic.
    In this final chapter, we’re stepping into the world of interactivity by adding JavaScript into the mix. We’ll start by generating the layers programmatically, giving us more flexibility and cleaner code (and we’ll never have to copy-paste divs again). Then, we’ll add some interaction. Starting with a simple :hover effect, and ending with a fully responsive bulging text that follows your mouse in real time. Let’s go.
    3D Layered Text Article Series
    The Basics Motion and Variations Interactivity and Dynamicism (you are here!) Clean Up
    Before we jump into JavaScript, let us clean things up a bit. We will pause the animations for now and go back to the static example we wrapped up with in the first chapter. No need to touch the CSS just yet. Let us start with the HTML.
    We will strip it down to the bare essentials. All we really need is one element with the text. The class stays. It is still the right one for the job.
    <div class="layeredText">Lorem Ipsum</div> Scripting
    It is time. Let us start adding some JavaScript. Don’t worry, the impact on performance will be minimal. We’re only using JavaScript to set up the layers and define a few CSS variables. That’s it. All the actual style calculations still happen off the main thread, maintain high frames per second, and don’t stress the browser.
    We will begin with a simple function called generateLayers. This is where all the magic of layer generation will happen. To work its magic, the function will receive the element we want to use as the container for the layers.
    function generateLayers(element) { // magic goes here } To trigger the function, we will first create a small variable that holds all the elements with the layeredText class. And yes, we can have more than one on the page, as we will see later. Then, we will pass each of these elements into the generateLayers function to generate the layers.
    const layeredElements = document.querySelectorAll('.layeredText'); layeredElements.forEach(generateLayers); Fail Safe
    Now let us dive into the generateLayers function itself and start with a small fail safe mechanism. There are situations, especially when working with frameworks or libraries that manage your DOM, where a component might get rendered more than once or a function might run multiple times. It should not happen, but we want to be ready just in case.
    So, before we do anything, we will check if the element already contains a div with the .layers class. If it does, we will simply exit the function and do nothing:
    function generateLayers(element) { if (element.querySelector('.layers')) return; // rest of the logic goes here } Tip: In the real world, I would treat this as a chance to catch a rendering bug. Instead of silently returning, I would probably send a message back to the dev team with the relevant data and expect the issue to be fixed.
    Counting Layers
    One last thing we need to cover before we start building the layers is the number of layers. If you remember, we have a CSS variable called --layers-count, but that will not help us here. Besides, we want this to be more dynamic than a single hardcoded value.
    Here is what we will do. We will define a constant in our JavaScript called DEFAULT_LAYERS_COUNT. As the name suggests, this will be our default value. But we will also allow each element to override it by using an attribute like data-layers="14".
    Then we will take that number and push it back into the CSS using setProperty on the parent element, since we rely on that variable in the styles.
    const DEFAULT_LAYERS_COUNT = 24; function generateLayers(element) { if (element.querySelector('.layers')) return; const layersCount = element.dataset.layers || DEFAULT_LAYERS_COUNT; element.style.setProperty('--layers-count', layersCount); } Adding Content
    Now we have everything we need, and we can finally generate the layers. We will store the original text content in a variable. Then we will build the markup, setting the innerHTML of the parent element to match the structure we used in all the previous examples. That means a span with the original content, followed by a div with the .layers class.
    Inside that div, we will run a loop based on the number of layers, adding a new layer in each iteration:
    function generateLayers(element) { // previous code const content = element.textContent; element.innerHTML = ` <span>${content}</span> <div class="layers" aria-hidden="true"> ${Array.from({ length: layersCount}, (_, i) => `<div class="layer" style="--i: ${i + 1};">${content}</div>` ).join('')} </div> `; } And that is it. Our 3D text is ready, and all the layers are now built entirely through JavaScript. Try playing around with it. Change the text inside the layeredText element. Add your name, your project name, your brand. Let me know how it looks.
    CodePen Embed Fallback Quick note: I also removed the --layers-count variable from the CSS, since it is now set dynamically with JavaScript. While I was at it, I moved the font settings out of the .layeredText element, since they should be applied globally or to a more appropriate wrapper. Just a bit of housekeeping to keep things clean.
    Normalizing Height
    Since we already added a way to set the number of layers dynamically, let us take advantage of it.
    Here is an example with three different div elements, each using a different number of layers. The first one (A) has 8 layers, the second (B) has 16, and the third (C) has 24.
    CodePen Embed Fallback You can clearly see the difference in height between the letters, since the total height depends on the number of layers. When it comes to color though, we used the normalized value (remember that?), so the gradient looks consistent regardless of height or layer count.
    We can just as easily normalize the total height of the layers. All we need to do is replace the --layer-offset variable with a new one called --text-height. Instead of setting the distance between each layer, we define the total height for the full stack. That lets us multiply the normalized value by --text-height, and get a consistent size no matter how many layers we have.
    .layeredText { --text-height: 36px; .layer { --n: calc(var(--i) / var(--layers-count)); transform: translateZ(calc(var(--n) * var(--text-height))); color: hsl(200 30% calc(var(--n) * 100%)); } } CodePen Embed Fallback Counter Interaction
    We are ready to start reacting to user input. But before we do anything, we need to think about the things we do not want to interact with, and that means the extra layers.
    We already handled them for screen readers using aria-hidden, but even with regular mouse interactions, these layers can get in the way. In some cases, they might block access to clickable elements underneath.
    To avoid all of that, we will add pointer-events: none; to the .layers element. This makes the layers completely ‘transparent’ to mouse clicks and hover effects.
    .layers { pointer-events: none; } Hovering Links
    Now we can finally start responding to user input and adding a bit of interaction. Let’s say I want to use this 3D effect on links, as a hover effect. It might be a little over the top, but we are here to have fun.
    We will start with this simple markup, just a paragraph of Lorem ipsum, but with two links inside. Each link has the .layeredText class. Right now, those links will already have depth and layers applied, but that is not what we want. We want the 3D effect to appear only on hover.
    To make that happen, we will define a new :hover block in .layeredText and move all the 3D related styles into it. That includes the color and shadow of the span, the color and translateZ of each .layer, and to make it look even better, we will also animate the opacity of the layers.
    .layeredText { &:hover { span { color: black; text-shadow: 0 0 0.1em #003; } .layer { color: hsl(200 30% calc(var(--n) * 100%)); transform: translateZ(calc(var(--i) * var(--layer-offset) + 0.5em)); opacity: 1; } } } Now we need to define the base appearance, the styles that apply when there is no hover. We will give the span and the layers a soft bluish color, apply a simple transition, and set the layers to be fully transparent by default.
    .layeredText { display: inline-block; span, .layer { color: hsl(200 100% 75%); transition: all 0.5s; } .layer { opacity: 0; } } Also, I added display: inline-block; to the .layeredText element. This helps prevent unwanted line breaks and allows us to apply transforms to the element, if needed. The result is a hover effect that literally makes each word pop right off the page:
    CodePen Embed Fallback Of course, if you are using this as a hover effect but you also have some elements that should always appear with full depth, you can easily define that in your CSS.
    For example, let us say we have both a heading and a link with the .layeredText class, but we want the heading to always show the full 3D effect. In this case, we can update the hover block selector to target both:
    .layeredText { &:is(h1, :hover) { /* full 3D styles here */ } } This way, links will only show the effect on hover, while the heading stays bold and dimensional all the time.
    CodePen Embed Fallback Mouse Position
    Now we can start working with the mouse position in JavaScript. To do that, we need two things: the position of the mouse on the page, and the position of each element on the page.
    We will start with the mouse position, since that part is easy. All we need to do is add a mousemove listener, and inside it, define two CSS variables on the body: --mx for the horizontal mouse position, and --my for the vertical position.
    window.addEventListener('mousemove', e => { document.body.style.setProperty('--mx', e.pageX); document.body.style.setProperty('--my', e.pageY); }); Notice that I am using e.pageX and e.pageY, not e.clientX and e.clientY. That is because I want the mouse position relative to the entire page, not just the viewport. This way it works correctly even when the page is scrolled.
    Position Elements
    Now we need to get the position of each element, specifically the top and left values. We will define a function called setRects that loops through all layeredElements, finds their position using a getBoundingClientRect function, and sets it to a couple of CSS custom properties.
    function setRects() { layeredElements.forEach(element => { const rect = element.getBoundingClientRect(); element.style.setProperty('--top', rect.top + window.scrollY); element.style.setProperty('--left', rect.left + window.scrollX); }); } Once again, I am using window.scrollX and scrollY to get the position relative to the entire page, not just the viewport.
    Keep in mind that reading layout values from the DOM can be expensive in terms of performance, so we want to do it as little as possible. We will run this function once after all the layers are in place, and again only when the page is resized, since that could change the position of the elements.
    setRects(); window.addEventListener('resize', setRects); The Moving Red Dot
    That is it. We are officially done writing JavaScript for this article. At this point, we have the mouse position and the position of every element stored as CSS values.
    Great. So, what do we do with them?
    Remember the examples from the previous chapter where we used background-image? That is the key. Let us take that same idea and use a simple radial gradient, from red to white.
    .layer { background-clip: text; color: transparent; background-image: radial-gradient(circle at center, red 24px, white 0); } But instead of placing the center of the circle in the middle of the element, we will shift it based on the mouse position. To calculate the position of the mouse relative to the element, we simply subtract the element’s position from the mouse position. Then we multiply by 1px, since the value must be in pixels, and plug it into the at part of the gradient.
    .layer { background-image: radial-gradient( circle at calc((var(--mx) - var(--left)) * 1px) calc((var(--my) - var(--top)) * 1px), red 24px, white 0 ); } The result is text with depth and a small red dot that follows the movement of your mouse.
    CodePen Embed Fallback Okay, a small red dot is not exactly mind blowing. But remember, you are not limited to that. Once you have the mouse position, you can use it to drive all sorts of dynamic effects. In just a bit, we will start building the bulging effect that kicked off this entire series, but in other cases, depending on your needs, you might want to normalize the mouse values first.
    Normalizing Mouse Position
    Just like we normalized the index of each layer earlier, we can normalize the mouse position by dividing it by the total width or height of the body. This gives us a value between 0 and 1.
    document.body.style.setProperty('--nx', e.pageX / document.body.clientWidth); document.body.style.setProperty('--ny', e.pageY / document.body.clientHeight); Normalizing the mouse values lets us work with relative positioning that is independent of screen size. This is perfect for things like adding a responsive tilt to the text based on the mouse position.
    CodePen Embed Fallback Bulging Text
    Now we are finally ready to build the last example. The idea is very similar to the red dot example, but instead of applying the background-image only to the top layer, we will apply it across all the layers. The color is stored in a custom variable and used to paint the gradient.
    .layer { --color: hsl(200 30% calc(var(--n) * 100%)); color: transparent; background-clip: text; background-image: radial-gradient( circle at calc((var(--mx) - var(--left)) * 1px) calc((var(--my) - var(--top)) * 1px), var(--color) 24px, transparent 0 ); } Now we get something similar to the red dot we saw earlier, but this time the effect spreads across all the layers.
    CodePen Embed Fallback Brighter Base
    We are almost there. Before we go any further with the layers, I want to make the base text look a bit weaker when the hover effect is not active. That way, we create a stronger contrast when the full effect kicks in.
    So, we will make the span text transparent and increase the opacity of its shadow:
    span { color: transparent; text-shadow: 0 0 0.1em #0004; } Keep in mind, this makes the text nearly unreadable when the hover effect is not active. That is why it is important to use a proper media query to detect whether the device supports hover. Apply this styling only when it does, and adjust it for devices that do not.
    @media (hover: hover) { /* when hover is supported */ } Fixing Sizes
    This is it. The only thing left is to fine tune the size of the gradient for each layer. And we are done. But I do not want the bulge to have a linear shape. Using the normalized value alone will give me evenly spaced steps across all layers. That results in a shape with straight edges, like a cone.
    To get a more convex appearance, we can take advantage of the new trigonometric functions available in CSS. We will take the normalized value, multiply it by 90 degrees, and pass it through a cos() function. Just like the normalized value, the cosine will return a number between 0 and 1, but with a very different distribution. The spacing between values is non-linear, which gives us that smooth convex curve.
    --cos: calc(cos(var(--n) * 90deg)); Now we can use this variable inside the gradient. Instead of giving the color a fixed radius, we will multiply --cos by whatever size we want the effect to be. I also added an absolute value to the calculation, so that even when --cos is very low (close to zero), the gradient still has a minimum visible size.
    And, of course, we do not want sharp, distracting edges. We want a smooth fade. So, instead of giving the transparent a hard stop point, we will give it a larger value. The difference between the var(--color) and the transparent values will control how soft the transition is.
    background-image: radial-gradient( circle at calc((var(--mx) - var(--left)) * 1px) calc((var(--my) - var(--top)) * 1px), var(--color) calc(var(--cos) * 36px + 24px), transparent calc(var(--cos) * 72px) ); And just like that, we get an interactive effect that follows the mouse and gives the impression of bulging 3D text:
    CodePen Embed Fallback Wrapping Up
    At this point, our 3D layered text has gone from a static stack of HTML elements to a fully interactive, mouse-responsive effect. We built dynamic layers with JavaScript, normalized depth and scale, added responsive hover effects, and used live input to shape gradients and create a bulging illusion that tracks the user’s every move.
    But more than anything, this chapter was about control. Controlling structure through code. Controlling behavior through input. And controlling perception through light, color, and movement. And we did it all with native web technologies.
    This is just the beginning. You can keep going with noise patterns, lighting, reflections, physics, or more advanced motion behaviors. Now you have the tools to explore them, and to create bold, animated, expressive typography that jumps right off the screen.
    Now go make something that moves.
    3D Layered Text Article Series
    The Basics Motion and Variations Interactivity and Dynamicism (you are here!)
    3D Layered Text: Interactivity and Dynamicism originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  11. by: Amit Sheen
    Fri, 22 Aug 2025 13:14:31 +0000

    In the previous two chapters, we built a layered 3D text effect, added depth and color, and then brought it to life with motion. We explored static structure, animated variations, and even some clever decoration tricks. But everything so far has been hard-coded.
    This time, we’re going dynamic.
    In this final chapter, we’re stepping into the world of interactivity by adding JavaScript into the mix. We’ll start by generating the layers programmatically, giving us more flexibility and cleaner code (and we’ll never have to copy-paste divs again). Then, we’ll add some interaction. Starting with a simple :hover effect, and ending with a fully responsive bulging text that follows your mouse in real time. Let’s go.
    3D Layered Text Article Series
    The Basics Motion and Variations Interactivity and Dynamism (you are here!) Clean Up
    Before we jump into JavaScript, let us clean things up a bit. We will pause the animations for now and go back to the static example we wrapped up with in the first chapter. No need to touch the CSS just yet. Let us start with the HTML.
    We will strip it down to the bare essentials. All we really need is one element with the text. The class stays. It is still the right one for the job.
    <div class="layeredText">Lorem Ipsum</div> Scripting
    It is time. Let us start adding some JavaScript. Don’t worry, the impact on performance will be minimal. We’re only using JavaScript to set up the layers and define a few CSS variables. That’s it. All the actual style calculations still happen off the main thread, maintain high frames per second, and don’t stress the browser.
    We will begin with a simple function called generateLayers. This is where all the magic of layer generation will happen. To work its magic, the function will receive the element we want to use as the container for the layers.
    function generateLayers(element) { // magic goes here } To trigger the function, we will first create a small variable that holds all the elements with the layeredText class. And yes, we can have more than one on the page, as we will see later. Then, we will pass each of these elements into the generateLayers function to generate the layers.
    const layeredElements = document.querySelectorAll('.layeredText'); layeredElements.forEach(generateLayers); Fail Safe
    Now let us dive into the generateLayers function itself and start with a small fail safe mechanism. There are situations, especially when working with frameworks or libraries that manage your DOM, where a component might get rendered more than once or a function might run multiple times. It should not happen, but we want to be ready just in case.
    So, before we do anything, we will check if the element already contains a div with the .layers class. If it does, we will simply exit the function and do nothing:
    function generateLayers(element) { if (element.querySelector('.layers')) return; // rest of the logic goes here } Tip: In the real world, I would treat this as a chance to catch a rendering bug. Instead of silently returning, I would probably send a message back to the dev team with the relevant data and expect the issue to be fixed.
    Counting Layers
    One last thing we need to cover before we start building the layers is the number of layers. If you remember, we have a CSS variable called --layers-count, but that will not help us here. Besides, we want this to be more dynamic than a single hardcoded value.
    Here is what we will do. We will define a constant in our JavaScript called DEFAULT_LAYERS_COUNT. As the name suggests, this will be our default value. But we will also allow each element to override it by using an attribute like data-layers="14".
    Then we will take that number and push it back into the CSS using setProperty on the parent element, since we rely on that variable in the styles.
    const DEFAULT_LAYERS_COUNT = 24; function generateLayers(element) { if (element.querySelector('.layers')) return; const layersCount = element.dataset.layers || DEFAULT_LAYERS_COUNT; element.style.setProperty('--layers-count', layersCount); } Adding Content
    Now we have everything we need, and we can finally generate the layers. We will store the original text content in a variable. Then we will build the markup, setting the innerHTML of the parent element to match the structure we used in all the previous examples. That means a span with the original content, followed by a div with the .layers class.
    Inside that div, we will run a loop based on the number of layers, adding a new layer in each iteration:
    function generateLayers(element) { // previous code const content = element.textContent; element.innerHTML = ` <span>${content}</span> <div class="layers" aria-hidden="true"> ${Array.from({ length: layersCount}, (_, i) => `<div class="layer" style="--i: ${i + 1};">${content}</div>` ).join('')} </div> `; } And that is it. Our 3D text is ready, and all the layers are now built entirely through JavaScript. Try playing around with it. Change the text inside the layeredText element. Add your name, your project name, your brand. Let me know how it looks.
    CodePen Embed Fallback Quick note: I also removed the --layers-count variable from the CSS, since it is now set dynamically with JavaScript. While I was at it, I moved the font settings out of the .layeredText element, since they should be applied globally or to a more appropriate wrapper. Just a bit of housekeeping to keep things clean.
    Normalizing Height
    Since we already added a way to set the number of layers dynamically, let us take advantage of it.
    Here is an example with three different div elements, each using a different number of layers. The first one (A) has 8 layers, the second (B) has 16, and the third (C) has 24.
    CodePen Embed Fallback You can clearly see the difference in height between the letters, since the total height depends on the number of layers. When it comes to color though, we used the normalized value (remember that?), so the gradient looks consistent regardless of height or layer count.
    We can just as easily normalize the total height of the layers. All we need to do is replace the --layer-offset variable with a new one called --text-height. Instead of setting the distance between each layer, we define the total height for the full stack. That lets us multiply the normalized value by --text-height, and get a consistent size no matter how many layers we have.
    .layeredText { --text-height: 36px; .layer { --n: calc(var(--i) / var(--layers-count)); transform: translateZ(calc(var(--n) * var(--text-height))); color: hsl(200 30% calc(var(--n) * 100%)); } } CodePen Embed Fallback Counter Interaction
    We are ready to start reacting to user input. But before we do anything, we need to think about the things we do not want to interact with, and that means the extra layers.
    We already handled them for screen readers using aria-hidden, but even with regular mouse interactions, these layers can get in the way. In some cases, they might block access to clickable elements underneath.
    To avoid all of that, we will add pointer-events: none; to the .layers element. This makes the layers completely ‘transparent’ to mouse clicks and hover effects.
    .layers { pointer-events: none; } Hovering Links
    Now we can finally start responding to user input and adding a bit of interaction. Let’s say I want to use this 3D effect on links, as a hover effect. It might be a little over the top, but we are here to have fun.
    We will start with this simple markup, just a paragraph of Lorem ipsum, but with two links inside. Each link has the .layeredText class. Right now, those links will already have depth and layers applied, but that is not what we want. We want the 3D effect to appear only on hover.
    To make that happen, we will define a new :hover block in .layeredText and move all the 3D related styles into it. That includes the color and shadow of the span, the color and translateZ of each .layer, and to make it look even better, we will also animate the opacity of the layers.
    .layeredText { &:hover { span { color: black; text-shadow: 0 0 0.1em #003; } .layer { color: hsl(200 30% calc(var(--n) * 100%)); transform: translateZ(calc(var(--i) * var(--layer-offset) + 0.5em)); opacity: 1; } } } Now we need to define the base appearance, the styles that apply when there is no hover. We will give the span and the layers a soft bluish color, apply a simple transition, and set the layers to be fully transparent by default.
    .layeredText { display: inline-block; span, .layer { color: hsl(200 100% 75%); transition: all 0.5s; } .layer { opacity: 0; } } Also, I added display: inline-block; to the .layeredText element. This helps prevent unwanted line breaks and allows us to apply transforms to the element, if needed. The result is a hover effect that literally makes each word pop right off the page:
    CodePen Embed Fallback Of course, if you are using this as a hover effect but you also have some elements that should always appear with full depth, you can easily define that in your CSS.
    For example, let us say we have both a heading and a link with the .layeredText class, but we want the heading to always show the full 3D effect. In this case, we can update the hover block selector to target both:
    .layeredText { &:is(h1, :hover) { /* full 3D styles here */ } } This way, links will only show the effect on hover, while the heading stays bold and dimensional all the time.
    CodePen Embed Fallback Mouse Position
    Now we can start working with the mouse position in JavaScript. To do that, we need two things: the position of the mouse on the page, and the position of each element on the page.
    We will start with the mouse position, since that part is easy. All we need to do is add a mousemove listener, and inside it, define two CSS variables on the body: --mx for the horizontal mouse position, and --my for the vertical position.
    window.addEventListener('mousemove', e => { document.body.style.setProperty('--mx', e.pageX); document.body.style.setProperty('--my', e.pageY); }); Notice that I am using e.pageX and e.pageY, not e.clientX and e.clientY. That is because I want the mouse position relative to the entire page, not just the viewport. This way it works correctly even when the page is scrolled.
    Position Elements
    Now we need to get the position of each element, specifically the top and left values. We will define a function called setRects that loops through all layeredElements, finds their position using a getBoundingClientRect function, and sets it to a couple of CSS custom properties.
    function setRects() { layeredElements.forEach(element => { const rect = element.getBoundingClientRect(); element.style.setProperty('--top', rect.top + window.scrollY); element.style.setProperty('--left', rect.left + window.scrollX); }); } Once again, I am using window.scrollX and scrollY to get the position relative to the entire page, not just the viewport.
    Keep in mind that reading layout values from the DOM can be expensive in terms of performance, so we want to do it as little as possible. We will run this function once after all the layers are in place, and again only when the page is resized, since that could change the position of the elements.
    setRects(); window.addEventListener('resize', setRects); The Moving Red Dot
    That is it. We are officially done writing JavaScript for this article. At this point, we have the mouse position and the position of every element stored as CSS values.
    Great. So, what do we do with them?
    Remember the examples from the previous chapter where we used background-image? That is the key. Let us take that same idea and use a simple radial gradient, from red to white.
    .layer { background-clip: text; color: transparent; background-image: radial-gradient(circle at center, red 24px, white 0); } But instead of placing the center of the circle in the middle of the element, we will shift it based on the mouse position. To calculate the position of the mouse relative to the element, we simply subtract the element’s position from the mouse position. Then we multiply by 1px, since the value must be in pixels, and plug it into the at part of the gradient.
    .layer { background-image: radial-gradient( circle at calc((var(--mx) - var(--left)) * 1px) calc((var(--my) - var(--top)) * 1px), red 24px, white 0 ); } The result is text with depth and a small red dot that follows the movement of your mouse.
    CodePen Embed Fallback Okay, a small red dot is not exactly mind blowing. But remember, you are not limited to that. Once you have the mouse position, you can use it to drive all sorts of dynamic effects. In just a bit, we will start building the bulging effect that kicked off this entire series, but in other cases, depending on your needs, you might want to normalize the mouse values first.
    Normalizing Mouse Position
    Just like we normalized the index of each layer earlier, we can normalize the mouse position by dividing it by the total width or height of the body. This gives us a value between 0 and 1.
    document.body.style.setProperty('--nx', e.pageX / document.body.clientWidth); document.body.style.setProperty('--ny', e.pageY / document.body.clientHeight); Normalizing the mouse values lets us work with relative positioning that is independent of screen size. This is perfect for things like adding a responsive tilt to the text based on the mouse position.
    CodePen Embed Fallback Bulging Text
    Now we are finally ready to build the last example. The idea is very similar to the red dot example, but instead of applying the background-image only to the top layer, we will apply it across all the layers. The color is stored in a custom variable and used to paint the gradient.
    .layer { --color: hsl(200 30% calc(var(--n) * 100%)); color: transparent; background-clip: text; background-image: radial-gradient( circle at calc((var(--mx) - var(--left)) * 1px) calc((var(--my) - var(--top)) * 1px), var(--color) 24px, transparent 0 ); } Now we get something similar to the red dot we saw earlier, but this time the effect spreads across all the layers.
    CodePen Embed Fallback Brighter Base
    We are almost there. Before we go any further with the layers, I want to make the base text look a bit weaker when the hover effect is not active. That way, we create a stronger contrast when the full effect kicks in.
    So, we will make the span text transparent and increase the opacity of its shadow:
    span { color: transparent; text-shadow: 0 0 0.1em #0004; } Keep in mind, this makes the text nearly unreadable when the hover effect is not active. That is why it is important to use a proper media query to detect whether the device supports hover. Apply this styling only when it does, and adjust it for devices that do not.
    @media (hover: hover) { /* when hover is supported */ } Fixing Sizes
    This is it. The only thing left is to fine tune the size of the gradient for each layer. And we are done. But I do not want the bulge to have a linear shape. Using the normalized value alone will give me evenly spaced steps across all layers. That results in a shape with straight edges, like a cone.
    To get a more convex appearance, we can take advantage of the new trigonometric functions available in CSS. We will take the normalized value, multiply it by 90 degrees, and pass it through a cos() function. Just like the normalized value, the cosine will return a number between 0 and 1, but with a very different distribution. The spacing between values is non-linear, which gives us that smooth convex curve.
    --cos: calc(cos(var(--n) * 90deg)); Now we can use this variable inside the gradient. Instead of giving the color a fixed radius, we will multiply --cos by whatever size we want the effect to be. I also added an absolute value to the calculation, so that even when --cos is very low (close to zero), the gradient still has a minimum visible size.
    And, of course, we do not want sharp, distracting edges. We want a smooth fade. So, instead of giving the transparent a hard stop point, we will give it a larger value. The difference between the var(--color) and the transparent values will control how soft the transition is.
    background-image: radial-gradient( circle at calc((var(--mx) - var(--left)) * 1px) calc((var(--my) - var(--top)) * 1px), var(--color) calc(var(--cos) * 36px + 24px), transparent calc(var(--cos) * 72px) ); And just like that, we get an interactive effect that follows the mouse and gives the impression of bulging 3D text:
    CodePen Embed Fallback Wrapping Up
    At this point, our 3D layered text has gone from a static stack of HTML elements to a fully interactive, mouse-responsive effect. We built dynamic layers with JavaScript, normalized depth and scale, added responsive hover effects, and used live input to shape gradients and create a bulging illusion that tracks the user’s every move.
    But more than anything, this chapter was about control. Controlling structure through code. Controlling behavior through input. And controlling perception through light, color, and movement. And we did it all with native web technologies.
    This is just the beginning. You can keep going with noise patterns, lighting, reflections, physics, or more advanced motion behaviors. Now you have the tools to explore them, and to create bold, animated, expressive typography that jumps right off the screen.
    Now go make something that moves.
    3D Layered Text Article Series
    The Basics Motion and Variations Interactivity and Dynamism (you are here!)
    3D Layered Text: Interactivity and Dynamism originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  12. by: Abhishek Prakash
    Fri, 22 Aug 2025 17:58:51 +0530

    You might notice something different about the Linux Handbook website. It has a fresh new look! 🎉
    But it’s not just about looks. Along with the redesign, I am introducing a better and more helpful course layout.
    Take our Linux course, for example. It gives you all the necessary information, chapters, difficulty level, duration, etc. And when you visit a chapter, all the chapters of the course are accessible from the left sidebar. This makes the learning easier, cleaner and more systematic.
    That's not it. I am also making collections of tutorials on a topic. Take the firewalld collection for example.
    This is still a work in progress. So a few things may look out of place until the transition is complete.
    The redesign is part of the commitment I have for Linux Handbook to make it an idea, independent portal of self-learning for Linux hobbyists and career aspirants alike.
    I welcome your feedback on these changes. Just hit reply to this message. I read and reply to each of them.
     
     
      This post is for subscribers only
    Subscribe now Already have an account? Sign in
  13. by: Doron Beit-Halahmi
    Fri, 22 Aug 2025 14:55:01 +0530

    Proxmox is a type-1 hypervisor that you install on a physical server. And then you use it to create numerous virtual machines and containers, manage them, create clusters with them, and what not.
    If you would like to learn virtualization or you would like to create a setup that involves using dedicated hardware for various Linux servers, Proxmox is the force to reckon with.
    If you are getting started with Proxmox, you are at the right place. You'll get all the essentials of Proxmox in this mini-course.
    And this Proxmox tutorial series is loved by our readers 👇
    😍Much better than the docs at Proxmox ;-)
    Earl Wertheimer, IT Consultant in Montreal, CanadaWhat will you learn?
    Here's what you'll learn in this Proxmox course:
    Installing Proxmox Creating virtual machines Creating containers Adding shared storage Backup and restores VMs Clone and templates Clustering and high availability Upgrading Proxmox By the end of this course, you'll be able to start using Proxmox for your homelab or work setup where you can deploy multiple servers in VMs or containers and manage them effectively.
    Prerequisite
    The course presumes that you are already managing Linux servers and you are completely new to the concept of virtual machines.
    While it is not a deal-breaker, previous experience with virtual machines will be helpful.
    How to use this mini-course?
    It's quite simple actually. The course is divided into chapters. The chapters of the series are always visible in the left sidebar and you can easily switch between them. The sub-sections of a chapter are located in the right sidebar.
    The next and previous chapter navigation are also present at the bottom of each chapter.
    For any doubts, you can always use the comment section available under each chapter.
    Let's start learning Proxmox!
  14. by: Pratham Patel
    Fri, 22 Aug 2025 13:09:14 +0530

    📶 Difficulty level: Intermediate
    ⏳ Time to complete: Approx. 3 hours
    📋 Prerequisite: Familiarity with Docker, containers and Linux command lineThe containers are often synonym with Docker. But Docker is not the only containerization tool out there.
    Red Hat's Podman is a promising tool for your container needs. The syntax is similar to Docker, so you don't have to unlearn Docker first and then learn something new.
    This Podman tutorial series aims to make you familiar with Podman. By the end of the series, you should be able to learn the difference between Docker and Podman and you should also be able to start using Podman for your container workflow.
    What will you learn?
    In this Podman tutorial series, you'll learn:
    The difference between Docker and Podman To create and destroy containers with Podman To autostart Podman containers when the system boots To update Podman containers Rootless containers concept Podman Compose concept Prerequisite
    This Podman mini-course requires:
    That you are not unfamiliar with the containerization concept Experience with Docker Familiarity with the Linux terminal and commands How to use this mini-course?
    It's quite simple actually. The course is divided into chapters. The chapters of the series are always visible in the left sidebar and you can easily switch between them. The sub-sections of a chapter are located in the right sidebar.
    The next and previous chapter navigation are also present at the bottom of each chapter.
    For any doubts, you can always use the comment section available under each chapter.
    Let's get started first by understanding the difference between Docker and Podman.
  15. by: Sourav Rudra
    Fri, 22 Aug 2025 06:31:05 GMT

    Privacy-focused services like encrypted email, secure messaging, and VPNs are growing in importance with each passing day. We live in an era where dissent is crushed and corporations treat user data like chips on a poker table. Your browsing habits, location data, and online communications have become valuable commodities to be traded without your consent.
    VPNs have emerged as essential tools for reclaiming digital sovereignty, but not all VPN services actually protect your privacy. Many providers claim to offer security while secretly logging user activity and storing connection records. This creates a false sense of security that can be more dangerous than having no protection at all.
    This list differs from our other VPN list, as we are focusing exclusively on services that either have independently audited no-logging policies or make no-logs claims backed by their practices.
    🚧I am just listing VPN services that can work on Linux and have 'no log policy'. Verifying their no-logging policy is not in my technical capability. I have included links to third-party security reports if they are available. 1. Mullvad VPN

    Mullvad VPN is one of the very few VPN services that allow you to generate a random account number instead of asking you for your email ID and other personal details. Their Swedish jurisdiction provides strong privacy protections, and they've actually removed servers when governments demanded access.
    The service operates with complete transparency about their infrastructure and regularly publishes independent security audit results. Plus, their WireGuard implementation performs exceptionally well on Linux systems compared to traditional OpenVPN protocols. You can even pay anonymously by mailing cash to their office.
    ⭐ Key Features
    Anonymous account creation. Native Linux apps with GUI and CLI options. WireGuard protocol optimized for Linux performance. Mullvad VPN2. Proton VPN

    Proton VPN (partner link) comes from the team behind Proton Mail and leverages Switzerland's strict privacy laws for protection. Their no-logs policy has been independently verified multiple times, and they publish regular transparency reports.
    I have been using ProtonVPN for quite some time now, and it's one of the first things I launch when booting into my Fedora-powered workstation. While the connection quality, download speeds, and server availability have been excellent, the ancient user interface for the Linux client can be frustrating sometimes.
    I Switched to Proton VPN and Here’s What I Honestly Think About ItProton VPN is an impressive solution. Here’s my experience with it.It's FOSS NewsSourav Rudra⭐ Key Features
    VPN Accelerator for faster connection speeds. Secure Core routing through privacy-friendly countries. NetShield ad, tracker, and malware blocking at DNS level. Proton VPN3. Internxt VPN

    Internxt VPN (partner links) hides and encrypts your internet traffic, protecting you from invasive tracking, targeted ads, and online surveillance. It has servers in five countries: France, Germany, Poland, Canada, and the UK.
    Their premium VPN comes as a bundle alongside their secure cloud storage services, which is the main product they are known for. I have their 1 TB lifetime plan that provides access to their VPN server located in France. The VPN can only be used via Chrome-based browser extension.
    While the server network is smaller, it provides stable connections and essential location coverage for European and North American users.
    Basically, if you opt for their encrypted cloud storage service, you are getting a VPN for free.
    Internxt clearly mentions a no log policy on its website. There are no independent security audits on VPN that I could find. The cloud storage service has been audited by Securitum.
    Internxt is celebrating their 5th anniversary, and their services are currently at 87% off using our exclusive code "it'sfoss".
    ⭐ Key Features
    Blocks ISP tracking and ads. Chrome-based browser extension only. Integrates with Internxt ecosystem that includes cloud storage and antivirus. Internxt VPN4. IVPN

    IVPN focuses on practical privacy features without unnecessary bloat or marketing gimmicks. They collect minimal data and allocate randomly generated accounts to users instead of asking for PII.
    Their server network prioritizes quality over quantity, with all hardware under IVPN's direct control to prevent third-party interference. Multi-hop connections route traffic through multiple servers for enhanced anonymity, and anti-surveillance features include advanced obfuscation to bypass network restrictions and deep packet inspection.
    ⭐ Key Features
    Multi-hop connections for enhanced anonymity. Firewall integration with WebRTS leak protection. Regular independent security audits with public results. IVPN5. AirVPN

    AirVPN caters to power users who want complete control over their VPN experience without handholding or simplified interfaces. The Italian service maintains detailed technical documentation and has an active community where users share configurations and troubleshooting tips.
    Port forwarding works great for torrenting and gaming, while unlimited server switches let you hop between locations freely. OpenVPN over SSH and SSL bypasses censorship in restrictive countries, and you can have up to five simultaneous connections per account.
    I could not find any security audits or third-party sources on their no-logging policy though.
    ⭐ Key Features
    OpenVPN over SSH, SSL, and Tor tunneling. Port forwarding and unlimited server switches. Adding an email address during signup is optional. AirVPN6. Surfshark

    Surfshark gained popularity by offering unlimited device connections at prices that won't break your budget. This makes it practical for households with multiple laptops, phones, and other devices needing protection.
    It packs several practical features beyond basic VPN functionality, including CleanWeb ad blocking, Bypasser split tunneling, and Cookie Pop-up Blocker for cleaner browsing.
    We have reviewed Surfshark's Linux app in the past and it is quite a good service.
    Testing the Surfshark VPN App on LinuxEurope-based VPN service Surfshark provides a native GUI client for desktop Linux. Let me share my experience with it.It's FOSSAnkush Das⭐ Key Features
    CleanWeb ad and malware blocking. Unlimited simultaneous device connections. RAM-only servers with automatic data wiping. Surfshark7. NordVPN

    NordVPN runs one of the largest server networks with thousands of access points across 60+ countries for reliable global coverage. Their specialty servers include P2P-optimized nodes, obfuscated servers for restrictive networks, and dedicated IP options for users who require a consistent IP address.
    Multiple independent audits have verified their no-logs claims aren't just marketing promises, and their Double VPN routes traffic through multiple servers located in different countries for added privacy.
    There are native GUI and CLI apps that work seamlessly across major Linux distributions without requiring manual OpenVPN configuration files or third-party clients.
    ⭐ Key Features
    Malware and ad blocking. NordLynx WireGuard implementation. Double VPN and Onion Over VPN connections. NordVPN8. ExpressVPN

    ExpressVPN costs a bit more than the others on this list, but it makes up for the premium pricing with solid infrastructure and consistent performance. Their servers maintain advertised speeds during peak hours instead of crawling to a halt, and the service reliably unblocks region-locked streaming content.
    It's TrustedServer tech ensures all servers run on RAM-only infrastructure, automatically wiping data with each restart for enhanced security, and the Lightway protocol provides quick download speeds for big files.
    While the desktop app for Linux is currently in beta, it should work reliably across major distributions like Ubuntu, Fedora, and Debian.
    Their no-log policy has been independently audited.
    ⭐ Key Features
    Best-in-class AES-256 encryption. Network Lock kill switch for when your connection drops. Access to ExpressVPN's Private DNS for more secure connections. ExpressVPNIn the end...
    As I mentioned earlier, I am not a security expert, so I cannot vouch for how good their no-log policies are. Many of these services have to battle court orders to resist logging in different geographical regions and those are murky stuff.
    My team and I have used the VPNs listed here in our personal capacity as end users. Currently, I use ProtonVPN as It's FOSS has a visionary plan for ProtonMail and all the Proton services.
    Choosing a good VPN from the list I provided here is really up to you. If you want full anonymity, Mullvad VPN seems a good bet if you can afford it. If you want something inexpensive that could protect your privacy from targeted advertising, unblock some georestricted contents, Internxt VPN could be worth a look, especially when it is bundled with encrypted cloud storage.
  16. by: Abhishek Prakash
    Fri, 22 Aug 2025 11:33:54 +0530

    What is firewalld?
    Firewalld is an open source firewall management tool that acts as a front-end tool for the Linux kernel's netfilter framework. It is a zone-based firewall system that allows for the different security configuration levels for different connection zones. While Ubuntu and Debian rely on ufw for the firewall function, firewalld is shipped by default in Fedora, CentOS, openSUSE and Red Hat.
    Why use firewalld?
    Easier management: No need to remember complex iptables or nftables syntax. Dynamic updates: Change rules without downtime. Predefined services: Quickly allow/deny SSH, HTTP, HTTPS, etc. Widespread adoption: Default firewall in RHEL, CentOS, Fedora, openSUSE, and more. 📖 Get familiar with firewalld terms quickly
    Before jumping into commands, let’s look at a few important terms you’ll encounter again and again:
    Zones: A zone represents a trust level for a network connection. For example, public (least trusted), home (medium), trusted (all allowed). Each network interface can be assigned to a zone. Services: Firewalld comes with predefined services like ssh, http, https. Enabling a service automatically opens the required port(s). Ports: You can directly allow or deny specific ports (like 80/tcp for HTTP) if you don’t want to rely on service definitions. Runtime vs Permanent:Runtime rules: Take effect immediately but are lost after reboot/reload. Permanent rules: Persist across reboots but require a reload to apply. Backends: Firewalld uses nftables (modern Linux) or iptables (older Linux) under the hood, so you don’t have to. Manage firewalld with firewall-cmd commands
    You use firewalld with a dedicated firewall-cmd command line tool.
    Command Description sudo firewall-cmd --state Check if firewalld is running sudo systemctl restart firewalld Restart the firewall service sudo firewall-cmd --reload Reload rules without stopping service sudo firewall-cmd --get-active-zones Show active zones and interfaces sudo firewall-cmd --get-default-zone Show the default zone sudo firewall-cmd --list-all List all rules in the default zone sudo firewall-cmd --add-service=ssh --permanent Allow SSH permanently sudo firewall-cmd --remove-service=ssh --permanent Remove SSH access permanently sudo firewall-cmd --add-port=8080/tcp --permanent Open TCP port 8080 permanently sudo firewall-cmd --remove-port=8080/tcp --permanent Close TCP port 8080 sudo firewall-cmd --list-services List allowed services in current zone sudo firewall-cmd --set-log-denied=all Enable logging of denied packets We have a one page guide on firewall-cmd command that shows these examples in a better way.
    firewalld-cmd Command in Linux: 24 ExamplesThe firewall-cmd command line tool lets you interact and manage the firewalld firewall in Linux. Here’s how to use this command.Linux HandbookLHB CommunityThis here is a collection of quick tutorials that teaches you various ways of using the firewalld firewall system. The collection will be updated continually with more tutorials in the future.
  17. by: Abhishek Prakash
    Thu, 21 Aug 2025 04:32:39 GMT

    There are numerous popular browser-based free VPNs. FreeVPN is one such extension that was recently caught to be spying on its users. As the saying goes, if it's free, you are the product.
    Google Verified FreeVPN Caught Red-handed Spying on its UsersIf it is free, you are the product. Unless it is free and open source.It's FOSS NewsSourav RudraIf you have to, at least use free option from reliable sources like Proton or Mozilla.
    💬 Let's see what else you get in this edition
    Some new hardware for tinkerers. XZ Utils backdoor being found in Debian docker images. Command that lets you create new files with predefined size. LibreOffice gets AI image generation ability. And other Linux news, tips, and, of course, memes! 📰 Linux and Open Source News
    LibreOffice gets a new AI image generation extension. Security researchers have found XZ Utils backdoor in Debian images on Docker Hub. Intel's ongoing global layoff drive is adversely affecting driver support in the Linux kernel. Firefox 142 is here with a topic-based new tab page, AI-powered link previews, and more. ArmSoM's CM1 is here for industrial-grade performance in embedded IoT. Raspberry Pi has launched a smaller variant of the Touch Display 2. Raspberry Pi Launches 5″ Touch Display 2 for Just $40Small, sharp, and just $40.It's FOSS NewsSourav Rudra🧠 What We’re Thinking About
    A Windows update is not playing nice with SSDs. Switching to Linux should fix this.
    Windows Update Is Killing SSDs! Should You Switch to Linux?The moment to make the move to Linux is now.It's FOSS NewsSourav Rudra🧮 Linux Tips, Tutorials, and Learnings
    Here are some privacy-focused alternatives to Notion. You can access root folder from the Nautilus file manager. If you ever forget it, you can easily reset the root password in Ubuntu. Handy fallocate command allows you to create files of a certain size, say a 10 GB file for your testing. Accessing Root Directory in Nautilus File ManagerQuick little tip that shows how you can access the files and folders under root from Nautilus file manager.It's FOSSAbhishek Prakash👷 AI, Homelab and Hardware Corner
    I tested the TerraMaster's SSD enclosure against my SanDisk external SSD. I never cared for SSD enclosures until now and I must say these are pretty useful gadgets, specially for people who have their homelab with access to numerous NVMe SSDs.
    TerraMaster D1 SSD Plus Review: Experience a Faster External SSDIt is one of those devices that I did not know I needed until I used it.It's FOSSAbhishek PrakashA split mechanical keyboard that doesn't look weird and is also silent? Nocfree is famous for that and they have a new version announced on Kickstarter. One more gadget added to my wishlist. Now I got to start saving for it 😄
    Nocfree & on Kickstarter✨ Project Highlight
    You might have heard about Omarchy. The distro that started the 'pre-configured Hyprland' revolution of sorts. Sourav tested it out, read his experience.
    This One Command Turned My Arch Install Into a Beautiful Hyprland SetupThis script turned my boring Arch install into something special.It's FOSS NewsSourav Rudra📽️ Videos I am Creating for You
    Have a look at Linux Mint 22.2 Zara features in the latest video.
    Subscribe to It's FOSS YouTube Channel🧩 Quiz Time
    Are you a terminal plumber? Our Chain Reaction quiz will test your pipes knowledge.
    Chain Reaction: A Linux Pipes & Commands QuizConnect the dots...er.. pipes and correctly guess the command combinations.It's FOSSAbhishek Prakash🛍️ Don't Miss: Linux ebooks and videos bundle
    Level up your Linux skills with the latest Humble Tech Book Bundle with courses by Pearson. Get professional-quality lessons like UNIX® and Linux® System Administration Handbook, Fifth Edition, Linux performance optimization, and more. Pay what you want for a whole new user experience on your favorite machine—and help support The BINC Foundation with your purchase!
    Humble Tech Book Bundle: Linux Complete by PearsonUnleash your machine’s potential with our latest Humble Tech Book Bundle: Linux Complete—customize, design, and help support The BINC Foundation today!Humble BundleExplore Linux Bundle💡 Quick Handy Tip
    In Dolphin (the KDE file manager), you can make copying and moving files 'faster'. Go to Menu → Configure → Configure Dolphin → Context Menu, turn on Copy To and Move To, and hit "Apply".
    After that, right-click any file or folder, and you’ll see Copy Here and Move Here options. Clicking them lets you pick a destination right there without needing to open another window.
    🤣 Meme of the Week
    I have become old. 👨‍🦳
    🗓️ Tech Trivia
    On 25th August 1991, a 21-year-old Finnish student named Linus Torvalds casually announced on Usenet that he was working on a “hobby” operating system for 386 PCs—something “just for fun” and not big or professional like GNU. That hobby project became Linux, our favorite open source project.
    🧑‍🤝‍🧑 FOSSverse Corner
    The discussion surrounding why Windows users are so difficult to convert to Linux is still ongoing. Go ahead, contribute to it!
    Why are Windows Users so Difficult to Convert to Linux?Over the weekend I had a windows user come to see me, he had no sound on his laptop computer speakers.Running windows 10. Easy, into devices on the control panel, look for realtek and enable them, sound worked. But reboot, they stopped. Virus check showed he was badly infected, so many lost count. Malwarebytes, adwcleaner etc and removed them, restart enable device worked, but second restart no sound, virus check again and they had returned. The computer is not capable of converting to window…It's FOSS Communitycallpaul.eu (Paul)❤️ With love
    Please share it with your Linux-using friends and encourage them to subscribe (hint: it's here).
    Share the articles in Linux Subreddits and community forums.
    Follow us on Google News and stay updated in your News feed.
    Opt for It's FOSS Plus membership and support us 🙏
    Enjoy FOSS 😄
  18. by: Abhishek Prakash
    Thu, 21 Aug 2025 09:50:26 +0530

    Stop wrestling with complex shell scripts and manual log parsing.
    AWK is your secret weapon for instant data analysis, log processing, and system monitoring. Convert your superlong scripts into elegant one-liners to help with your actual usecases.
    What makes AWK special?
    Built into every Linux system - no installation needed Handles structured data effortlessly Perfect for log analysis, configuration processing, and report generation Bridges the gap between simple grep/sed and complex programming languages What You'll Learn in This Series
    While there is no end to mastering a new tool or skill, this tutorial series will make you familiar with the essential concepts of AWK.
    Part 1: Introduction to AWK
    Get up and running with AWK basics. Learn when to use AWK vs grep vs sed, get familiar with the pattern-action syntax, and start extracting data from files like a pro.
    Part 2: Pattern Matching and Operations
    Control exactly what data gets processed. Master conditional logic, comparison operators, and complex pattern matching that handles real-world scenarios.
    Part 3: Built-in Variables and Field Manipulation
    Discover AWK's built-in sensors (NR, NF, FS, OFS) and learn to reshape data on-the-fly. Turn any text format into exactly what you need.
    Part 4: Mathematical Operations
    Perform calculations on your data and manipulate text with precision. Format reports, clean data, and transform strings like a text processing wizard.
    Part 5: String Manipulations
    Utilize the vast string functions AWK provides to deal and add a new dimension to your scripts.
    Part 6: Arrays and Data Structures
    Unlock AWK's most powerful feature. Count occurrences, group data, create summaries, and perform analysis that would require complex scripts in other languages.
    Part 7: Control Flow
    Build sophisticated scripts with for and while loops.
    Part 8: User Defined Functions
    Write cleaner, more maintainable code by breaking complex operations into reusable components.
    Part 9: AWK Best Practices
    Write maintainable, efficient AWK scripts. Learn debugging techniques, performance optimization, and when NOT to use AWK.
    Why This Series
    ✅ Hands-On Learning
    Every chapter includes complete sample files and working examples. Copy, paste, run and see immediate results.
    ✅ Sysadmin-Focused
    Real scenarios you face daily: processing logs, monitoring systems, generating reports, and automating tasks.
    ✅ Progressive Complexity
    Start with simple field extraction, progress to complex data analysis. Each chapter builds on previous knowledge.
    ✅ Practical Examples
    Every example solves system administration challenges using realistic data.
    Who This Series Is For
    Perfect if you're:
    A Linux system administrator handling log files and data processing Comfortable with basic command line but want to level up your text processing skills Tired of writing long scripts for simple data extraction tasks Looking to automate reporting and monitoring tasks Want to understand when and how to use AWK effectively Not quite ready? If you're new to Linux command line, start with basic bash tutorials first. This series assumes you're comfortable navigating the terminal and editing files.
    Tools and Requirements
    What you need:
    Any Linux system (local, VM, or server access) Basic terminal/command line familiarity Text editor of your choice Sample log files (I'll provide realistic examples) What's included:
    Complete sample data files for every chapter Working code examples you can copy and modify Practice exercises with increasing difficulty Ready? Let's start learning.
  19. by: Abhishek Prakash
    Thu, 21 Aug 2025 02:49:22 GMT

    Transferring large files via typical USB thumb drives is a pain. Try it with a 20 GB file and it will take an hour just for copying the files.
    That's why external, portable SSDs are the new normal these days, especially when we have to deal with 4K video files that go in multiple GBs.
    Another player in this domain is an external SSD enclosure that allows you to use your typical, internal NVMe SSD like a portable, external SSD.
    One of the latest such devices is TerraMaster's D1 SSD Plus. If you did not know already, TerraMaster manufactures NAS, DAS and other storage equipment. D1 SSD Plus is their latest offering.
    📋TerraMaster sent me this device for review. The views expressed are my own and come from experience with time spent on it.TerraMaster D1 SSD Plus Enclosure
    The TerraMaster D1 SSD Plus is a high-speed, portable M.2 NVMe SSD enclosure that supports up to 8 TB drives and connects via USB4 (40 Gbps), delivering near-desktop performance with read/write speeds close to 4 GB/s (or so it claims).
    Weighing at 250 grams, TerraMaster D1 SSD Plus is a heavy device for a portable SSD. But that's by choice and by design. The enclosure is made of aerospace-grade aluminum, and it is certainly a lot bulkier than your usual external SSD. Although it keeps the SSD safe and also adds the passive cooling features thanks to the dual-sided fins.
    It looks like the white colored aluminum casing is getting popular. ZimaBoard 2 and some other gadgets in the homelab niche also use this styling these days. I prefer dark, black looks, but let the color not be a judge of this device.
    🚧TerraMaster D1 SSD Plus is just an enclosure. It does NOT include NVMe SSD.Set up
    Please note that the enclosure does NOT come with NVMe SSD. You have to use your own NVMe SSD and it cannot be SATA SSD.
    The box contains the enclosure, a high-speed cable, a screwdriver, manual, and a pouch for the device.
    There is a tiny screw at the bottom of the device. You have to use the provided screwdriver to unscrew it and open the enclosure. The screw doesn't come out entirely but stays fixed on it. This is good thinking, as you don't want to lose the tiny screw. At the same time, you wouldn't want to use an unsuitable device on the screw because if the screw loses its shape, you may have a hard time with it.
    Once the enclosure is opened, you'll see the option to add the NVMe SSD on one part. The other part has a thermal pad with a sticker on it that should be removed before the first use.
    The entire setup doesn't take long and is certainly not complicated.
    Data safety and SSD supports
    D1 SSD Plus is compatible with double sided SSDs too. This is another plus.
    Another plus point is the data safety. TerraMaster claims that D1 SSD Plus incorporates additional protective components to ensure stable data transmission, safeguarding against short circuits, voltage surges, and electrostatic discharge (ESD).
    As noted by Gizmochina, the large amount of SMD capacitors used here are the same as you see with enterprise SSDs to stabilize the voltage, provide power failure protection, and thus ensure data safety.
    Technical specifications
    Specification Details Interface USB4 (40 Gbps), TB5/4/3, USB 3.x/2.0 Max Speeds Read up to ~3,853 MB/s, Write up to ~3,707 MB/s SSD Slot M.2 NVMe 2280 Max Capacity 8 TB Enclosure Aluminum, fanless, heat-dissipating Dimensions (mm) 112.5 × 60 × 33 Weight 246 g (without SSD) Power Consumption ~7.5 W active, ~5.5 W hibernation File Systems Supported NTFS, APFS, HFS+, exFAT, FAT32, EXT4 Extras Backup apps (TDAS & TPC), screwdriver, pouch Price (enclosure) Approximately $110 Get TerraMaster D1 SSD Plus on AmazonSpeed matters
    Since one of the main points of having a TerraMaster external SSD enclosure is to use it as a better alternative of regular external SSDs, I tested it against my SanDisk Extreme Portable Disk (model SDSSDE60-1T00).
    This SanDisk SSD has been with me for the past few years. In fact, I have three of them. One of them stores important data and is not used much and the other two are more portable in nature. I have almost stopped using USB drives even for data transfer after these SSDs.
    Let me share how the TerraMaster SSD enclosure compares with my SanDisk Extreme portable disk.
    To summarize, this is my test kit:
    ASUS Zenbook S14 with Thunderbolt 4 port SanDisk Extreme Portable Disk SDSSDE60-1T00 (USB 3.2 interface with advertised speed of 1050 MB/s). TerraMaster D1 SSD Plus with WD Blue SN5000 (PCIe 4.0 interface with advertised speed of 2853 MB/s) 📋My tests are more from a casual, end-user's perspective. I am sure these tests can be performed at a more expert level with dedicated speed testing software but I wanted to test it the way I use them in my day-to-day activities.In the test screenshots, Data-SSD is TerraMaster and Backup-SSD is SanDisk.
    The first test I did was with a folder containing photos of around 5.5 GB in size. Surprisingly, SanDisk nearly took the same time (6.6 sec) as TerraMaster (5.32 sec).
    I was not expecting this, to be honest. Then I created a file of 10 GB in size with fallocate and used it to test the two external disks. This time TerraMaster was around two times faster than SanDisk.
    Next, I copied a folder with some huge video files. The folder was around 96 GB in size. And as expected, TerraMaster finished copying under one third of the time than SanDisk.
    TerraMaster took 1 minute, 28 seconds for 96 GB of file transfer. Which should be roughly around 1.1 GB/s.
    TerraMaster D1 SSD PlusSanDisk took 4 minutes and 10 seconds, which should amount to a speed of 380 MB/s.
    SanDiskBasically, the larger the file size, the better it performs.
    Of course, the SanDisk uses USB 3.2 interface and is a few years older, but most of the external SSDs use the same interface and have a similar performance range. In my opinion, it is only fair to keep the comparison with these external disks as the external SSD enclosure is supposed to replace them in your setup.
    Backup your PC and smartphone data easily
    TerraMaster has dedicated software to backup Windows PCTerraMaster also provides dedicated software to backup your Windows PC easily to your external SSD. I don't use Windows and there is no such application for Linux so I didn't test it.
    There are also dedicated mobile apps for iOS and Android. I was actually excited about the idea of automatically backing up smartphone data to the SSD.
    I have a Galaxy S23 Ultra with 1 TB storage and 2 children. Which means that I have tons of photos and videos of my children. I keep an automatic backup on pCloud as I have their 2 TB lifetime storage. Having data locally is a plus as I prefer keeping multiple copies of the data.
    Unfortunately, at present, my Galaxy S23 is suffering from 'foreign particle and moisture' in the charging port and thus I could not test it on my phone. I'll update this section when this problem goes away and the USB port is functional again.
    I used my wife's iPhone,but the WD Blue SN5000 probably required more power because I saw a 'Cannot use accessory. This accessory uses too much power' error.
    I am sure these apps have been created to add more versatility to the overall offering of TerraMaster devices. I wish I could test them but it didn't happen.
    Advantages of an external SSD enclosure
    I learned a thing or two about using an external SSD enclosure.
    Speed: By using the Thunderbolt port, these SSD enclosures are equal or faster than your regular external SSDs. Reusability: If you have internal NVMe SSDs that are not being used, you can put them in the enclosure and use them as external SSDs. You are not fixed to a single brand of SSD as well. Cost-effective in long run: You have the option to 'upgrade' your external SSD by changing the NVMe SSD. Robust: In some unfortunate case if the USB connector breaks on the external SSD, your data is pretty much lost. In case of SSD enclosure, your SSD can be taken out anytime and put into another device. A device worth having
    I was skeptical at first, unsure of the usability of such a device. But when I looked closely and tested it, I could see its potential and why external SSD enclosures are gaining popularity specially among homelab users who have multiple NVMe SSDs in their setup. It gives the option to reuse your internal SSDs into a portable, external SSD.
    TerraMaster D1 SSD Plus is a robust device. It is bulky, but it ensures safe SSD operation. The all almunium chassis gives it a rugged look and at the same time, it provides passive cooling.
    With 4K being the new normal, it's not uncommon to have video files in 100s of GBs. USB 3 is certainly not adequate for data transfer of such large files. External SSDs are the way to go. Even there, the speed matters, and as you saw, TerraMaster D1 SSD Plus was easily more than 3 times faster than portable SSD.
    The ability to transfer photos and videos directly from your smartphones into the SSD is another plus for TerraMaster D1 SSD Plus, given that you use the correct SSD.
    My biggest gripe is perhaps its bulky outfit. Now, I understand that it is important to secure the SSD against jerks and falls for a longer and smoother operation and hence it makes sense to have a military grade enclosure. Plus, it handles the heat pretty well so I should not complain about the size.
    Get it from official websiteOrder it from Amazon
  20. by: Amit Sheen
    Wed, 20 Aug 2025 13:54:52 +0000

    In the previous chapter, we built a basic 3D layered text effect using nothing but HTML and CSS. It looks great and has a solid visual presence, but it’s completely static. That is about to change.
    In this chapter, we will explore ways to animate the effect, add transitions, and play with different variations. We will look at how motion can enhance depth, and how subtle tweaks can create a whole new vibe.
    3D Layered Text Article Series
    The Basics Motion and Variations (you are here!) Interactivity and Dynamism (coming August 22) ⚠️ Motion Warning: This article contains multiple animated examples that may include flashing or fast moving visuals. If you are sensitive to motion, please proceed with caution.
    ‘Counter’ Animation
    Let’s start things off with a quick animation tip that pairs perfectly with layered 3D text. Sometimes, we want to rotate the element without actually changing the orientation of the text so it stays readable. The trick here is to combine multiple rotations across two axes. First, rotate the text on the z-axis. Then, add a tilt on the x-axis. Finally, rotate the text back on the z-axis.
    @keyframes wobble { from { transform: rotate(0deg) rotateX(20deg) rotate(360deg); } to { transform: rotate(360deg) rotateX(20deg) rotate(0deg); } } Since we rotate on the z-axis and then reverse that rotation, the text keeps its original orientation. But because we add a tilt on the x-axis in the middle, and the x-axis itself keeps rotating, the angle of the tilt changes as well. This creates a kind of wobble effect that shows off the text from every angle and emphasizes the sense of depth.
    CodePen Embed Fallback If we want to take this a few steps further, we can combine the wobble with a floating effect. We will animate the .layers slightly along the z-axis:
    .layers { animation: hover 2s infinite ease-in-out alternate; } @keyframes hover { from { transform: translateZ(0.3em); } to { transform: translateZ(0.6em); } } To really sell the effect, we will leave the original span in place — like a shadowed anchor — change its color to transparent, and animate the blur factor of its text-shadow:
    span { color: transparent; animation: shadow 2s infinite ease-in-out alternate; } @keyframes shadow { from { text-shadow: 0 0 0.1em #000; } to { text-shadow: 0 0 0.2em #000; } } Syncing those two animations together gives the whole thing a more realistic feel:
    CodePen Embed Fallback Splitting Letters
    OK, this is starting to look a lot better now that things are moving. But the whole word is still moving as one. Can we make each letter move independently? The answer, as usual, is “yes, but…”
    It is absolutely possible to split each word into a separate letters and animate them individually. But it also means a lot more elements moving on the screen, and that can lead to performance issues. If you go this route, try not to animate too many letters at once, and consider reducing the number of layers.
    In the next example, for instance, I reduced the layer count to sixteen. There are five letters, and to place them side by side, I gave the .scene a display: flex, then added a small delay to each letter using :nth-child:
    CodePen Embed Fallback New Angles
    Until now, we have only been moving the text along the z-axis, but we can definitely take it further. Each layer can be moved or rotated in any direction you like, and if we base those transformations on the --n variable, we can create all sorts of interesting effects. Here are a few I played with, just to give you some ideas.
    In the first one, I am animating the translateX to create a shifting effect:
    CodePen Embed Fallback In the others, I am adding a bit of rotation. The first one is applied to the y-axis for the sloping effect:
    CodePen Embed Fallback This next example applies rotation on the x-axis for the tilting:
    CodePen Embed Fallback And, finally, we can apply it on the z-axis for a rotating example:
    CodePen Embed Fallback Layer Delay
    Working with separate layers does not just let us tweak the animation for each one; it also lets us adjust the animation-delay for every layer individually, which can lead to some really interesting effects. Let us take this pulsing example:
    CodePen Embed Fallback Right now, the animation is applied to the .layeredText element itself, and I am simply changing its scale:
    .layeredText { animation: pulsing 2s infinite ease-out; } @keyframes pulsing { 0%, 100% { scale: 1; } 20% { scale: 1.2; } } But we can apply the animation to each layer separately and give each one a slight delay. Note that the span is part of the stack. It is a layer, too, and sometimes you will want to include it in the animation:
    .layer { --delay: calc(var(--n) * 0.3s); } :is(span, .layer) { animation: pulsing 2s var(--delay, 0s) infinite ease-out; } Here I am using the :is selector to target both the individual layers and the span itself with the same animation. The result is a much more lively and engaging effect:
    CodePen Embed Fallback Pseudo Decorations
    In the previous chapter, I mentioned that I usually prefer to save pseudo elements for decorative purposes. This is definitely a technique worth using. We can give each layer one or two pseudo elements, add some content, position them however we like, and the 3D effect will already be there.
    It can be anything from simple outlines to more playful shapes. Like arrows, for example:
    CodePen Embed Fallback Notice that I am using the :is selector to include the span here, too, but sometimes we will not want to target all the layers — only a specific portion of them. In that case, we can use :nth-child to select just part of the stack. For example, if I want to target only the bottom twelve layers (out of twenty four total), the decoration only covers half the height of the text. I can do something like :nth-child(-n + 12) , and the full selector would be:
    :is(span, .layer:nth-child(-n + 12))::before { /* pseudo style */ } This is especially useful when the decoration overlaps with the text, and you do not want to cover it or make it hard to read.
    CodePen Embed Fallback Of course, you can animate these pseudo elements too. So how about a 3D “Loading” text with a built-in spinner?
    CodePen Embed Fallback I made a few changes to pull this off. First, I selected twelve layers from the middle of the stack using a slightly more advanced selector: .layer:nth-child(n + 6):nth-child(-n + 18). This targets the layers from number six to eighteen.
    Second, to fake the shadow, I added a blur filter to the span‘s pseudo element. This creates a nice soft effect, but it can cause performance issues in some cases, so use it with care.
    :is(span, .layer:nth-child(n + 6):nth-child(-n + 18))::before { /* spinner style */ } span { /* span style */ &::before { filter: blur(0.1em); } } Face Painting
    But you don’t have to use pseudo elements to add some visual interest. You can also style any text with a custom pattern using background-image. Just select the top layer with the :last-child selector, set its text color to transparent so the background shows through, and use background-clip: text.
    .layer { /* layer style */ &:last-child { color: transparent; background-clip: text; background-image: ... /* use your imagination */ } } Here is a small demo using striped lines with repeating-linear-gradient, and rings made with repeating-radial-gradient:
    CodePen Embed Fallback And, yes, you can absolutely use an image too:
    CodePen Embed Fallback Animating Patterns
    Let us take the previous idea a couple of steps further. Instead of applying a pattern just to the top layer, we will apply it to all the layers, creating a full 3D pattern effect. Then we will animate it.
    We’ll start with the colors. First, we give all the layers a transparent text color. The color we used before will now be stored in a custom property called --color, which we will use in just a moment.
    .layer { --n: calc(var(--i) / var(--layers-count)); --color: hsl(200 30% calc(var(--n) * 100%)); color: transparent; } Now let’s define the background, and we’ll say we want a moving checkerboard pattern. We can create it using repeating-conic-gradient with two colors. The first will be our --color variable, and the second could be transparent. But in this case, I think black with very low opacity works better.
    We just need to set the background-size to control the pattern scale, and of course, make sure to apply background-clip: text here too:
    .layer { --n: calc(var(--i) / var(--layers-count)); --color: hsl(200 30% calc(var(--n) * 100%)); color: transparent; background-image: repeating-conic-gradient(var(--color) 0 90deg, hsl(0 0% 0% / 5%) 0 180deg); background-size: 0.2em 0.2em; background-clip: text; transform: translateZ(calc(var(--i) * var(--layer-offset))); animation: checkers 24s infinite linear; } @keyframes checkers { to { background-position: 1em 0.4em; } } As you can see, I have already added the animation property. In this case, it is very simple to animate the pattern. Just slowly move the background-position, and that is it. Now we have text with a moving 3D pattern:
    CodePen Embed Fallback Variable Fonts
    So far, we have been using a single font, and as I mentioned earlier, font choice is mostly a matter of taste or brand guidelines. But since we are already working with layered text, we absolutely have to try it with variable fonts. The idea behind variable fonts is that each one includes axes you can manipulate to change its appearance. These can include width, weight, slant, or just about anything else.
    Here are a few examples I really like. The first one uses the Climate Crisis font, which has a YEAR axis that ranges from 1979 to 2025. With each year, the letters melt slightly and shrink a bit. It is a powerful ecological statement, and when you stack the text in layers, you can actually see the changes and get a pretty striking 3D effect:
    CodePen Embed Fallback Another great option is Bitcount, a variable font with a classic weight axis ranging from 100 to 900. By changing the weight based on the layer index, you get a layered effect that looks like peaks rising across the text:
    CodePen Embed Fallback And here is an example that might give your browser a bit of a workout. The font Kablammo includes a MORF axis, and adjusting it completely changes the shape of each letter. So, I figured it would be fun to animate that axis (yes, font-variation-settings is animatable), and add a short delay between the layers, like we saw earlier, to give the animation a more dynamic and lively feel.
    CodePen Embed Fallback Delayed Position
    Before we wrap up this second chapter, I want to show you one more animation. By now you have probably noticed that there is always more than one way to do things, and sometimes it is just a matter of finding the right approach. Even the positioning of the layers, which we have been handling statically with translateZ, can be done a little differently.
    If we animate the layers to move along the z-axis, from zero to the full height of the text, and add an equal delay between each one, we end up with the same visual 3D effect, only in motion.
    .layer { --n: calc(var(--i) / var(--layers-count)); --delay: calc(var(--n) * -3s); animation: layer 3s var(--delay) infinite ease-in-out; } @keyframes layer { from { transform: translateZ(0); } to { transform: translateZ(calc(var(--layers-count) * var(--layer-offset))); } } This is a more advanced technique, suited for more complex animations. It is not something you need for every use case, but for certain effects, it can look very cool.
    CodePen Embed Fallback Wrapping Up
    So far, we have brought the layered text effect to life with movement, variation, and creative styling. We also saw how even small changes can have a huge visual impact when applied across layers.
    But everything we have done so far has been pre defined and self contained. In the next chapter, we are going to add a layer of interactivity. Literally. From simple :hover transitions to using JavaScript to track the mouse position, we will apply real-time transformations and build a fully responsive bulging effect.
    3D Layered Text Article Series
    The Basics Motion and Variations (you are here!) Interactivity and Dynamism (coming August 22) 3D Layered Text: Motion and Variations originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  21. by: Chris Coyier
    Tue, 19 Aug 2025 19:15:02 +0000

    Alex & Chris get into a fairly recent technological change at CodePen where we ditched our Elasticsearch implementation for just using our own Postgres database for search. Sometimes choices like this are more about team expertise, dev environment practicalities, and complexity tradeoffs. We found this change to be much better for us, which matters! For the most part search is better and faster. Postgres is not nearly as fancy and capable as Elasticsearch, but we werent taking advantage of what Elasticsearch had to offer anyway.
    For the power users out there: it’s true that we’ve lost the ability to do in-code search for now. But it’s temporary and will be coming back in time.
    Time Jumps
    00:07 Alex is back! 01:10 The history of search at CodePen 02:15 Why was Elasticsearch not the right choice for CodePen? 09:36 Why we’re using PostGres instead 15:18 What does triggers have to do with search? 21:02 Figuring out what people are actually searching for 24:19 Some of the tradeoffs in changing search
  22. by: Ahmed Alkabary
    Tue, 19 Aug 2025 17:35:01 +0530

    Ansible has become a cornerstone in the realm of automation, enabling efficient management of IT infrastructure through simple, yet powerful automation.
    This online course is meticulously designed to equip you with the essential skills and knowledge required to excel in the RHCE Ex294 Exam, where proficiency in Ansible is a key component.
    By enrolling in this course, you will delve into the intricacies of Ansible, mastering playbooks, roles, modules, and best practices for configuration management.
    Our hands-on approach ensures that you not only understand the theoretical concepts but also gain practical experience in automating tasks across diverse environments.
    Who is this course for?
    Whether you are a seasoned IT professional looking to enhance your automation skills or a newcomer aiming to break into the field, this course offers a structured path towards success in the RHCE Ex294 Exam.
    Even if you are not preparing for the RHCE exam, this is still a good learning resource on Ansible in general.
    This is a fully practical hands-on course for learning Ansible Automation. It will get you up and running with Ansible in no time.
    With this 12-chapter course, you'll learn how to automate your apps deployment and IT infrastructure operations with Ansible.
    As you can see, some chapters of the course are for Pro members only. The Pro membership costs $50 a year and you get this course in e-book format along with e-books on Linux commands and Bash, There is also a SSH video course for absolute beginners.
    If you do not want to spend $50, you can buy this exam preparation course in e-book format for $15 (or less depending on your geographical location).
    Learn Ansible Quickly - eBook for RHCE Certification
    Master All Ansible Automation skills required to pass EX294 exam and become a Red Hat Certified Engineer.
    Get it for $15
  23. by: Abdullah Tarek
    Tue, 19 Aug 2025 13:06:24 +0530

    Welcome to the "Linux for DevOps" course! In the fast-paced world of DevOps, proficiency in Linux is not just a skill but a necessity. 
    Whether you are new to Linux or looking to deepen your skills, this course will guide you through essential concepts, command-line operations, and system administration tasks that form the backbone of Linux in the DevOps world.
    You'll start with the basics, break down the command line (it's not as scary as it sounds!), and dive into the essential tools you need. Whether you're a complete beginner or just looking to level up your skills, we've got you covered.
    No techy language, no unnecessary fluff—just practical learning that you can apply right away. Let's make Linux your friend!
    📶 Difficulty level: Beginner
    ⏳ Time to complete: Approx. 16 hours
    📋 Prerequisite: None
    🗒️ Type: Primarily text-based courseHow to use this course?
    This course is available only for Pro members of Linux Handbook. If you are not a Pro member yet, sign up here and you'll access all our premium courses as long as your subscription is active. Alternatively, you can purchase just this course for a single payment.Linux For DevOps - Courses by Linux HandbookWelcome to the “Linux for DevOps” course! In the fast-paced world of DevOps, proficiency in Linux is not just a skill but a necessity. Whether you are new to Linux or looking to deepen your skills, this course will guide you through essential concepts, command-line operations, and system administration tasks…Courses by Linux HandbookThroughout this course, you will gain practical skills through hands-on exercises, and real-world scenarios.
    The best approach here would be to follow the instructions and commands on your Linux system installed in a virtual machine.
    By the end, you'll have the knowledge and confidence to navigate, administrate, and automate Linux systems, making you a more effective DevOps professional.
    Without further ado, Let's dive in!
  24. Chris’ Corner: Faces

    by: Chris Coyier
    Mon, 18 Aug 2025 16:30:47 +0000

    It’s one of those weeks where I just feel like posting some specimen screenshots of new-to-me typefaces that I like and have saved.
    Haffer XH Babcock Bernie Dumpling Ultramega Gottak Pixel Imperfect Scorekard
  25. 3D Layered Text: The Basics

    by: Amit Sheen
    Mon, 18 Aug 2025 13:46:00 +0000

    Recently, a client asked me to create a bulging text effect. These are exactly the kinds of creative challenges I live for. I explored several directions, JavaScript solutions, SVG filters, but then I remembered the concept of 3D layered text. With a bit of cleverness and some advanced CSS, I managed to get a result I’m genuinely proud of.
    Visually, it’s striking, and it’s also a perfect project to learn all sorts of valuable CSS animation techniques. From the fundamentals of layering, through element indexing, to advanced background-image tricks. And yes, we’ll use a touch of JavaScript, but don’t worry about it right now.
    There is a lot to explore here, so this article is actually the first of a three part series. In this chapter, we will focus on the core technique. You will learn how to build the layered 3D text effect from scratch using HTML and CSS. We will cover structure, stacking, indexing, perspective, and how to make it all come together visually.
    In chapter two, we will add movement. Animations, transitions, and clever visual variations that bring the layers to life.
    In chapter three, we will introduce JavaScript to follow the mouse position and build a fully interactive version of the effect. This will be the complete bulging text example that inspired the entire series.
    3D Layered Text Article Series
    The Basics (you are here!) Motion and Variations (coming August 20) Interactivity and Dynamism (coming August 22) The Method
    Before we dive into the text, let’s talk about 3D. CSS actually allows you to create some wild three-dimensional effects. Trust me, I’ve done it. It’s pretty straightforward to move and position elements in a 3D space, and have full control over perspective. But there’s one thing CSS doesn’t give us: depth.
    If I want to build a cube, I can’t just give an element a width, a height, and a depth. There is no depth, it doesn’t work that way. To build a cube or any other 3D structure in CSS, we have two main approaches: constructive and layered.
    Constructive
    The constructive method is very powerful, but can feel a bit fiddly, with plenty of transforms and careful attention to perspective. You take a bunch of flat elements and assemble them together, somewhere between digital Lego bricks and origami. Each side of the shape gets its own element, positioned and rotated precisely in the 3D space. Suddenly, you have a cube, a pyramid, or any other structure you want to create.
    And the results can be super satisfying. There’s something unique about assembling 3D objects piece by piece, watching flat elements transform into something with real presence. The constructive method opens up a world where you can experiment, improvise, and invent new forms. You could even, for example, build a cute robot bouncing on a pogo stick.
    CodePen Embed Fallback Layered
    But here we’re going to focus on the layered method. This approach isn’t about building a 3D object out of sides or polygons. Instead, it’s all about stacking multiple layers, sometimes dozens of them, and using subtle shifts in position and color to create the illusion of depth. You’re tricking the eye into seeing volume and bulges where there’s really just a clever pile of flat elements.
    This technique is super flexible. Think of a cube of sticky memo papers, but instead of squares, the papers are cut to shape your design. It’s perfect for text, 3D shapes, and UI elements, especially with round edges, and you can push it as far as your creativity (and patience) will take you.
    CodePen Embed Fallback Accessibility note: Keep in mind that this method can easily become a nightmare for screen reader users, especially when applied to text. Make sure to wrap all additional and decorative layers with aria-hidden="true". That way, your creative effects won’t interfere with accessibility and ensure that people using assistive technologies can still have a good experience.
    Creating a 3D Layered Text
    Let’s kick things off with a basic static example, using “lorem ipsum” as a placeholder (feel free to use any text you want). We’ll start with a simple container element with a class of .text. Inside, we’ll put the original text in a span (it will help later when we want to style this text separately from the layered copies), and another div with a class of “layers” where we’ll soon add the individual layers. (And don’t forget the aria-hidden.)
    <div class="text"> <span>Lorem ipsum</span> <div class="layers" aria-hidden="true"></div> </div> Now that we have our wrapper in place, we can start building out the layers themselves. In chapter three, we will see how to build the layers dynamically with JavaScript, but you can generate them easily with a simple loop in your preprocessor (if you are using one), or just add them manually in the code. Check out the pro tip below for a quick way to do that. The important thing is that we end up with something that looks like this.
    <div class="layers" aria-hidden="true"> <div class="layer"></div> <div class="layer"></div> <div class="layer"></div> <!-- ...More layers --> </div> Great, now we have our layers, but they are still empty. Before we add any content, let’s quickly cover how to assign their indexes.
    Indexing the layers
    Indexing simply means assigning each layer a variable (let’s call it --i) that holds its index. So, the first layer gets --i: 1;, the second gets --i: 2;, and so on. We’ll use these numbers later on as values for calculating each layer’s position and appearance.
    There are a couple of ways to add these variables to your layers. You can define the value for each layer using :nth-child in CSS, (again, a simple loop in your preprocessor, if you’re using one), or you can do it inline, giving each layer element a style attribute with the right --i value.
    .layer { &:nth-child(1): { --i: 1; } &:nth-child(2): { --i: 2; } &:nth-child(3): { --i: 3; } /* ... More layers */ } …or:
    <div class="layers" aria-hidden="true"> <div class="layer" style="--i: 1;"></div> <div class="layer" style="--i: 2;"></div> <div class="layer" style="--i: 3;"></div> <!-- ...More layers --> </div> In this example, we will go with the inline approach. It gives us full control, keeps things easy to understand, and avoids dependency between the markup and the stylesheet. It also makes the examples copy friendly, which is great if you want to try things out quickly or tweak the markup directly.
    Pro tip: If you’re working in an IDE with Emmet support, you can generate all your layers at once by typing .layer*24[style="--i: $;"] and pressing Tab. The .layer is your class, *24 is the number of elements, attributes go in square brackets [ ], and $ is the incrementing number. But, If you’re reading this in the not-so-distant future, you might be able to use sibling-index() and not even need these tricks. In that case, you won’t need to add variables to your elements at all, just swap out var(--i) for sibling-index() in the next code examples.
    Adding Content
    Now let us talk about adding content to the layers. Each layer needs to contain the original text. There are a few ways to do this. In the next chapter, we will see how to handle this with JavaScript, but if you are looking for a CSS-only dynamic solution, you can add the text as the content of one of the layer’s pseudo elements. This way, you only need to define the text in a single variable, which makes it a great fit for titles, short labels, or anything that might change dynamically.
    .layer { --text: "Lorem ipsum"; &::before { content: var(--text); } } The downside, of course, is that we are creating extra elements, and I personally prefer to save pseudo elements for decorative purposes, like the border effect we saw earlier. We will look at more examples of that in the next chapter.
    A better, more straightforward approach is to simply place the text inside each layer. The downside to this method is that if you want to change the text, you will have to update it in every single layer. But since in this case the example is static and I do not plan on changing the text, we will simply use Emmet, putting the text inside curly braces {}.
    So, we will type .layers*24[style="--i: $;"]{Lorem ipsum} and press Tab to generate the layers.
    <div class="text"> Lorem ipsum <div class="layers" aria-hidden="true"> <div class="layer" style="--i: 1;">Lorem ipsum</div> <div class="layer" style="--i: 2;">Lorem ipsum</div> <div class="layer" style="--i: 3;">Lorem ipsum</div> <!-- ...More layers --> </div> </div> Let’s Position
    Now we can start working on the styling and positioning. The first thing we need to do is make sure all the layers are stacked in the same place. There are a few ways to do this as well , but I think the easiest approach is to use position: absolute with inset: 0 on the .layers and on each .layer, making sure every layer matches the container’s size exactly. Of course, we’ll set the container to position: relative so that all the layers are positioned relative to it.
    .text { position: relative; .layers, .layer { position: absolute; inset: 0; } } Adding Depth
    Now comes the part that trips some people up, adding perspective. To give the text some depth, we’re going to move each layer along the z-axis, and to actually see this effect, we need to add a bit of perspective.
    As with everything so far, there are a few ways to do this. You could give perspective to each layer individually using the perspective() function, but my recommendation is always to apply perspective at the parent level. Just wrap the element (or elements) you want to bring into the 3D world inside a wrapper div (here I’m using .scene) and apply the perspective to that wrapper.
    After setting the perspective on the parent, you’ll also need to use transform-style: preserve-3d; on each child of the .scene. Without this, browsers flatten all transformed children into a single plane, causing any z-axis movement to be ignored and everything to look flat. Setting preserve-3d; ensures that each layer’s 3D position is maintained inside the parent’s 3D context, which is crucial for the depth effect to come through.
    .scene { perspective: 400px; * { transform-style: preserve-3d; } } In this example, I’m using a fairly low value for the perspective, but you should definitely play around with it to suit your own design. This value represents the distance between the viewer and the object, which directly affects how much depth we see in the transformed layers. A smaller value creates a stronger, more exaggerated 3D effect, while a larger value makes the scene appear flatter. This property is what lets us actually see the z-axis movement in action.
    Layer Separation
    Now we can move the layers along the z-axis, and this is where we start using the index values we defined earlier. Let’s start by defining two custom properties that we’ll use in a moment: --layers-count, which holds the number of layers, and --layer-offset, which is the spacing between each layer.
    .text { --layers-count: 24; --layer-offset: 1px; } Now let’s set the translateZ value for each layer. We already have the layer’s index and the spacing between layers, so all we need to do is multiply them together inside the transform property.
    .layer { transform: translateZ(calc(var(--i) * var(--layer-offset))); } This feels like a good moment to stop and look at what we have so far. We created the layers, stacked them on top of each other, added some content, and moved them along the z-axis to give them depth. And this is where we’re at:
    CodePen Embed Fallback If you really try, and focus hard enough, you might see something that kind of looks like 3D. But let’s be honest, it does not look good. To create a real sense of depth, we need to bring in some color, add a bit of shadow, and maybe rotate things a bit for a more dynamic perspective.
    Forging Shadows
    Sometimes we might want (or need) to use the value of --i as is, like in the last snippet, but for some calculations, it’s often better to normalize the value. This means dividing the index by the total number of layers, so we end up with a value that ranges from 0 to 1. By normalizing, we keep our calculations flexible and proportional, so the effect remains balanced even if the number of layers changes.
    .layer { --n: calc(var(--i) / var(--layers-count)); } Now we can adjust the color for each layer, or more precisely, the brightness of the color. We’ll use the normalized value on the ‘light’ of a simple HSL function, and add a touch of saturation with a bluish hue.
    .layer { color: hsl(200 30% calc(var(--n) * 100%)); } Gradually changing the brightness between layers helps create a stronger sense of depth in the text. And without it, you risk losing some of the finer details
    CodePen Embed Fallback Second, remember that we wrapped the original text in a span so we could style it? Now is the time to use it. Since this text sits on the bottom layer, we want to give it a darker color than the rest. Black works well here, and in most cases, although in the next chapter we will look at examples where it actually needs to be transparent.
    span { color: black; text-shadow: 0 0 0.1em #003; } Final Touches
    Before we wrap this up, let us change the font. This is of course a matter of personal taste or brand guidelines. In my case, I am going with a bold, chunky font that works well for most of the examples. You should feel free to use whatever font fits your style.
    Let us also add a slight rotation to the text, maybe on the x-axis, so the lettering appears at a better angle:
    .text { font-family: Montserrat, sans-serif; font-weight: 900; transform: rotateX(30deg); } And there you have it, combining all the elements we’ve covered so far: the layers, indexes, content, perspective, positioning, and lighting. The result is a beautiful, three-dimensional text effect. It may be static for now, but we’ll take care of that soon.
    CodePen Embed Fallback Wrapping Up
    At this point, we have a solid 3D text effect built entirely with HTML and CSS. We covered everything from structure and indexing to layering, depth, and color. It may still be static, but the foundation is strong and ready for more.
    In the next chapters, we are going to turn things up. We will add motion, introduce transitions, and explore creative ways to push this effect further. This is where it really starts to come alive.
    3D Layered Text Article Series
    The Basics (you are here!) Motion and Variations (coming August 20) Interactivity and Dynamism (coming August 22) 3D Layered Text: The Basics originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

Important Information

Terms of Use Privacy Policy Guidelines We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.