Inline inside flex - flexbox

I am currently using the following css to display a list of items with a flexbox
section ol li div ul {
display:flex;
flex-direction:row;
flex-wrap: wrap;
gap:7px;
row-gap:0;
list-style-type: none;
}
This satisfies me on all but one problem:
when I have a big item that will not fit entirely on the rest of the line, it will be set at the beginning of a new line, thus possibly making a huge part of the line before unused. I do not wish that (note that for small items, this is exactly what I want).
Initial goal (probably not achievable): I have been thinking on what kind of rule I would like and it would be something like "if more than x% of the line is wasted, then display the item inline instead". This would enable to continue filling the line.
I have currently abandoned on doing that with only html and css and I might consider trying to write such a rule in js later, but not for now (unless somebody has a very nice solution).
Current goal: I have thus decided to manually specify some items (that are "big") that should be inlined (sometimes using media queries, but we can ignore them for now). The idea is to add the following class to those objects.
.inlineitem {
display:inline;
}
Problem: display:inline; within a flex container does not work and I do not wish to change the whole flex container for the other items... Is there a way to achieve what I want ?

Related

Vertical scrollbar visibility in react-virtualized table

When using react-virtualized's Table class with a table with many columns, it is necessary to scroll horizontally to the very end of the columns in order to be able to see the vertical scrollbar.
(you can see an extremely similar question about React-Table here, it is not clear to me if react-virtualized's table code uses React-Table's code at all, but in any case I am having an identical problem)
in the linked issue someone commented that:
.ReactTable .rt-tbody{
overflow: initial !important;
}
fixed their issue. I checked this solution with react-table and got the desired behavior.
However, as far as I can tell react-virtualized table doesn't have tbody class available for css. (The docs do list a bunch of available class names, but a body class name doesn't seem to be on that list).
I've messed around with the css trying to set different overflow options in different ways to no avail. I have not been able to get the vertical scrollbar to display without needing to horizontally scroll all the way to the end. What can I do to make that happen?
(Edit: I've also tried to figure out some way to make this work with react-floating-scroll but it seems like the ref passed back by virtualized table isn't the kind of ref the scroll code needs...)
This will move the scroll bar to the left side instead of right side.
.ReactVirtualized__Table {
.ReactVirtualized__Table__Grid {
direction: rtl !important;
.ReactVirtualized__Grid__innerScrollContainer {
direction: ltr !important;
}
}
}

Custom Header Layout - Spartacus Storefront

