I have created a span which acts as a placeholder for figcaption. I am trying to center the placeholder but it is creating some padding(not sure) which I cannot control.
Here is the link for code sandbox.
sanbox
I have tried commenting out property width:0 which indeed centered the caption but the focus is misbehaving now.
This is the react component for span which acts as placeholder
<span
contentEditable={false}
style={{
pointerEvents: "none",
display: "inline-block",
width: "0",
maxWidth: "100%",
whiteSpace: "nowrap",
opacity: "0.333"
}}
>
Figure Caption
</span>
To reproduce the bug, please open the sandbox, place your cursor inside editor, and click on insert image button. As soon as you click it an image with caption gets inserted. Placeholder inside it is not centered.
Just remove width: "0" from settings. In a centered parent and child, the width:0 for a block (or inline-block) child element, puts it in the center of parent (in fact it puts the left of element in the center of parent) and if it contains text or any type of content, the content will grow to the right (The content overflows the zero-width element).
To overcome the focus problem there are some workarounds:
First Idea: using margin-left. You may still use width:0 but you have to set margin-left equal to half width of caption text. This idea needs more coding to calculate the dynamic width of caption as soon as text changes (onKeyup event).
Another Idea: Remove the width:0 but: Hide the default caption as soon as user clicks on the cpation and set it back again if the user input was null. You may hold the default caption in a data-caption tag to recover it easily.
Related
How do I make element visible only inside letters and not around them?
I want to position absolutely an element over some text and only make the element visible inside letters.
Is there something like "overflow: hidden" for the text?
Text to set overflow : hidden on
#Edit: Maybe I did not express myself well enough, I want to put some div or image etc. over some text and make it so the div/image, only shows trough letters as if they were holes cut in the foreground element, but I also want to keep text color when there is nothing "covering" it;
I don't understand what you want but there is the text-flow, that can help you.: text-flow
Look at this code, can help as well :
width: 200px; //define a fixed width
white-space: nowrap; //it's like flex-wrap: nowrap, avoid the line breaks
overflow: auto; //or hidden in your case
The following sandbox shows code that works perfectly well for a Material UI Table placed within a Paper component with a sticky header: https://codesandbox.io/s/2n40y
I would like the scrollbars (horizontal and vertical) to appear at the edges of the browser page, bottom and right respectively, yet still control the scrolling of the Table itself.
Currently I am only able to do this when removing the table from the Paper and making it a child of the page directly -- or a child of a main div that would span the full page height. Yet I need the Paper component to remain there, where other components will be placed above and below it.
Any ideas on how to achieve this?
UPDATE: in the attached sketch, the browser border appears in black and the scrollbars where they should ideally be appear in green. There is a container div in the middle of the page that contains the table in red. The table's headers should be sticky and the table shouldn't appear beyond the container div which acts as an aesthetic wrapper around it. Ideally, the browser vertical scrollbar would scroll the whole page down while leaving the page header (title + subtitle) and the table headers sticky. Also, when horizontally scrolling, the table should scroll within the container div. This is why I marked the parts that should not ideally appear in dashed lines.
All the changes we need to make are on demo.js
Firstly, we need to use a custom MUI TableContainer as the containerComponent for your #devexpress/dx-react-grid-material-ui Table. Basically, the purpose of this is so we can remove the overflow properties of the Table so that the scrolling is primarily for the body to address the requirement of
the scrollbars (horizontal and vertical) to appear at the edges of the
browser page, bottom and right respectively
import TableContainer from "#material-ui/core/TableContainer";
import makeStyles from "#material-ui/core/styles/makeStyles";
const useStyles = makeStyles({
tableContainer: {
overflow: "initial"
}
});
const MUITableContainer = ({ children, ...rest }) => {
const classes = useStyles();
return (
<TableContainer classes={{ root: classes.tableContainer }} {...rest}>
{children}
</TableContainer>
);
};
Secondly, at your MUITableContainer, get rid of the height: 400px so that the table's height will respond to the content. Again, the browser body bottom & right scrollbars will now control the document's scroll positions - this includes the table. Take a look at the Table containerComponent prop as well - we have assigned the custom TableContainer we created earlier.
<Paper>
<Grid rows={rows} columns={columns} rootComponent={GridRoot}>
<Table
containerComponent={MUITableContainer}
tableComponent={StickyTable}
/>
...
Lastly, to test this requirement:
there will be other objects before and after it.
Just render sample components before & after the Paper component
I cannot see the design spec you have referenced, but going off the sample in the comment on the first answer, I think you are trying to keep the header and footer from going off the left edge of the viewport when the user scrolls. But using just CSS, no JavaScript.
I took the entirety of the HTML (only the HTML) from your original code at https://codesandbox.io/s/2n40y (specifically <div id="root">) and dropped that into a Codepen.
Then I added a few visual design styles from your example so it looks kinda close.
Then I added the following CSS to make the column headers sticky:
th {
position: -webkit-sticky;
position: sticky;
top: 0;
}
I dropped in the following HTML as the first child and last child of <div id="root">, though it really doesn't matter where they live as long as they are not in the table.
<div class="stuckHeaderFooter">
[...]
</div>
To keep those from scrolling off screen when I scroll to the right, I made them sticky to the left (for RTL content you would need to make it sticky to the right):
.stuckHeaderFooter {
position: -webkit-sticky;
position: sticky;
left: 0;
padding: 0 1em;
display: inline-block;
}
The padding just makes it look less ugly. The inline-block is there to keep the block-level elements from filling the entire document width, which would keep them from being properly sticky since they would be wider than the viewport. You will probably have to set a max-width using vw units, but without knowing your content, target sizes, etc., I cannot say what would be best.
Finally, you have to remove the inline height: 400px on the first <div> under the root (<div class="MuiPaper-root MuiPaper-elevation1 MuiPaper-rounded" style="height: 400px;">). If you cannot override it because something injects it, then this style will override it for you but it brittle without knowing what else may be going on:
#root > div {
height: auto !important;
}
CSS only, no JavaScript in this approach at all, which is what I think you wanted.
Pen: https://codepen.io/aardrian/pen/PoNMopM
Debug view: https://cdpn.io/aardrian/debug/PoNMopM
Update: 5 October 2020: Looking at the sketch provided with the question, it is important to note that the container that does the clipping is the one that gets the scrollbar. So your options for a CSS-only solution are limited:
Add a fake block to make a visible border on the right (I updated the pen to add one; look at #root::after for an example but you will still need JS to make sure that does not appear until the table starts to get covered).
Yeah, I ran out of ideas.
In conclusion, I don't believe there is a CSS-only solution here because of how clipped areas work.
You can achieve this by setting the height and width to be equal to the viewport:
<Paper style={{ height: "100vh", width: "100vw" }}>
Example modified: https://codesandbox.io/s/table-sticky-header-forked-l77is?file=/demo.js
I am developing a configuration page using React. I have a list of configurable elements that are displayed in a table, and the "save" button is disabled and made transparent until a data field is modified, at which point the button is enabled, and becomes fully opaque.
However, when the button is in the disabled state, the buttons are rendered over top of parent elements, such as the sticky table header and nav bar. This becomes very apparent when scrolling. Enabling the buttons fixes the issue, and are no longer rendered over the parent elements.
Currently I am using the react-bootstrap Button component to render the button, but using a regular HTML button produces the same results. It also seems both disabling the button, or changing the opacity field independently will cause the issue as well.
<td className="saveButton">
<Button
variant="primary"
id={this.props.id}
disabled={!this.state.modified} //Only enable saving after data has been modified
style={this.state.modified ? {opacity: 1} : {opacity: 0.3}}
onClick={this.updateListItem}
>Save</Button>
</td>
The buttons should disappear beneath the sticky table header and navbar with the rest of the table row, but the buttons that are in a disabled state end up being rendered over top, like so:
(Note the enabled button correctly scrolling beneath the table header)
Any ideas where I've gone wrong?
I was able to reproduce your bug with a basic table layout using a sticky header. If you un-comment the z-index in the th you'll see it fixes the problem. https://codepen.io/sallf/pen/BaaBwmR
You've only shown the button inside the table, so I don't know exactly how you have your table set up, but this seems like a likely fix.
th {
position: sticky;
top: 0;
background: white;
// Remove z-index and td will appear
// to be over the td
z-index: 1;
}
As to why this is happening, I really don't know. It seems like a bug in the browser to me, but would be curious if anyone knows more.
Update
This happens because any element with an opacity less than 1 creates a new stacking context. Position inside a stacking context is determined by a stacking order.
According to the color module:
If an element with opacity less than 1 is not positioned, then it is painted on the same layer, within its parent stacking context, as positioned elements with stack level 0.
This basically means that a static element with opacity < 1 will be on the same stack level as a positioned element with the default z-index: auto (when they share the same parent stacking context).
When elements are on the same stack level, the stacking order is determined by the rendering tree (aka order of elements in your html). In this case, since the td comes after th in the html tree, td will be painted in front of th.
See an example on What No One Told You About Z-Index.
Related question.
I create a sidebar drawer using react material ui and try to create the clicked item on the sidebar drawer style to be like in this example http://react-material-dashboard.devias.io/dashboard.
I use the code from here https://github.com/mui-org/material-ui/blob/master/docs/src/pages/demos/drawers/ResponsiveDrawer.js to create the drawer.
And add style like this for the active item.
const styles = () => ({
clickedItem: {
borderLeft: "4px solid #0767DB",
borderRadius: "4px",
backgroundColor: "#F6F9FD",
marginLeft: "10px"
}
});
However, because of I add the marginLeft, the sidebar is now scrollable in x axis because it adds additional space on the right side. I want it to add margin of left without affecting the right side. I try to use overflow: "hidden". But, the y scroll bar is also hide and can't be scroll.
How to fix it so the item size (width) is still the same even though I add marginLeft?
I had a play with the browser-inspect on the dashboard linked.
Try adding: width:auto; to the styles you're passing the active element. This will stop the margin being added to the fixed width indiscriminately and causing the overflow.
Just as a bonus, it might help to add word-break: break-all; to avoid any singular long words also causing an overflow in the drawer.
Hope this helps!
My biggest problem here is to express what I want, so please free to alter the formulation / suggestion correct wording for things.
On mobile I wish my page to be only vertically scrollable (page width and view port width are the same. A bug is causing an element adding more width than it should. I have identified the culprit element, when I set this element style to "display:none;" the display is correct (no horizontal scroll), when I don't I get an horizontal scroll.
To make it clear, with ".culpritElement {display: none}":
With culpritElement visible:
culpritElement is generated with some inline style by a third party library that I don't want to tweak. Is there a CSS directive to set to make the element visible but out of the positioning flow of the others (and page size computing).
You could set .culpritElement { max-width: 100vw; overflow-x: hidden; }
Or you could apply the above css style to its parent element