How to get to use different CSS formatting for expandable quotes

Started by Julius_2000, March 03, 2023, 05:37:24 PM

Previous topic - Next topic

Julius_2000

Hi,

I've set a max-height for our quotes and sometimes, depending on content, it's not that apparent that there's more content hidden. Thus I would like to use a CSS linear-gradient mask that would have a transparent bottom to visually indicate the quote is cut short.

You cannot view this attachment.

Now, since expanding and shrinking of quotes are handled via javascript, I struggle to figure out how to do it. It would be great if I could have a class when shrinked and a class when expanded to switch my mask on and off. How can I achieve this?


Antechinus

I assume this is SMF 2.1, in which case you can use jQuery's toggleClass
https://api.jquery.com/toggleClass/

That will add/remove the defined class on click or touch (assuming that is how you are handling expand/collapse).

Julius_2000

Thank you so much @Antechinus for your reply!!! Yes, we use 2.1.3 and the quotes are handled as it's designed by SMF. So, could you please tell me how to implement your advice with the toggleClass, which files to edit and where? Would be so glad!

Could I edit the scripts.js file which contains the expanding/collapse of quotes?

// Expand quotes
if ((typeof(smf_quote_expand) != 'undefined') && (smf_quote_expand > 0))
{
$('blockquote').each(function(index, item) {

let cite = $(item).find('cite').first();
let quote_height = parseInt($(item).height());

if(quote_height < smf_quote_expand)
return;

$(item).css({
'overflow-y': 'hidden',
'max-height': smf_quote_expand +'px'
});

let anchor = $('<a/>', {
text: ' [' + smf_txt_expand + ']',
class: 'expand'
});

if (cite.length)
cite.append(anchor);

$(item).on('click', 'a.expand', function(event) {
event.preventDefault();

if (smf_quote_expand < parseInt($(item).height()))
{
cite.find('a.expand').text(' ['+ smf_txt_expand +']');
$(item).css({
'overflow-y': 'hidden',
'max-height': smf_quote_expand +'px'
});
}

else
{
cite.find('a.expand').text(' ['+ smf_txt_shrink +']');
$(item).css({
'overflow-y': 'visible',
'max-height': '100%',
});

expand_quote_parent($(item));
}

return false;
});
});
}
});

function expand_quote_parent(oElement)
{
$.each(oElement.parentsUntil('div.inner'), function( index, value ) {
$(value).css({
'overflow-y': 'visible',
'max-height': '',
}).find('a.expand').first().text(' ['+ smf_txt_shrink +']');
});
}

Julius_2000

Ok, with toggleClass approach I was able to set a class when clicking on "expand" but I wasn't able to set an initial class which would define the look of the shrunk quote (gradient mask).

So I looked again at the code and tried mimicking the $(item)css code by adding the css gradient mask directly below the existing lines "overflow" and "max-height", and it worked.

Quote// Expand quotes
   if ((typeof(smf_quote_expand) != 'undefined') && (smf_quote_expand > 0))
   {
      $('blockquote').each(function(index, item) {

         let cite = $(item).find('cite').first();
         let quote_height = parseInt($(item).height());

         if(quote_height < smf_quote_expand)
            return;

         $(item).css({
            'overflow-y': 'hidden',
            'max-height': smf_quote_expand +'px',
            'mask':   'linear-gradient(to bottom, #000 30%, transparent)'
         });

         let anchor = $('<a/>', {
            text: ' [' + smf_txt_expand + ']',
            class: 'expand'
         });

         if (cite.length)
            cite.append(anchor);

         $(item).on('click', 'a.expand', function(event) {
            event.preventDefault();

            if (smf_quote_expand < parseInt($(item).height()))
            {
               cite.find('a.expand').text(' ['+ smf_txt_expand +']');
               $(item).css({
                  'overflow-y': 'hidden',
                  'max-height': smf_quote_expand +'px',
                  'mask':   'linear-gradient(to bottom, #000 30%, transparent)'
               });
            }

            else
            {
               cite.find('a.expand').text(' ['+ smf_txt_shrink +']');
               $(item).css({
                  'overflow-y': 'visible',
                  'max-height': '100%',
                  'mask':   'none'
               });

               expand_quote_parent($(item));
            }

            return false;
         });
      });
   }
});

But is there a way to do it without defining the mask there and instead, like I initially tried, to set an intial class for expandable quotes, then use the toggleClass and define the formatting in index.css?

Antechinus

It should work if you set all the styling in the CSS files. All the javascript should need to do is add or remove the additional class.

The 2.1 markup is just a blockquote tag, with a cite tag inside it. So ignore the cite tag (not relevant for this).

1/ Set the blockquote to position: relative; (so that you can absolute position an ::after pseudo element within it). This just gets added to the default blockquote CSS in index.css.

2/ Set the ::after to position: absolute; and full width, stuck at the bottom.
blockquote::after {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: *your choice*px;
background: *gradient of your choice*;
content: '';
}
Note: Leave the content empty, unless you want text over the gradient, but the content declaration has to be there for a pseudo element to work.

Then you just write other CSS to deal with your expanded quotes. Presumably you just want to hide the gradient, so...
blockquote.expanded::after {
height: 0;
background: #0000;
}

You can add a transition to that if you like.
blockquote.expanded::after {
height: 0;
background: #0000;
transition: height ease-in-out .3s, background ease-in-out .3s;
}

Or you could leave the height alone, just transition the background to transparent, and set pointer-events: none; on the pseudo so that it doesn't get in the way of highlighting or clicking any quote content.
blockquote.expanded::after {
pointer-events: none;
background: #0000;
transition: background ease-in-out .3s;
}

Things like overflow, max-height, etc can also be dealt with like this.

Advertisement: