1

Is there a possible way to fix the boxes in below snippet at there initial state (present at bottom) whether scroll horizontally or vertically

#styleChangeOuterTag {
  /* display: none; */
  /* position: fixed; */
  position: relative;
  top: 0;
  left: 0;
  width: 300px;
  height: 100px;
  padding: 2vw 1.5vw;
  background-color: rgb(255, 245, 245);
  border: 2px solid rgb(255, 60, 255);
  border-radius: 3px;
  z-index: 5;
  overflow: auto;
  user-select: none;
}

#styleChangeOuterTag::after {
  content: '';
  background-color: #ccc;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 20px;
  height: 20px;
  cursor: nesw-resize;
}

#anotherBox {
  background-color: red;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 20px;
  height: 20px;
  cursor: nwse-resize;
}

#styleOptionDetails {
  border: 2px solid purple;
  border-radius: 3px;
  padding: 1vw;
  overflow: auto;
}
<div id="styleChangeOuterTag">
  ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent
  <hr>
  <div id="styleOptionDetails">
    t<br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> >
  </div>
  <div id="anotherBox">
  </div>
</div>

I tried to use sticky(possible on id #anotherBox not on ::after) but with that it comes to its original position when scroll completes.

Another option left is fixed with that have to reposition box with respect to document(screen). So don't change position when container is resized using them

The container is resizable with these boxes so wanted them to remain in position at bottom and move with the container when change in size of container.

So this is the reason I wanted them to remain in the initial state(fixed state when scroll) but move with the conatiner when resized

Resizable part is not important so not added here . If needed can provide

Thanks for help in advance

Rana
  • 2,500
  • 2
  • 7
  • 28
  • Are you trying to get `#anotherBox` to be at the bottom corner of the viewable space or at bottom corner of the parent div? – depperm Oct 06 '21 at 12:13
  • bottom corner of viewable space @depperm – Rana Oct 06 '21 at 12:14
  • Does this answer your question? [Fixed position but relative to container](https://stackoverflow.com/questions/6794000/fixed-position-but-relative-to-container) – depperm Oct 06 '21 at 12:18
  • Or [this one](https://stackoverflow.com/questions/11261270/css-position-element-fixed-inside-scrolling-container) – depperm Oct 06 '21 at 12:18
  • No it don't solve @depperm in `fixed` position the box is visible but have to reposition with respect to screen and also when the container resizes with `JS` it will remain intact in its position . And `sticky` is not applicable on `::after` – Rana Oct 06 '21 at 12:32
  • is it the red or gray box you're trying to afix? – depperm Oct 06 '21 at 12:35
  • Both of them so that it don't depend on one another @depperm – Rana Oct 06 '21 at 12:36

3 Answers3

2

This is not exactly what you wanted, but the answer you are looking for is position: sticky

remember that everything sticky or absolute follows its closest position: relative relative.

For horizontal sticky, there are still more work left to do in the snippet, but take a look at https://stackoverflow.com/a/57478547/3712531

#styleChangeOuterTag {
  /* display: none; */
  /* position: fixed; */
  top: 0;
  left: 0;
  width: 300px;
  height: 100px;
  padding: 2vw 1.5vw;
  background-color: rgb(255, 245, 245);
  border: 2px solid rgb(255, 60, 255);
  border-radius: 3px;
  z-index: 5;
  overflow: auto;
  user-select: none;
}

#styleChangeOuterTag::after {
  content: '';
  background-color: #ccc;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 20px;
  height: 20px;
  cursor: nesw-resize;
}

#anotherBox {
  background-color: red;
  position: sticky;
  bottom: 0;
  right: 0;
  width: 20px;
  height: 20px;
  cursor: nwse-resize;
}

#styleOptionDetails {
  border: 2px solid purple;
  border-radius: 3px;
  padding: 1vw;
  overflow: auto;
}
<div id="styleChangeOuterTag">
  ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent
  <hr>
  <div id="styleOptionDetails">
    t<br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> Content
    <br> >
  </div>
  <div id="anotherBox">
  </div>
</div>
Stanley
  • 2,434
  • 18
  • 28
  • does `fixed` position relative to container – Rana Oct 06 '21 at 13:42
  • An element with position: fixed; is positioned relative to the viewport, which means it always stays in the same place even if the page is scrolled. The top, right, bottom, and left properties are used to position the element. https://www.w3schools.com/css/css_positioning.asp – Stanley Oct 06 '21 at 13:43
  • Yes that's right thought I read something wrong , as the container is resizing so `fixed` position will let the `box` intact only to one position and don't let it change when container changes size . How to get the `red` box to the right edge in your snippet – Rana Oct 06 '21 at 13:51
  • @Rana Read the stack overflow link I posted and make sure the correct elements are positioned relative – Stanley Oct 06 '21 at 13:52
  • How position `::after` `relative` to container – Rana Oct 07 '21 at 10:56
  • `div::after { position: absolute; }` @Rana – Stanley Oct 07 '21 at 12:06
  • But as you can see in question snippet already used `{ position: absolute; }` but on scroll it don't remain in fixed state – Rana Oct 07 '21 at 12:46
  • because that is not what absolute positioning do. You need sticky if you want to follow scroll – Stanley Oct 07 '21 at 12:57
  • 1
    But sticky is not applied to `::after` – Rana Oct 09 '21 at 08:46
1

Try solution with a couple of lines of javascript.

  1. In #anotherBox set the position: fixed;, bottom and right compute a fixed position with variable which to get from js.
  2. With JS define height and width, then place with style to the element. Also set window event with resize to get the position when block will grow or shrink.
