What is the best way to encapsulate a group of sibling HTML elements within a box?

Looking to visually accentuate a group of related elements that share a common attribute.

#boxed_contents span[data-boxme] {
  display: inline-block;
  border: 2px solid #00F;
  border-radius: 5px;
}
<div id="boxed_contents">
    <span>hello</span><!--
 --><span>world</span><!--
 --><span data-boxme>look</span><!--
 --><span data-boxme>at</span><!--
 --><span data-boxme>me</span>
</div>

This almost does the trick but I desire to enclose all 'boxme' elements within one box instead of individual boxes. While wrapping adjacent 'boxme' elements in a div is an option, I prefer a solution that doesn't involve changing the HTML structure due to it being more about visual design than structural layout.

Is it possible to achieve this using only CSS? If not, could Javascript be used to accomplish this with ease?

Answer №1

It's actually quite tricky to wrap elements within another using pure CSS. However, we can mimic the effect by adding borders to each adjacent element and placing a pseudo-element over the middle borders using absolute positioning.

By the way, it's important to remember that custom attributes are not considered valid in HTML unless they follow the format of data-*.

#boxed_contents [data-boxme] {
  display: inline-block;
  border: 2px solid #00F;
}

#boxed_contents [data-boxme] + [data-boxme] {
  margin-left: -.25em;
  padding-left: .25em;
  position: relative;
}

#boxed_contents [data-boxme] + [data-boxme]:after {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: -4px;
  width: 4px;
  background: white;
}
<div id="boxed_contents">
  <span>hello</span>
  <span>world</span>
  <span data-boxme>look</span>
  <span data-boxme>at</span>
  <span data-boxme>me</span>
  <span>not me</span>
</div>

Answer №2

Are you satisfied with the functionality of this?

var borderProps='2px solid #f00',borderRadius='5px',boxMeAttr='data-boxme';
var spans=document.querySelectorAll('span'),boxMeArrays=[],dummyArray=null,iterator=0;
var currSpan=null,prevSpan=null;
var i,length=spans.length,adjacentSpans=0;
for(i=0; i<length; i+=1){
    prevSpan=currSpan;
    currSpan=spans[i];
    if(currSpan.hasAttribute(boxMeAttr)){
        if(prevSpan!==null&&prevSpan.hasAttribute(boxMeAttr)){
            dummyArray[dummyArray.length]=currSpan;
        }else{
            dummyArray=[currSpan];
            boxMeArrays[iterator]=dummyArray;
            iterator+=1;
        }
    }
}
length=boxMeArrays.length;
for(i=0; i<length; i+=1){
    adjacentSpans=boxMeArrays[i].length;
    for(var j=0; j<adjacentSpans; j+=1){
        currSpan=boxMeArrays[i][j];
        if(adjacentSpans>1){
            if(j===0){
                currSpan.innerText+=' ';
                currSpan.style.borderLeft=currSpan.style.borderTop=currSpan.style.borderBottom=borderProps;
                currSpan.style.borderTopLeftRadius=currSpan.style.borderBottomLeftRadius=borderRadius;
            }else if(j===adjacentSpans-1){
                currSpan.style.borderTop=currSpan.style.borderBottom=currSpan.style.borderRight=borderProps;
                currSpan.style.borderTopRightRadius=currSpan.style.borderBottomRightRadius=borderRadius;
            }else{
                currSpan.innerText+=' ';
                currSpan.style.borderTop=currSpan.style.borderBottom=borderProps;
            }
        }else{
            currSpan.style.border=borderProps;
            currSpan.style.borderRadius=borderRadius;
        }
    }
}

It's definitely a bit complex, but I believe it is scalable. Additionally, to enhance the borders' appearance by joining them neatly, an extra space using innerText is added within your HTML.

You can view and test this solution on jsFiddle. Let me know if there are any overlooked details, and I genuinely hope this method meets your requirements.

Answer №3

I am grateful to the divine for guiding me in the right direction with the sibling selector, allowing me to uniquely style consecutive elements, and using a pseudo-selector to incorporate border elements.

In order to achieve the desired effect, I had to introduce a line of JavaScript code to ensure the presence of an empty span element without the boxme attribute at the end. This approach enables me to utilize the :before pseudo-element on any non-boxme element that follows a boxme element. The key advantage of this technique (compared to the one suggested by the divine) is that it preserves the rounded corners from my initial CSS design.

document.getElementById('boxed_contents').appendChild(document.createElement('span'));
#boxed_contents span[data-boxme] {
  border: 2px solid #00F;
  border-right: none;
  border-radius: 5px 0 0 5px;
  padding-left: 4px;
}
#boxed_contents span[data-boxme] + span[data-boxme] {
  border-left: none;
  border-radius: 0;
  padding-left: 0;
}
#boxed_contents span[data-boxme] + span:not([data-boxme]):before {
  content: "";
  border: 2px solid #00F;
  border-left: none;
  border-radius: 0 5px 5px 0;
  padding-right: 4px;
}
<div id="boxed_contents">
    <span>hello</span><!--
 --><span>world</span><!--
 --><span data-boxme>look</span><!--
 --><span data-boxme>at</span><!--
 --><span data-boxme>me</span>
</div>

Although I cannot guarantee the compatibility of this solution across all platforms, it appears to function effectively on Chrome, which is my primary target platform.

Answer №4

After reviewing the code, I have made some adjustments to align it with your desired functionality. The .boxme tag within the class element now applies the specified style within the #box_contents tag.

#boxed_contents.boxme {
  display: inline-block;
}
#boxed_contents.borderBox {
  border: 2px solid #00F;
  border-radius: 5px;
}

:)

