Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Sunshine And March Vibes (2025 Wallpapers Edition)

      May 8, 2025

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      May 8, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      May 8, 2025

      How To Prevent WordPress SQL Injection Attacks

      May 8, 2025

      Xbox handheld leaks in new “Project Kennan” photos from the FCC — plus an ASUS ROG Ally 2 prototype with early specs

      May 8, 2025

      OpenAI plays into Elon Musk’s hands, ditching for-profit plan — but Sam Altman doesn’t have Microsoft’s blessing yet

      May 8, 2025

      “Are we all doomed?” — Fiverr CEO Micha Kaufman warns that AI is coming for all of our jobs, just as Bill Gates predicted

      May 8, 2025

      I went hands-on with dozens of indie games at Gamescom Latam last week — You need to wishlist these 7 titles right now

      May 8, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      NativePHP Hit $100K — And We’re Just Getting Started 🚀

      May 8, 2025
      Recent

      NativePHP Hit $100K — And We’re Just Getting Started 🚀

      May 8, 2025

      Mastering Node.js Streams: The Ultimate Guide to Memory-Efficient File Processing

      May 8, 2025

      Sitecore PowerShell commands – XM Cloud Content Migration

      May 8, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      8 Excellent Free Books to Learn Julia

      May 8, 2025
      Recent

      8 Excellent Free Books to Learn Julia

      May 8, 2025

      Janus is a general purpose WebRTC server

      May 8, 2025

      12 Best Free and Open Source Food and Drink Software

      May 8, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»Revisiting CSS border-image

    Revisiting CSS border-image

    March 21, 2025

    In my last article on “Revisiting CSS Multi-Column Layout”, I mentioned that almost twenty years have flown by since I wrote my first book, Transcending CSS. In it, I explained how and why to use what were, at the time, an emerging CSS property.

    Ten years later, I wrote the Hardboiled Web Design Fifth Anniversary Edition, covering similar ground and introducing the new CSS border-image property.

    Hint: I published an updated version, Transcending CSS Revisited which is free to read online. Hardboiled Web Design is available from my bookshop.

    I was very excited about the possibilities this new property would offer. After all, we could now add images to the borders of any element, even table cells and rows (unless their borders had been set to collapse).

    Since then, I’ve used border-image regularly. Yet, it remains one of the most underused CSS tools, and I can’t, for the life of me, figure out why. Is it possible that people steer clear of border-image because its syntax is awkward and unintuitive? Perhaps it’s because most explanations don’t solve the type of creative implementation problems that most people need to solve. Most likely, it’s both.

    I’ve recently been working on a new website for Emmy-award-winning game composer Mike Worth. He hired me to create a highly graphical design that showcases his work, and I used border-image throughout.

    Design by Andy Clarke, Stuff & Nonsense. Mike Worth’s website will launch in April 2025, but you can see examples from this article on CodePen.

    A brief overview of properties and values

    First, here’s a short refresher. Most border-image explanations begin with this highly illuminating code snippet:

    border-image: [source] [slice]/[width]/[outset] [repeat]

    This is shorthand for a set of border-image properties, but it’s best to deal with properties individually to grasp the concept more easily.

    A border-image’s source

    I’ll start with the source of the bitmap or vector format image or CSS gradient to be inserted into the border space:

    border-image-source: url('/img/scroll.png');

    When I insert SVG images into a border, I have several choices as to how. I could use an external SVG file:

    border-image-source: url('/img/scroll.svg');

    Or I might convert my SVG to data URI using a tool like Base64.Guru although, as both SVG and HTML are XML-based, this isn’t recommended:

    border-image-source: url('data:image/svg+xml;base64,…');

    Instead, I can add the SVG code directly into the source URL value and save one unnecessary HTTP request:

    border-image-source: url('data:image/svg+xml;utf8,…');

    Finally, I could insert an entirely CSS-generated conical, linear, or radial gradient into my border:

    border-image-source: conical-gradient(…);

    Tip: It’s useful to remember that a browser renders a border-image above an element’s background and box-shadow but below its content. More on that a little later.

    Slicing up a border-image

    Now that I’ve specified the source of a border image, I can apply it to a border by slicing it up and using the parts in different positions around an element. This can be the most baffling aspect for people new to border-image.

    Most border-image explanations show an example where the pieces will simply be equally-sized, like this:

    Showing nine star shapes in the same images displayed as a three-by-three grid.

    However, a border-image can be developed from any shape, no matter how complex or irregular.

    Instead of simply inserting an image into a border and watching it repeat around an element, invisible cut-lines slice up a border-image into nine parts. These lines are similar to the slice guides found in graphics applications. The pieces are, in turn, inserted into the nine regions of an element’s border.

    Dissecting the top, right, bottom, and left slices of a border image.

    The border-image-slice property defines the size of each slice by specifying the distance from each edge of the image. I could use the same distance from every edge:

    border-image-slice: 65

    I can combine top/bottom and left/right values:

    border-image-slice: 115 65;

    Or, I can specify distance values for all four cut-lines, running clockwise: top, right, bottom, left:

    border-image-slice: 65 65 115 125;

    The top-left of an image will be used on the top-left corner of an element’s border. The bottom-right will be used on the bottom-right, and so on.

    Diagram of the nine border image slices.

    I don’t need to add units to border-image-slice values when using a bitmap image as the browser correctly assumes bitmaps use pixels. The SVG viewBox makes using them a little different, so I also prefer to specify their height and width:

    <svg height="600px" width="600px">…</svg>

    Don’t forget to set the widths of these borders, as without them, there will be nowhere for a border’s image to display:

    border-image-width: 65px 65px 115px 125px;

    Filling in the center

    So far, I’ve used all four corners and sides of my image, but what about the center? By default, the browser will ignore the center of an image after it’s been sliced. But I can put it to use by adding the fill keyword to my border-image-slice value:

    border-image-slice: 65px 65px 115px 125px fill;

    Setting up repeats

    With the corners of my border images in place, I can turn my attention to the edges between them. As you might imagine, the slice at the top of an image will be placed on the top edge. The same is true of the right, bottom, and left edges. In a flexible design, we never know how wide or tall these edges will be, so I can fine-tune how images will repeat or stretch when they fill an edge.

    Showing the same image four times, once per type of repeat, including stretch, repeat, round, and space.

    Stretch: When a sliced image is flat or smooth, it can stretch to fill any height or width. Even a tiny 65px slice can stretch to hundreds or thousands of pixels without degrading.

    border-image-repeat: stretch;

    Repeat: If an image has texture, stretching it isn’t an option, so it can repeat to fill any height or width.

    border-image-repeat: repeat;

    Round: If an image has a pattern or shape that can’t be stretched and I need to match the edges of the repeat, I can specify that the repeat be round. A browser will resize the image so that only whole pieces display inside an edge.

    border-image-repeat: round;

    Space: Similar to round, when using the space property, only whole pieces will display inside an edge. But instead of resizing the image, a browser will add spaces into the repeat.

    border-image-repeat: space;

    When I need to specify a separate stretch, repeat, round, or space value for each edge, I can use multiple keywords:

    border-image-repeat: stretch round;

    Outsetting a border-image

    There can be times when I need an image to extend beyond an element’s border-box. Using the border-image-outset property, I can do just that. The simplest syntax extends the border image evenly on all sides by 10px:

    border-image-outset: 10px;

    Of course, there being four borders on every element, I could also specify each outset individually:

    border-image-outset: 20px 10px; 
    /* or */
    border-image-outset: 20px 10px 0;

    border-image in action

    Mike Worth is a video game composer who’s won an Emmy for his work. He loves ’90s animation — especially Disney’s Duck Tales — and he asked me to create custom artwork and develop a bold, retro-style design.

    Four examples of page layouts, including the main menu, a default page, message received confirmation, and a 404 page, all featuring bold cartoon illustrations reminiscent of nineties Disney cartoons.

    My challenge when developing for Mike was implementing my highly graphical design without compromising performance, especially on mobile devices. While it’s normal in CSS to accomplish the same goal in several ways, here, border-image often proved to be the most efficient.

    Decorative buttons

    The easiest and most obvious place to start was creating buttons reminiscent of stone tablets with chipped and uneven edges.

    Illustration of chipped and zagged edges spliced up for border-image.

    I created an SVG of the tablet shape and added it to my buttons using border-image:

    button {
      border-image-repeat: stretch;
      border-image-slice: 10 10 10 10 fill;
      border-image-source: url('data:image/svg+xml;utf8,…');
      border-image-width: 20px;
    }

    I set the border-image-repeat on all edges to stretch and the center slice to fill so these stone tablet-style buttons expand along with their content to any height or width.

    CodePen Embed Fallback

    Article scroll

    I want every aspect of Mike’s website design to express his brand. That means continuing the ’90s cartoon theme in his long-form content by turning it into a paper scroll.

    Page layout of a paper scroll with jagged edges on the sides and rolled paper on the top and bottom.

    The markup is straightforward with just a single article element:

    <article>
      <!-- ... -->
    </article>

    But, I struggled to decide how to implement the paper effect. My first thought was to divide my scroll into three separate SVG files (top, middle, and bottom) and use pseudo-elements to add the rolled up top and bottom parts of the scroll. I started by applying a vertically repeating graphic to the middle of my article:

    article {
      padding: 10rem 8rem;
      box-sizing: border-box;
      /* Scroll middle */
      background-image: url('data:image/svg+xml;utf8,…');
      background-position: center;
      background-repeat: repeat-y;
      background-size: contain;
    }

    Then, I added two pseudo-elements, each containing its own SVG content:

    article:before {
      display: block;
      position: relative;
      top: -30px;
      /* Scroll top */
      content: url('data:image/svg+xml;utf8,…');
    }
    
    article:after {
      display: block;
      position: relative;
      top: 50px;
      /* Scroll bottom */
      content: url('data:image/svg+xml;utf8,…');
    }

    While this implementation worked as expected, using two pseudo-elements and three separate SVG files felt clumsy. However, using border-image, one SVG, and no pseudo-elements feels more elegant and significantly reduces the amount of code needed to implement the effect.

    I started by creating an SVG of the complete tablet shape:

    And I worked out the position of the four cut-lines:

    Then, I inserted this single SVG into my article’s border by first selecting the source, slicing the image, and setting the top and bottom edges to stretch and the left and right edges to round:

    article {
      border-image-slice: 150 95 150 95 fill;
      border-image-width: 150px 95px 150px 95px;
      border-image-repeat: stretch round;
      border-image-source: url('data:image/svg+xml;utf8,…');
    }

    The result is a flexible paper scroll effect which adapts to both the viewport width and any amount or type of content.

    CodePen Embed Fallback

    Home page overlay

    My final challenge was implementing the action-packed graphic I’d designed for Mike Worth’s home page. This contains a foreground SVG featuring Mike’s orangutan mascot and a zooming background graphic:

    <section>
      <!-- content -->
      <div>...</div>
    
      <!-- ape -->
      <div>
        <svg>…</svg>
      </div>
    </section>

    I defined the section as a positioning context for its children:

    section {
      position: relative;
    }

    Then, I absolutely positioned a pseudo-element and added the zooming graphic to its background:

    section:before {
      content: "";
      position: absolute;
      z-index: -1;
      background-image: url('data:image/svg+xml;utf8,…');
      background-position: center center;
      background-repeat: no-repeat;
      background-size: 100%;
    }

    I wanted this graphic to spin and add subtle movement to the panel, so I applied a simple CSS animation to the pseudo-element:

    @keyframes spin-bg {
      from { transform: rotate(0deg); }
      to { transform: rotate(360deg); }
    }
    
    section:before {
      animation: spin-bg 240s linear infinite;
    }

    Next, I added a CSS mask to fade the edges of the zooming graphic into the background. The CSS mask-image property specifies a mask layer image, which can be a PNG image, an SVG image or mask, or a CSS gradient:

    section:before {
      mask-image: radial-gradient(circle, rgb(0 0 0) 0%, rgb(0 0 0 / 0) 60%);
      mask-repeat: no-repeat;
    }

    At this point, you might wonder where a border image could be used in this design. To add more interactivity to the graphic, I wanted to reduce its opacity and change its color — by adding a colored gradient overlay — when someone interacts with it. One of the simplest, but rarely-used, methods for applying an overlay to an element is using border-image. First, I added a default opacity and added a brief transition:

    section:before {
      opacity: 1;
      transition: opacity .25s ease-in-out;
    }

    Then, on hover, I reduced the opacity to .5 and added a border-image:

    section:hover::before {
      opacity: .5;
      border-image: fill 0 linear-gradient(rgba(0,0,255,.25),rgba(255,0,0,1));
    }

    You may ponder why I’ve not used the other border-image values I explained earlier, so I’ll dissect that declaration. First is the border-image-slice value, where zero pixels ensures that the eight corners and edges stay empty. The fill keyword ensures the middle section is filled with the linear gradient. Second, the border-image-source is a CSS linear gradient that blends blue into red. A browser renders this border-image above the background but behind the content.

    CodePen Embed Fallback

    Conclusion: You should take a fresh look at border-image

    The border-image property is a powerful, yet often overlooked, CSS tool that offers incredible flexibility. By slicing, repeating, and outsetting images, you can create intricate borders, decorative elements, and even dynamic overlays with minimal code.

    In my work for Mike Worth’s website, border-image proved invaluable, improving performance while maintaining a highly graphical aesthetic. Whether used for buttons, interactive overlays, or larger graphic elements, border-image can create visually striking designs without relying on extra markup or multiple assets.

    If you’ve yet to experiment with border-image, now’s the time to revisit its potential and add it to your design toolkit.

    Hint: Mike Worth’s website will launch in April 2025, but you can see examples from this article on CodePen.

    About Andy Clarke

    Often referred to as one of the pioneers of web design, Andy Clarke has been instrumental in pushing the boundaries of web design and is known for his creative and visually stunning designs. His work has inspired countless designers to explore the full potential of product and website design.

    Andy’s written several industry-leading books, including Transcending CSS, Hardboiled Web Design, and Art Direction for the Web. He’s also worked with businesses of all sizes and industries to achieve their goals through design.

    Visit Andy’s studio, Stuff & Nonsense, and check out his Contract Killer, the popular web design contract template trusted by thousands of web designers and developers.


    Revisiting CSS border-image originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    Source: Read More 

    Hostinger
    Facebook Twitter Reddit Email Copy Link
    Previous ArticleBill Gates says Satya Nadella almost missed the cut for CEO of Microsoft — Even with Steve Ballmer’s support
    Next Article Resticity is a cross-platform UI for restic

    Related Posts

    News & Updates

    Xbox handheld leaks in new “Project Kennan” photos from the FCC — plus an ASUS ROG Ally 2 prototype with early specs

    May 8, 2025
    News & Updates

    OpenAI plays into Elon Musk’s hands, ditching for-profit plan — but Sam Altman doesn’t have Microsoft’s blessing yet

    May 8, 2025
    Leave A Reply Cancel Reply

    Continue Reading

    Researchers from NYU and the University of Maryland Unveil an Artificial Intelligence Framework for Understanding and Extracting Style Descriptors from Images

    Development

    The Future of React Native: Trends, Predictions & Innovations to Watch in 2025

    Web Development

    How to rename and retain the endpoint name for Amazon RDS

    Databases

    3D Shape Tokenization

    Machine Learning

    Highlights

    Problems to execute a UFT script by a VBScript file

    November 13, 2024

    I’m facing a problem when I try to execute a UFT script using a VBScript file to call it. The code inside the .vbs file is below:

    dim uft
    Set uft = CreateObject(“QuickTest.Application”)
    uft.Visible = False
    uft.Launch
    uft.Open “R:dataHPCJobsSpoolsubmit_2017.06_CAEDevGomputeBenchAppuft_script”
    uft.Test.Run Nothing, True, False
    uft.Quit
    Set uft = Nothing
    MsgBox “Test done”

    Inside the UFT script I have 7 actions. When I double click the .vbs file the first action execute without problems, but when arrives in the second action start my problem: in all my actions (except the first one) has a code to create a .txt file. When the script create the first one (in the second action) it just stop to run all the rest of the second action and jump to third action to create the second .txt file, doing this for the rest of the actions.

    I don’t know how this .vbs script are really doing and why it do not following the order of the script, because when I run inside UFT all works perfectly. Can anyone know what is the cause of this problem?

    Thanks and regards.

    How GoDaddy built a category generation system at scale with batch inference for Amazon Bedrock

    March 16, 2025

    CVE-2025-28037 – TOTOLINK A810R/A950RG Remote Command Execution

    April 23, 2025

    Collabwriting: How to create shareable notes on any web page – and more

    June 3, 2024
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.