skip to Main Content

ETA: (See bottom for additional info)

Working with a very poorly designed CMS/cart system that has inline-styles embedded everywhere, and I am able to mostly override things using CSS, but there are some things left with hard coded !important properties.

It’s not my favorite method, but fortunately I can use JavaScript and .removeAttr() to clean up the mess. However, I am unable to get down into some deeply nested divs/spans.

$(document).ready(function() {
    $('#cartDiv').removeAttr('style');
});

The above works perfectly to remove all inline styles from #cartDiv but nothing below that is removed. I tried adding multiple lines, and even specifically target everything from #cartDiv using targeted selectors, but it didn’t seem to work. I want to remove styles from #cartDiv AND all child elements below it.

Edit to add – Here is an exmaple of some of the existing code:

<div id="cartDiv" style="top: 0; right: 0; width: 180px; text-align: center; padding: 0 5px 5px; z-index: 10;">
    <div style="display:table; height:28px; text-align:right; width:100%;"> 
        <span style="vertical-align:middle; display:table-cell; color: #ccc; font-family: Arial; font-size: 12px !important;"> 
            <a href="javascript:ProceedToCheckout('no');" style="color: #fff !important; text-decoration:underline !important; font-family: Arial !important; font-size: 12px !important; font-weight: normal !important;">Check Out</a> &nbsp; | &nbsp; <a href="checkout/cart.php?1" style="color: #fff !important; text-decoration:underline !important; font-family: Arial !important; font-size: 12px !important; font-weight: normal !important;">View Cart</a> &nbsp;&nbsp;&nbsp; </span> 
        <span style="vertical-align:middle; display:table-cell; color: #ccc; font-family: Arial; font-size: 12px !important;"> <a href="#" onclick="ExpandCart();"><img border="0" width="16" height="11" src="https://siteimages.s3.amazonaws.com/btn-expand.png"></a> </span>
    </div>  
</div>

ETA (additional info)

So it seems that the !important styles are added BY the javascript (cart.js) file dynamically to the #cartDiv and this file is linked in the footer. As I am unable to A, change the contents of the file; or B, change the contents of the footer (to maybe point to my own cart.js), I am left with trying to figure out how to override the following JS.

// Cart - This is what renders the expanded version of the cart in the upper corner
/** @return {boolean} */
function ExpandCart() {
    var oldCart = window.cartVersion != 2017;
    var cartDiv = $("#cartDiv");
    var cartDivMobile = $("#cartDivMobile");

    var products = '';
    var subtotal = 0;
    var subtotal_to_discount = 0;
    var giftCardSubtotal = 0;
    var totalItems = 0;
    var numProducts = 0;
    var numGiftCards = 0;

    if (oldCart) {
        UpdateCouponsInCartArrayAndCookie();
    }

    // Item totals
    for (var i = window.cartArray.length - 1; i >= 0; i--) {
        var row = window.cartArray[i];
        if (row[0] == 'product') {
            if (row[1].indexOf('PITEM') > -1) {
                continue;
            }
            totalItems += Number(row[4]);
            var displayPrice = 0;
            if (row[25]) {
                displayPrice = row[25];
            } else {
                displayPrice = row[3];
            }

            var amount = Math.round((parseFloat(displayPrice) * row[4]) * 100) / 100;
            if (row.length > 16 && row[16] == 'GC') {
                giftCardSubtotal += amount;
                numGiftCards++;
            } else {
                numProducts++;
                subtotal += amount;

                // 19 - discount_eligible
                if (row[19] === "true") {
                    subtotal_to_discount += amount;
                }
            }

            if (oldCart) {

                products +=
                    '<div style="font-size: 12px !important; line-height: 20px; border-bottom: 1px solid #999; padding-bottom:5px; margin-bottom: 10px;">' +
                    '<div style="line-height: 14px; font-size: 11px !important; margin-bottom:4px;">' +
                    window.cartArray[i][2].replace(/+/g, ' ') +
                    '</div>' +
                    '<div><b>' + formatCurrency(displayPrice) + '</b></div>' +

                    '<span style="font-size: 10px; color: #999;">quantity: ' + row[4] + '</span><br><br>' +
                    '</div>';
            }
        }
    }

3

Answers


  1. You could do a recursive function, and I probably will. But in the mean time you could always:

    UPDATE: added the logic inside a MutationObserver callback

    // original solution
    $("#cartDiv, #cartDiv *").attr("style", null);
    
    
    // recursive solution
    function cleanStyle(elem) {
      elem.removeAttribute("style");
      [...elem.children].forEach(cleanStyle);
    }
    // cleanStyle(document.querySelector("#cartDiv"))
    
    var cartDiv = document.querySelector("#cartDiv")
    
    
    function addToCart() {
      var html = `<h1 style="background:blue !important">hello h1</h1>
      <div>
        <h2 style="color: red !important">?</h2>
        <h2 style="color: red !important">?</h2>
      </div>
      `;
      cartDiv.innerHTML = html;
    }
    
    
    const config = {
      attributes: true,
      childList: true,
      subtree: true
    };
    
    const observer = new MutationObserver(function(mutationList, observer) {
      cleanStyle(cartDiv)
      // observer.disconnect();
    });
    
    observer.observe(cartDiv, config);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    <div id="cartDiv" style="padding:10px !important">
      <p>
      this is the empty cart
      </p>
      <!-- 
      <h1 style="background:blue !important">hello h1</h1>
      <div>
        <h2 style="color: red !important">?</h2>
        <h2 style="color: red !important">?</h2>
      </div>
      -->
    </div>
    
    <button onclick="addToCart()">add something COLORFUL to cart</button>
    Login or Signup to reply.
  2. To dynamically remove all style attributes from an element and all of its children and their children you can use the javascript querySelectorAll method with some css selectors. Here is an example using JavaScript rather than jQuery.

    document.querySelectorAll('#cartDiv, #cartDiv *')
      .forEach((element) => element.removeAttribute('style');
    
    Login or Signup to reply.
  3. This might not be the quick fix you’re looking for however i’ve dealt with this before and in the long run the best thing to do is migrate/refactor styling into a scss file or _files.
    For example changing something like this first h1 to the h2 and scss file

    <h1 style='color:red !important'> this is bad> </h1> 
    
    (change to ->) 
    <div className='text-wrapper">
       <h2> this is good </h2>
    </div>
    
    SCSS FILE: 
    .text-wrapper{
        h2{
            color: blue; 
            //could also add classname to the h2 html instead
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search