#anotherBox {
  background-color: red;
  position: fixed;
  bottom: calc(100vh - var(--y));
  right: calc(100vw - var(--x));
  width: 20px;
  height: 20px;
  cursor: nwse-resize;
}

const tag = document.getElementById('styleChangeOuterTag');

function callVarible() {
  tag.style = `--x: ${tag.clientWidth}px; --y: ${tag.clientHeight}px`;
}
callVarible();
window.addEventListener('resize', () => callVarible());
*,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#styleChangeOuterTag {
  /* display: none; */
  /* position: fixed; */
  position: relative;
  top: 0;
  left: 0;
  width: 30vw; /* changed */
  height: 40vh; /* changed */
  padding: 2vw 1.5vw;
  background-color: rgb(255, 245, 245);
  border: 2px solid rgb(255, 60, 255);
  border-radius: 3px;
  z-index: 5;
  overflow: auto;
  user-select: none;
}

#styleChangeOuterTag::after {
  content: '';
  background-color: #ccc;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 20px;
  height: 20px;
  cursor: nesw-resize;
}

#anotherBox {
  background-color: red;
  position: fixed; /* changed */
  bottom: calc(100vh - var(--y)); /* changed */
  right: calc(100vw - var(--x)); /* changed */
  width: 20px;
  height: 20px;
  cursor: nwse-resize;
}

#styleOptionDetails {
  border: 2px solid purple;
  border-radius: 3px;
  padding: 1vw;
  overflow: auto;
}
<div id="styleChangeOuterTag"> ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent
  <hr />
  <div id="styleOptionDetails">
    t<br /> Content <br /> Content <br /> Content <br /> Content <br /> Content <br /> Content <br /> Content <br /> Content <br /> Content <br /> Content <br /> Content <br /> >
  </div>
  <div id="anotherBox"></div>
</div>

updated with resize: both; codepen.io

Anton
  • 8,058
  • 1
  • 9
  • 27
  • Thanks a lot @brother , it really helped (+1) . Can this be applied to `::after` and what will be change in value of `left` . And one last thing `scroll` are automatic means not always present than how will the code change like `if(overflow){var=100vh-y+15px}` or somthing else – Rana Oct 10 '21 at 11:08
  • I have updated the snippet. Removed **+15px** from css calc() and changed in js `offsetWidth` to `clientWidth`. Now, box will have always the same position with scroll track or not. You can't get the position `::after` from javascript, because `pseudo-element` is not actually on the DOM. But you can create a second `
    ` and define it with javascript like **red box**.
    – Anton Oct 10 '21 at 11:53
  • Thanks a lot again . Can you tell which method is better `resize: both` or having own resizer function . – Rana Oct 10 '21 at 12:31
  • Better to create own function. Css `resize: both` create own width and height inline style on the DOM element. But you can get those width and height with javascript and set variables back to style, however because of this you will lost flexability when the scroll is visible or not. Added another snippet to see this. – Anton Oct 10 '21 at 13:19
  • Thanks a lot I will provide bounty(in 4hrs) to you and select other answer with 1 vote as accepted. Can you tell about variable in `CSS` using `JS` because it is the first time I confronted these – Rana Oct 10 '21 at 13:53
  • All what i know about css variable and how to use it with JS is [here](https://developer.mozilla.org/ru/docs/Web/API/CSSStyleDeclaration/getPropertyValue). But have one trick, you can get variable from inline style directly in css file. I created a sandobox where solved `resize: both;` the problem with the scroll track. – Anton Oct 10 '21 at 14:29
1

If it is acceptable for you to create one more container, the problem seems to be easy to solve. Set position: relative and size for container and remove position attribute in #styleChangeOuterTag. Then position: absolute will be connected to container and not affected by scrolling. Also this approach allows changing the size of the container.

.container {
  position: relative;
  width: 300px;
  height: 100px;
}

#styleChangeOuterTag {
  width: 100%;
  height: 100%;
  padding: 2vw 1.5vw;
  background-color: rgb(255, 245, 245);
  border: 2px solid rgb(255, 60, 255);
  border-radius: 3px;
  z-index: 5;
  overflow: auto;
  user-select: none;
}

#styleChangeOuterTag::after {
  content: '';
  background-color: #ccc;
  position: absolute;
  bottom: -2vw;
  left: 0;
  width: 20px;
  height: 20px;
  cursor: nesw-resize;
}

#anotherBox {
  background-color: red;
  position: absolute;
  bottom: -2vw;
  right: -1.5vw;
  width: 20px;
  height: 20px;
  cursor: nwse-resize;
}

#styleOptionDetails {
  border: 2px solid purple;
  border-radius: 3px;
  padding: 1vw;
  overflow: auto;
}
<div class="container">
  <div id="styleChangeOuterTag">
    ContentContentContentContentContentContentContentContentContentContentContentContentContentContentContentContent
    <hr>
    <div id="styleOptionDetails">
      t<br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> Content
      <br> >
    </div>
    <div id="anotherBox">
    </div>
  </div>
</div>
Ivan Beliakov
  • 529
  • 3
  • 14
  • Nice and simple solution , can't thought about it . Thanks a lot (+1) . But will the `scroll bars` presence changes the position or not as `scrolls` are automatic – Rana Oct 10 '21 at 11:11
  • Yes, scroll bar may be a problem here. I think javascript is a better option then – Ivan Beliakov Oct 10 '21 at 16:05