Has anyone solved or knows how to solve the following situation given the implementation of the header in Spartacus?
I would like to show in the header, a layout on the right of two level blocks, and on the left of a single level block.
Objective Header Layout
I can't think of how to do it since I can't see how to wrap certain slots, given the Spartacus implementation for the header.
Given the implementation of the header in Spartacus, inside the StorefrontComponent I cannot replace it using the ConfigModule.withConfig ({...}, as CmsConfig)
I understand and already tried that I can replace the header, implementing an Outlet (cxOutletRef = "header"), but this makes it impossible to edit it through SmartEdit, which is not acceptable to me.
Any suggestion? Or possible solution?
As a last option it occurs to me that I can create a component type from the back, and map it from Angular using "ConfigModule.withConfig ({...}, as CmsConfig)" implementing the "conflicting two-level" block from scratch or even the entire header.
Thank you !
////// CORRECTION 09/23/20 //////
Outlets do not prevent editing via SmartEdit. It's necessary to indicate the Slot to which the component corresponds, this is easy to implement using the PageSlotComponent.
✔ Example:
<ng-template cxOutletRef="cx-header">
<header
cxSkipLink="cx-header"
[cxFocus]="{ disableMouseFocus: true }"
[class.is-expanded]="isExpanded$ | async"
(keydown.escape)="collapseMenu()"
(click)="collapseMenuIfClickOutside($event)"
>
<cx-page-slot position="MiniCart"></cx-page-slot>
</header>
<cx-page-slot position="BottomHeaderSlot"> </cx-page-slot>
<cx-global-message></cx-global-message>
</ng-template>
In this way, SmartEdit does allow you to edit the MiniCart component, within its corresponding slot.
🚫 Wrong way:
<ng-template cxOutletRef="cx-header">
<header
cxSkipLink="cx-header"
[cxFocus]="{ disableMouseFocus: true }"
[class.is-expanded]="isExpanded$ | async"
(keydown.escape)="collapseMenu()"
(click)="collapseMenuIfClickOutside($event)"
>
<cx-mini-cart></cx-mini-cart>
</header>
<cx-page-slot position="BottomHeaderSlot"> </cx-page-slot>
<cx-global-message></cx-global-message>
</ng-template>
you can indeed solve this with a custom layout configuration and additional CSS, but it's not necessary. I give you a few options to consider:
Option 1: Change the generated DOM
You can either provide a custom layout config as #pwavg suggests, or even introducing a custom storefront component.
If you introduce a custom layout config, you're limited by the sections we use in the storefront component. If you insist on custom sections (ie. an element that wraps the searchbox, login, mincart and nav), you need to introduce a custom storefront component. The disadvantage here is that you'll deviating away from standard Spartacus component, which might result in missing features in the future.
Option 2: Pure CSS
A pure CSS solution is the easiest. You do not need to change any actual DOM, but apply some custom CSS rules to the standard DOM. Grid system is indeed designed for this. It's a bit complex to start with, but would do the job.
You can actually achieve this with flexbox as well, but you'd need to move the logo slot out of the flexbox flow.
Here's an actual quick and dirty code snippet to demonstrate changing by a few CSS rules only. It comes with a few assumptions/limitations, but for most cases it might be fine.
header {
cx-page-slot.SiteLogo {
// we absolute position the logo, so it flows outside the flexbox system. this requires
// an hard-coded top position, that might be fine, but I don't know the details.
position: absolute;
top: 60px;
}
cx-page-slot.SearchBox {
// align searchbox to the left, not sure if that's required, but looks better
margin: 14px auto 14px 150px;
}
cx-page-slot.NavigationBar {
margin-left: 150px;
overflow: hidden;
}
// manipulate a very high logo to demonstrate this works
cx-page-slot.SiteLogo img {
height: 100px;
}
}
Result (sorry for the logo ;) )
Option 3: cx-header Outlet
I would say you should be able to use outlets as well, as this will get you closer to option 1 (changing the actual DOM). I can't think of a reason why it would not work in SmartEdit - but happy to learn if it is the case. I'd recommend in this case to use the cx-header outletRef, so you would replace the entire header.
I am not super experienced with Spartacus so this might not be the correct way. Just trying to think with you on this.
I think you can just extend you layoutconfig and style the slots with CSSGrid. So for example you layout could be something like this:
layoutSlots: {
header: {
lg: {
slots: [
'SiteLinks',
'SiteLogin',
'HeaderLinks',
'SiteLogo',
'NavigationBar',
'SearchBox',
'MiniCart',
'NavigationBar2',
],
},
slots: ... (for mobile view)
},
},
And create a custom css grid for the positions of the slot.
If you want to have more markup control you could use cxOutletRef to replace the header with something like:
<ng-template cxOutletRef="cx-header">
<header>
<div class="header-top">
<cx-page-layout section="headerTop"></cx-page-layout>
</div>
<div class="header-bottom">
<cx-page-layout section="headerBottom"></cx-page-layout>
</div>
</header>
</ng-template>
And then divide the slots between headerTop and headerBottom in you config.

React Virtualized Table drop down filter in header cut off by overflow: none