<div id="boxed_contents">
  <span>hello</span>
  <span>world</span>
  <div class='borderBox'>
    <span class='boxme'>look</span>
    <span class='boxme'>at</span>
    <span class='boxme'>me</span>
  </div>
</div>

If you are familiar with the structure of the boxme elements, you can manipulate them further by enclosing them in an additional DIV container.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Selenium throws errors when elements become stale or are not clickable

I am a beginner when it comes to coding and I recently started it as a hobby. Please bear with me if my terminology is not entirely accurate. I have written a script that navigates to a webpage, continuously refreshes it until a certain element (currently ...

creating a responsive grid layout in react for mobile devices

My goal is to ensure that the videos displayed in a grid appear horizontally one after the other on mobile devices, while maintaining a vertical alignment on desktop view. I have experimented with setting values for rows and columns as "auto". retur ...

Utilizing lz-string to import and export game data in JavaScript for saving purposes

Lately, I've been discovering a multitude of web-based games that allow you to export and import your save game data. When you click "export," you receive a string of random characters as your save file. I want to store my save game state using lz-str ...

What is the best way to expand/shrink elements smoothly when hovering with CSS?

As a beginner in the world of coding, I am eager to tackle something simple in CSS. My current project involves a landing page that is divided into two sections down the middle. The left side features a yellow div, while the right side showcases a grey div ...

Obtain all the data in the table cells using Jquery

I've been tasked with a unique challenge. There's a table with a form inside it, and I'm using Jquery to handle the form. Is there a way to retrieve the data from the <td></td> element without any specific id or class? The situa ...

Can ng-click be injected into an ng-bound HTML div in an Angular application?

In my controller, I am returning HTML using the following function: $scope.filterLocation = function(obj) { var loc = $filter('filter')( $scope.locationss, {'product_code': obj}); var htmlstring = ""; angular.forEach(loc, function(v ...

The function `jQuery .html('<img>')` is not functional in Firefox and Opera browsers

This particular code snippet jq("#description" + tourId).html('<b>Opis: </b> '+ data); has been tested and functions correctly in Internet Explorer, Firefox, and Opera. However, when it comes to this specific piece of code jq("#i ...

Distinguishing Between the Heights and Maximum Heights of WebKit SVG

When running the following two examples in Chrome or Safari (Firefox remains unaffected), one can notice the differences in the width of the SVG image. Initially, the first example appears to exhibit the correct behavior in my opinion. However, in the sec ...

Experiencing difficulties in arranging Bootstrap columns based on media queries

I am creating a layout for a website that requires 4 columns. When the screen is in desktop mode or wider than tablet width, it should show all 4 columns with the outer 2 being used for padding only. However, in mobile mode, the outer 2 columns should di ...

Rearranging Twitter Bootstrap Grid Columns

Is it possible to rearrange columns in Bootstrap without using col-sm-pull-12/col-sm-push-12? I'm struggling to achieve the desired layout. Are there any alternative methods to accomplish this task? Check out this JSFiddle for reference. <div cla ...

What is the best way to merge two JSON values with the help of jQuery?

Two JSON Objects are provided below: The first one is: [{ "id": 5001, "count": "0", "type": "None" }, { "id": 5002, "count": "0", "type": "Glazed" }, { "id": 5005, "count": "0", "type": "Sugar" }, { "id": 5003, ...

Is there a way to remove the scrollbar from the menu created with react-burger-menu?

How can I remove the scroll bar from the menu created with react-burger-menu? Despite trying various CSS properties adjustments, I have not been able to achieve the desired effect. Here is an image of the open menu and the corresponding CSS: (https://i.st ...

"Incorporating images into a dropdown menu by utilizing the option value attribute

After attempting various solutions without success, I am reaching out for help as I am unable to find a fitting solution for my problem. The issue at hand is adding images to select list options based on the option value, with the limitation of not being a ...

Ways to arrange buttons vertically so they are perfectly aligned beneath one another

I'm trying to align a set of buttons, each containing an information icon, vertically under each other. The current alignment can be seen in image_1 below. Can someone please provide me with guidance on how to achieve this using CSS and HTML? I was t ...

"Experiencing Issues with jQuery as Thumbnails Caption is Not Functioning Proper

I am currently working on creating interactive thumbnails using jQuery. However, I have encountered an issue where the caption only displays on the last thumbnail. It doesn't show up individually for each one as intended. How can I modify my code to ...

Issues regarding the animation and hover effects of a button

I have successfully created a button with an animation on my webpage. The button pops up after 3-4 seconds, and when the user hovers over it, it widens. However, I'm encountering an issue where the pop-up animation restarts every time the button is ho ...

Disallow the use of punctuation marks such as dots, plus signs, minus signs, and the letter 'e' when entering

Is there a way to restrict the input of a dot, plus sign, minus sign, or letter 'e' when using semantic-ui-react library? I have searched for solutions but have not found any that work. Can someone provide assistance with this issue? ...

Optimal method for aligning decimal point of price within a django template

I need to show the total amount of money a user has spent in a table. I would like the display of the amount to be clean, but it currently looks like this: https://i.sstatic.net/kOpQ3.png I want the decimal point to line up perfectly on the black s ...

changing CSS styles

I'm struggling with what seems like a simple issue and can't find a solution anywhere. The HTML element I have is <div class="box"> It originally has this rule in its stylesheet: .box { width: 40%; } My Custom CSS sheet overwrites the o ...

Troubles with the placement of the navbar icon in responsive design

After following a tutorial on responsive navigation bars (https://www.w3schools.com/howto/howto_js_topnav_responsive.asp), I successfully implemented the navbar on my website. However, I encountered an issue with the icon placement when clicked. Here is ho ...