Okay so my code isn't complex at all. I am watching a tutorial on react styled components and my code got to this point:
const Container = styled.div
`height: 60px;
`
const Wrapper = styled.div`
padding : 10px 20px;
display : flex;
justify-content : space-between;
`
const Left = styled.div`
flex : 1;
`
const Center = styled.div`
flex: 1;
`
const Right = styled.div`
flex : 1;
`
This is the rest of the code:
const Navbar = () => {
return (
<Container>
<Wrapper>
<Left>loremmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm</Left>
<Center>Center</Center>
<Right>Right</Right>
</Wrapper>
</Container>
)
}
export default Navbar
So what is basically happening is that i created 3 components on the same line named Left, Center and Right components and i put them inside a Wrapper component. What the flex attribute is meant to do is to give Left, Center and Right components equal space on the browser. Meaning that if there is some long string inside Left (as seen above), the Center and Right components maintain their positions and are not pushed to the side to accommodate Left. Its meant to be working but when i open my browser, this is what i see:
loremmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmCenterRight
meaning that the flex attribute is obviously not working? so anyone knows what i am doing wrong? and btw, the tutorial i am watching just came out in September 2021 so i doubt its because there's a change in the syntax or something, but if it is the case then please point it out.
That is because flex attempts to size according to your proportions by organizing around element boundaries - or words in case of text.
But it is not an absolute rule. Since you're having a gigantic word that cannot be wrapped flex does the best it can do under this condition. Similar to how you would usually not want to break up or hide parts of a large button to respect proportions at all costs. This is called overflow.
Your CSS should work if you have different paragraph sizes with normal words.
One option is to hide overflow or show a scroll bar:
const Left = styled.div`
flex : 1;
overflow: hidden; # also scroll
# text-overflow: ellipsis; # Optional to show a nicer "Loremmmmm..."
`
Alternatively you can permit wrapping on letter boundary - breaking up long words will also make flex proportions achievable:
const Left = styled.div`
flex : 1;
overflow-wrap: anywhere;
`
Related
I´m havin issues with blocking the whole height of the screen. I made this navbar and want it to look like it´s "floating" on the page, by adding some margin around ist, so it´s not touching the border of the screen.
Using the height: 100% prop won´t work, bc I the margin won´t get attached at the bottom of the screen -> First it goes all the way down the screen, so that I have to scroll down a bit until the margin gets added + the following content does not appear to the right, but underneath the sidebar -> watch the image.
So I basically want this thing to be in a vertical div element for example, so that the next element will be next to the right of the navbar (right now the text "TEST" still is underneath the navbar).
I´m also using TailwindCSS, those are my classes attached to the wrapping div of the navbar:
import SidebarHeader from './sidebarHeader';
import SidebarMenu from './SidebarMenu';
const Sidebar = () => {
return (
<div
style={{ height: '100vh' }}
className=" m-5 rounded-2xl bg-primary w-80 border-l-4 border-primary transition duration-500 pl-5 py-5">
<SidebarHeader />
<SidebarMenu />
</div>
);
};
export default Sidebar;
App code:
import { BrowserRouter } from 'react-router-dom';
import './assets/tailwind.css';
import Sidebar from './page-components/sidebar';
import Header from './page-components/header';
function App() {
return (
<BrowserRouter>
<Sidebar />
<Header />
</BrowserRouter>
);
}
export default App;
// Header code
//const Header = () => {
// return <div>TEST</div>;
//};
//
//export default Header;
I could do a grid layout I guess, but I don´t know if that´s the smartest solution. There must be a way to have smth like a vertical block element or not?
Glad for any help I can get- cheers!
You can use css calc like height: calc(100vh - XXpx) and then you can add margins to it - sum of bottom and top margins must be equal to XXpx you defined earlier.
Or just wrap the sidebar in a parent component with some padding { height: 100vh; padding: XXpx}; display: flex;, with display flex. Child should have a flex-grow property set to 1.
To put something next to the sidebar, both elements should have display: inline-block; vertical-aligh: top in that case the second solution would not work unless you wrapp the sidebar parent + aside content in a wrapper div with display: flex property.
I am attempting to utilize the IBM Gantt Chart Component in a React application.
The goal is to get the gantt chart component to span the entire page as seen below:
In my JS source code, I have the following line:
return(
<div id="ganttDiv">
<GanttChart config={config} />
</div>
);
In my CSS, I set the width to 100% and the height to 100vh. I also put thick borders to determine the extents of the div.
#ganttDiv{
width: 100%;
height: 100vh;
border-color: rgb(102, 255, 0);
border-style: dashed;
border-width: 15px;
background-color: rgb(255, 255, 255);
}
Instead of the React element spanning the entire page, I get:
As you can see, the div correctly fills the entire page as shown with the green borders, but the contents of the div don't expand to fill the space.
After researching and looking around for several hours, I learned that I could use flex boxes.
Therefore, I added display: flex; to my CSS, and now the height looks correct:
Unfortunately, the width now shrinks to less than half of the page instead of being 100% width from before.
I tried following the examples provided by MDN Web Docs and tried setting the CSS to row, row-reverse, column, and column-reverse which does not work.
It seems like I can only get it to span the entire width or span the entire height, but not both.
I hope that someone can help. Have a nice day. :-)
Edit:
When I compile it with using 100vw as the others suggested, it doesn't do anything. However, if I edit with F12 developer tools the imported component itself (not the div), it works. On the sidebar, it says that the component is only inheriting color from the div, nothing else. So what should I do?
To fix the problem, it was necessary to apply the width to the component itself, not the div. Unfortunately, the syntax for doing this with React is different since we use JSX instead of HTML.
Therefore, to the fix the problem I had to do:
return(
<div id="ganttDiv" >
<GanttChart config={config} style={{width: '100vw'}} />
</div>
);
I'm trying to build a component with multiline textfield. If the text entered exceeds 2 lines, then I'd like to add the ellipsis (...) for text-overflow.
How can I achieve this by just manipulating the css to show the ellipsis in display only but not modify the actual text that will be stored to contain '...'?
I'm using this React component link
Thanks
I just figured out how to solve this for React.
As Khodor mentioned, line-clamp is what you want. However, it's not currently supported by the official CSS spec. So, you can use -webkit-line-clamp as a sort of workaround. However, I struggled to figure out the exact syntax needed for React. I eventually figured out it out by peeking at the source code for this NPM package react-lines-ellipses and searching for 'webkit' in his github repo.
The React-specific CSS
const textStyle = {
maxWidth: '100%',
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 3,
overflow: 'hidden',
textOverflow: 'ellipsis',
};
I set the maxWidth to ensure the text filled the whole width of the display element. This is optional.
overflow: 'hidden' hides the extra text beyond the 3 lines (I chose 3 at random).
textOverflow: 'ellipses' adds an ellipses (...) to the end of the line, where it gets cut off.
The JSX
<div
onClick={toggleTruncate}
style={calculateTextStyle()}
>
This is where my long text goes.
</div>
// This function returns the correct style to the above div.
function calculateTextStyle() {
return truncate ? textStyle : null;
}
// I used React Hooks to create a variable in state to manage if the text should be truncated or not.
const [truncate, setToggleTruncate] = React.useState(true);
// This function toggles the state variable 'truncate', thereby expanding and truncating the text every time the user clicks the div.
function toggleTruncate() {
setToggleTruncate(!truncate);
}
for CSS only, you can use line-clamp, though it doesn't have the best browser support
Check this codepen for implementation.
display: block; /* Fallback for non-webkit */
display: -webkit-box;
max-width: 400px;
height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
margin: 0 auto;
font-size: $font-size;
line-height: $line-height;
-webkit-line-clamp: $lines-to-show;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
The javascript for this could look something like below. You take the value, split it into lines, and if there's more than one line, you wrap the following lines in parentheses.
The React component your using appears to take in an onChange prop, which could use a similar function.
const textAreaElement = document.getElementById('t')
textAreaElement.addEventListener('keyup', () => {
const value = textAreaElement.value.replace(/[\(\)]/g, '')
const splitLines = value.split(/(?:\r\n|\r|\n)/)
const newValue = splitLines.length > 1 ?
`${splitLines[0]}\n(${splitLines.slice(1, splitLines.length).join('\n')})` : splitLines[0]
textAreaElement.value = newValue;
});
<textarea id="t"></textarea>
An easy implementation for multi-line ellipsis will be using antd typography component. You can provide a prop called ellipsis with the value of number of rows after which it should be truncated.
<Paragraph ellipsis={{ rows: 3, expandable: true }}>
Ant Design, a design language for background applications, is refined by Ant UED Team.
Ant Design, a design language for background applications, is refined by Ant UED Team.
Ant Design, a design language for background applications, is refined by Ant UED Team.
Ant Design, a design language for background applications, is refined by Ant UED Team.
Ant Design, a design language for background applications, is refined by Ant UED Team.
Ant Design, a design language for background applications, is refined by Ant UED Team.
</Paragraph>
I have a React component which opens up a popup on a button click. So the popup has a Scrollbar and there is another component below the popup which contains the confirmation button and cancel button. Currently the popup's scrollbar is overlapping the other component as shown below:
The code for the screen is pasted below:
import styled from "styled-components";
const Wrapper = styled.div`
width: 90vw;
height: 90vh;
`;
const Content = styled.div`
height: fit-content;
padding-bottom: 150px;
`;
return (
<Wrapper>
<Content>{popupToDisplay()}</Content>
</Wrapper>
);
The popupToDisplay() function displays a popup depending on the result of a switch case.
So, now I am trying to move the Scrollbar above the purple line as shown in the image. I am able to reduce the size of the Popup by decreasing the 'height' property of the Wrapper component as shown below:
const Wrapper = styled.div`
width: 90vw;
height: 40vh;
`;
But now the issue while doing so is since the height is getting decreased, the popup is coming down from the top, i.e. there is space at the top as shown below:
I don't want the top of the popup to move down, only the bottom of the popup should move up. I also tried giving 'margin-bottom' property to the Wrappper constant, but its still not working. Can someone please help me with this.
Assuming I have 2 elements on a responsive design like this:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
both of them with style contains:
width: auto;
display: inline-block;
float: left;
And because I'm expecting different screen sizes to view page, so, according to screen size, sometimes they will be rendered/displayed on the same row, and sometimes they will not!, the second DIV will be moved to a separate row.
So, I'm wondering, how can I check if they are on the same line with JavaScript?
Thank you
"on the same line" would require inline elements or floating block elements of the exact same height. DIVs are block elements by default. So either use <span> tags instead of <div>, or add display: inline-block;to the CSS rule of those DIVs
ADDITION after EDIT OF QUESTION:
width: auto for a <div> means 100% of the parent element (in this case full width). As I wrote: If you have blocks, use display: inline-block; in their CSS. If you want them to have the same height, put them into a common container DIV (which you already have) and apply the following CSS:
#container {
display: table;
}
.first, .second {
display: table-cell;
width: 50%;
}
Aha (edited question), Javascript: Well, read out the DIV widths, add them and compare the result to the (read-out) container width.
You can use the element bounding boxes and check for overlap:
var rect1 = $('.first')[0].getBoundingClientRect();
var rect2 = $('.second')[0].getBoundingClientRect();
var overlaps = rect1.top <= rect2.bottom && rect2.top <= rect1.bottom;
This checks for any overlap which will probably be sufficient for your use. I used jQuery to get the elements but you can use pure js in the same way, it would just be a bit more verbose.
There is no concept of line on a page. You can check the x and y position of any element in the window and then decide if that meets whatever criteria you have for "on the same line".
By default, a div is the full width of a window so the two divs inside your container in this HTML:
<div id="container">
<div class="first"></div>
<div class="second"></div>
</div>
will be one above the other unless there is some other CSS you have not disclosed that controls the layout to allow them to be in the same row. If they are indeed width: auto and don't have any other layout rules affecting this, then they will each be full width and thus first will be above second in the layout stream. They would never be "on the same line" by any typical definition of that phrase.
Feel free to try it out here: https://jsfiddle.net/jfriend00/y0k7hLr8/ by resizing the right pane to any width you want. In all cases, the first will stay on top of the second.
If, on the other hand, you allow the div elements to have a different type of layout such as let them be display: inline-block and define a width for them, then the layout engine will fit as many on a given row as possible like here: https://jsfiddle.net/jfriend00/229rs97p/
Something tells me display: flex might help you in this. Read https://css-tricks.com/snippets/css/a-guide-to-flexbox/ for more info.