We have a React Virtualized Table with a header row.
One (or more) of the header cells will contain a drop down Componentallowing you to select values to filter the column by.
We have created the Component, and the ValuePanel has position: absolute; to make it float above the other elements on the page.
We included it in the header and it mostly works, except that the HeaderRow has overflow:none; on it.
<div
class="ReactVirtualized__Table__headerRow table-toplevel-row table-toplevel-header"
role="row"
style="height: 100px;overflow: hidden;padding-right: 17px;width: 1920px;"
>
This "chops off" the bottom of the panel showing the values.
Reading up on overflow: none; and position: absolute; it seems that the ValuePanel must have a (positional) parent outside of the HeaderRow.
This can be achieved by either:
Moving the ValuePanel element so it's no longer an ancestor of the HeaderRow.
Having the nearest ancestor of the ValuePanel element with a position of absolute or relative (i.e. it's positional parent) outside of the HeaderRow.
The problem with 1, is that the Component is supposed to be a self-contained and reusable anywhere, so it shouldn't require part of it's HTML to exist outside of itself ... that violates the "self-contained" bit.
The problems with 2 are that we won't always be able to guarantee where the positional parent is in the hierarchy above the ValuePanel unless the positional parent is inside the Component. And the ValuePanel gets it's width from it's positional parent, so if the positional parent is outside of the Component then the width could well be wrong.
We very much want to avoid having to specify a fixed width for the component and/or the ValuePanel. And we want to keep the Component self-contained.
The thought occurred to remove overflow: none; from the HeaderRow, but it's obviously there for a reason. I haven't tested, but I assume getting rid of that would cause issues with header content that, well, overflows. We could replace it with overflow-y: none;overflow-x: hidden;, but again this seems like it's likely to cause issues under certain circumstances.
I had a search around, but I couldn't find any results for it.
Has anyone achieved this before and can provide some insight? Or otherwise has some ideas/advice?
Slightly longer answer now that I'm back at my computer: Check out react-portal.
It lifts content out of the z-index stack (and so avoids clipping problems) while maintaining the visual position of it (top/left), allowing it to render outside of the clipping rect/box of its parent. It's perfect for things like drop-down menus within List or Table.

SASS; change font-family if size of element is above 16px

I don't even know if this is possible, I have to bring an RTL version of the website that is LTR.. I'm using Foundation 5 with Node and Grunt.Basically a file that overwrites some css rules of the original ltr file..
The client asked me to; Use a special font-family when the size of the element's text is above 16px.. Since other devs change the sass/css constantly I need a tool (or SASS formula) that allows to automatically switch the font-family when deploying the files with Grunt.
So instead of spending lots of time "scanning" the whole css/sass files for font-sizes and re-creating those rules with correct font-family.. I need something that automatically detects if the font-size is set then checks if it is above 16px, then if so, it changes the font family of the element.
Thanks
For me best way to do that is to use one SASS mixin to apply the font-size and check the value to apply the custom font :
#mixin custom-font-size($pixel) {
font-size: $pixel;
#if $pixel > 16 {
font-family: 'Comic Sans MS';
}
}
and call it like so :
#include custom-font-size(10px);

How can I efficiently overwrite CSS with a content script?

My problem is that I want to overwrite a style of a site. Thing is, there is a way to do this, using the !important sentence, as seen in this example.
However, there are thousands of CSS instructions in my file, is there a more quick/efficient way to do this, i.e. not putting !important on each and every single line?
The approach I've found easiest and most effective is to wrap whatever html template you're injecting in a div with a very specific id.
<div id="my-specific-id">
// Your injected HTML template or section of the website you want to change
</div>
Once you've done this, reset all of the CSS that might affect that section.
#my-specific-id {
// A comprehensive CSS reset
}
// The rest of your CSS will override the reset above
Here is one such reset: http://html5doctor.com/html-5-reset-stylesheet/
Note that you probably won't need everything from the CSS Reset, so remove what isn't relevant to take some load off the browser. I can't imagine that you really want to reset figcaption, for example.
As someone writing an extension, you should care a lot about whether or not your extension ruins the user experience on websites you inject scripts into.
The approach I've outlined will guarantee that only the sections of the website that you specifically care about are changed.
You can do this with your own templates (say you wanted to add a weather widget to every page without using an iframe) or with specific parts of the page. You could, for example, wrap all <p> elements in a highly specific id that you define.
Here's an example using Sass from a recent project I've been working on...
#specific-id-css-ultimate-reset {
html, button, input, div, p, img, form {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
#import "modules/all";
#import "components/all";
#import "popups/all";
}
<div id="my-superspecific-html-template-wrapper">
<HTML TEMPLATE>
</div>
Maybe it will be faster for you to include all styles from the original CSS that you don't wish to override in your injected stylesheet? If so, you can then remove the original stylesheet from page using content script/code injection or blocking the browser request for CSS file.
You can also write a small script that does some regex magic and adds !important to every line of given CSS file.

Resources