Oh, the Many Ways to Make Triangular Breadcrumb Ribbons!
Apr 21, 2025 am 11:26 AMVarious ways to make triangle bread crumb strips
This article explores how to create a series of interconnected links that appear similar to the V-shaped shapes and notches in each block seen in the step-by-step breadcrumb navigation.
This style is common in web design, such as multi-step forms and website breadcrumb navigation. We call these styles "banding" for ease of understanding.
Like many web elements, we can create these stripes in a variety of ways! I created a demo page with multiple methods, such as using CSS triangles, SVG backgrounds, and CSS clip-path properties.
HTML structure
The HTML structure of each demonstration is basically the same, including a parent element<nav></nav>
The link to elements and as child elements.
<nav aria-label="breadcrumbs" role="navigation"> <a href="http://ipnx.cn/link/3dc023ccc7e0bd23ce2d4427756fd03c">Home page</a> <a href="http://ipnx.cn/link/3dc023ccc7e0bd23ce2d4427756fd03ccategories/articles/">blog</a> <a aria-current="page" href="http://ipnx.cn/link/3dc023ccc7e0bd23ce2d4427756fd03carticles/building-an-animated-sticky-header-with-custom-offset/">article</a> </nav>
Please note that according to the A11y Style Guide, these elements should comply with accessibility standards. When designing components, it is important to consider accessibility and introducing accessibility at the outset is the best way to avoid the “forget to add accessibility” problem.
Basic style
For this type of style, we need to make sure the element size is correct. To do this, we will define the font size of .ribbon
(we call these elements "bands") wrap the element, and then use the em unit on the child element (link).
/* Define the font size of the wrapping element*/ .ribbon { font-size: 15px; } /* Use em units to define the size of the stripe element*/ .ribbon__element { font-size: 1.5em; letter-spacing: 0.01em; line-height: 1.333em; padding: 0.667em 0.667em 0.667em 1.333em; }
This technique is beneficial to define the triangle shape size for each strip, as we will use the same size to calculate the triangle. Since we use em units to calculate the size of striped elements, we can resize all elements by redefining the font size of the wrapper element.
Let's use CSS Grid for layout, because we can do that. We can do this using a wider range of browser-enabled approaches, but it depends on your support needs.
We will define four columns:
- Three columns are used for stripe elements
- A column is used to solve the spacing problem. As is, the right arrow shape will be placed outside the strip assembly, which may mess up the original layout.
/* Packaging Elements* We use CSS Grid, but make sure it meets your browser support requirements. * Suppose that autoprefixer is used for vendor prefixes and attributes. */ .ribbon { display: grid; grid-gap: 1px; grid-template-columns: repeat(auto-fill, 1fr) 1em; /* Automatically fill three stripe elements with a narrow column to solve the size problem*/ }
If you want to avoid stretching strip elements, you can define the mesh differently. For example, we can use max-content
to resize the columns according to content size. (However, note that max-content
is not yet supported in some major browsers.)
/* Make the stripe column adjust according to the maximum content size*/ .ribbon--auto { grid-template-columns: repeat(3, max-content) 1em; }
I believe there are many different ways to layout. I like this approach because it defines the exact gap between striped elements without complex calculations.
Accessibility is more than just adding aria attributes. It also includes color contrast and readability, as well as adding hover and focus states. If you don't like outline styles, you can use other CSS properties such as box-shadow.
/* Use the current link color, but add underscore on hover*/ .ribbon__element:hover, .ribbon__element:active { color: inherit; text-decoration: underline; } /* Clear the default outline style and use the embedded box shadow to indicate the focus state*/ .ribbon__element:focus { box-shadow: inset 0 -3px 0 0 #343435; outline: none; }
Create unique triangle shapes
We have multiple options when defining the triangle at the end of each strip. We can:
- Create triangles with pseudo-elements and borders
- Using SVG background image on pseudo-element
- Using inline SVG images
- Create clip-path using
polygon()
function
Let's dig into each one.
Method 1: Border method
First, we should set the width and height of the element to zero so that it does not interfere with the pseudo-elements we use to draw the triangle. We should then draw the triangle using the border, specifically, define a solid left border that matches the background color, so that it blends with the rest of the strip. Next, let's define the top and bottom borders and set it to transparent. The trick here is to calculate the size of the border.
The content size of our stripe element is row high value plus top and bottom padding:
<code>1.333em 0.667em 0.667em = 2.667em</code>
This means that our top and bottom borders should be half the size of this. The only thing left is to absolutely position the element to the correct side of the component.
/* Left arrow*/ .ribbon--alpha .ribbon__element:before { /* Make content size zero*/ content: ''; height: 0; width: 0; /* Use borders to make pseudo-elements fit strip size*/ border-bottom: 1.333em solid transparent; border-left: 0.667em solid #fff; border-top: 1.333em solid transparent; /* Position the element absolutely to the left of the stripe element*/ position: absolute; top: 0; bottom: 0; left: 0; } /* Right arrow*/ .ribbon--alpha .ribbon__element:after { /* Make content size zero*/ content: ''; height: 0; width: 0; /* Use borders to make pseudo-elements fit strip size*/ border-bottom: 1.333em solid transparent; border-left: 0.667em solid; border-top: 1.333em solid transparent; /* Position the element absolutely to the right of the stripe element and push it outside*/ position: absolute; top: 0; right: 0; bottom: 0; -webkit-transform: translateX(0.667em); transform: translateX(0.667em); }
Since the right triangle should match the background color of the strip, remember to add the correct border color to the pseudo-elements of each strip.
/* Right arrow of the first element*/ .ribbon--alpha .ribbon__element:nth-child(1):after { border-left-color: #11d295; } /* Right arrow of the second element*/ .ribbon--alpha .ribbon__element:nth-child(2):after { border-left-color: #ef3675; } /* Right arrow of third element*/ .ribbon--alpha .ribbon__element:nth-child(3):after { border-left-color: #4cd4e9; }
That's it!
Method 2: Background image method
We can also create triangles using background images. This requires creating images that match the design, which is a bit cumbersome, but is still entirely possible. We will use SVG here because it will be smooth at any resolution.
Unlike the border triangle method, we want to match the height of the pseudo-element to the height of the stripe element (or 100%). The width of the component should match the left boundary width of the border triangle, which in our case is 0.666666em. Then we should use a white triangle as the background image on the left triangle and then a color triangle image on the right triangle. Again, we use absolute positioning to place the triangle on the correct side of the stripe element.
/* Left arrow*/ .ribbon--beta .ribbon__element:before { /* Define arrow size*/ content: ''; height: 100%; width: 0.666666em; /* Define background image that matches background color*/ background-image: url(data:image/svg xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSI jZmZmIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cmml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); background-position: center left; background-repeat: no-repeat; background-size: 100%; /* Position the element absolutely to the left of the stripe element*/ position: absolute; bottom: 0; top: 0; left: 0; } /* Right arrow*/ .ribbon--beta .ribbon__element:after { /* Define arrow size*/ content: ''; height: 100%; width: 0.667em; /* Define background image properties*/ background-position: center left; background-repeat: no-repeat; background-size: 100%; /* Position the element absolutely to the right of the stripe element and push it outside*/ position: absolute; top: 0; right: 0; bottom: 0; -webkit-transform: translateX(0.667em); transform: translateX(0.667em); } /* Define background image that matches the background color of the first element*/ .ribbon--beta .ribbon__element:nth-child(1):after { background-image: url(data:image/svg xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkP SJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjMTFkMjk1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cmml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); } /* Define background image that matches the background color of the second element*/ .ribbon--beta .ribbon__element:nth-child(2):after { background-image: url(data:image/svg xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkP SJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjZWYzNjc1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cmml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); } /* Define background image that matches the background color of the third element*/ .ribbon--beta .ribbon__element:nth-child(3):after { background-image: url(data:image/svg xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkP SJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjNGNkNGU5IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cmml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=); }
That's it!
The rest are similar to the original text, except that the statements are adjusted and replaced, leaving the original text unchanged. Due to space limitations, I will not repeat it here. Please refer to the original text to continue studying the remaining part.
The above is the detailed content of Oh, the Many Ways to Make Triangular Breadcrumb Ribbons!. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

There are three ways to create a CSS loading rotator: 1. Use the basic rotator of borders to achieve simple animation through HTML and CSS; 2. Use a custom rotator of multiple points to achieve the jump effect through different delay times; 3. Add a rotator in the button and switch classes through JavaScript to display the loading status. Each approach emphasizes the importance of design details such as color, size, accessibility and performance optimization to enhance the user experience.

To deal with CSS browser compatibility and prefix issues, you need to understand the differences in browser support and use vendor prefixes reasonably. 1. Understand common problems such as Flexbox and Grid support, position:sticky invalid, and animation performance is different; 2. Check CanIuse confirmation feature support status; 3. Correctly use -webkit-, -moz-, -ms-, -o- and other manufacturer prefixes; 4. It is recommended to use Autoprefixer to automatically add prefixes; 5. Install PostCSS and configure browserslist to specify the target browser; 6. Automatically handle compatibility during construction; 7. Modernizr detection features can be used for old projects; 8. No need to pursue consistency of all browsers,

Use the clip-path attribute of CSS to crop elements into custom shapes, such as triangles, circular notches, polygons, etc., without relying on pictures or SVGs. Its advantages include: 1. Supports a variety of basic shapes such as circle, ellipse, polygon, etc.; 2. Responsive adjustment and adaptable to mobile terminals; 3. Easy to animation, and can be combined with hover or JavaScript to achieve dynamic effects; 4. It does not affect the layout flow, and only crops the display area. Common usages are such as circular clip-path:circle (50pxatcenter) and triangle clip-path:polygon (50%0%, 100 0%, 0 0%). Notice

Themaindifferencesbetweendisplay:inline,block,andinline-blockinHTML/CSSarelayoutbehavior,spaceusage,andstylingcontrol.1.Inlineelementsflowwithtext,don’tstartonnewlines,ignorewidth/height,andonlyapplyhorizontalpadding/margins—idealforinlinetextstyling

Setting the style of links you have visited can improve the user experience, especially in content-intensive websites to help users navigate better. 1. Use CSS's: visited pseudo-class to define the style of the visited link, such as color changes; 2. Note that the browser only allows modification of some attributes due to privacy restrictions; 3. The color selection should be coordinated with the overall style to avoid abruptness; 4. The mobile terminal may not display this effect, and it is recommended to combine it with other visual prompts such as icon auxiliary logos.

To create responsive images using CSS, it can be mainly achieved through the following methods: 1. Use max-width:100% and height:auto to allow the image to adapt to the container width while maintaining the proportion; 2. Use HTML's srcset and sizes attributes to intelligently load the image sources adapted to different screens; 3. Use object-fit and object-position to control image cropping and focus display. Together, these methods ensure that the images are presented clearly and beautifully on different devices.

The choice of CSS units depends on design requirements and responsive requirements. 1.px is used for fixed size, suitable for precise control but lack of elasticity; 2.em is a relative unit, which is easily caused by the influence of the parent element, while rem is more stable based on the root element and is suitable for global scaling; 3.vw/vh is based on the viewport size, suitable for responsive design, but attention should be paid to the performance under extreme screens; 4. When choosing, it should be determined based on whether responsive adjustments, element hierarchy relationships and viewport dependence. Reasonable use can improve layout flexibility and maintenance.

Different browsers have differences in CSS parsing, resulting in inconsistent display effects, mainly including the default style difference, box model calculation method, Flexbox and Grid layout support level, and inconsistent behavior of certain CSS attributes. 1. The default style processing is inconsistent. The solution is to use CSSReset or Normalize.css to unify the initial style; 2. The box model calculation method of the old version of IE is different. It is recommended to use box-sizing:border-box in a unified manner; 3. Flexbox and Grid perform differently in edge cases or in old versions. More tests and use Autoprefixer; 4. Some CSS attribute behaviors are inconsistent. CanIuse must be consulted and downgraded.
